toolroll 0.9.61 → 0.9.63
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 +46 -0
- package/README.md +51 -3
- package/dist/agent-fence.d.ts +155 -10
- package/dist/agent-fence.js +473 -38
- package/dist/browser/workspace.css +1 -1
- package/dist/browser/workspace.js +21 -21
- package/dist/browser-workspace.d.ts +28 -0
- package/dist/chat-actions.js +2 -2
- package/dist/check-levels.js +3 -0
- package/dist/claim.js +1 -1
- package/dist/cli-help.d.ts +1 -1
- package/dist/cli-help.js +1 -0
- package/dist/cli.js +31 -11
- package/dist/contracts/cli.d.ts +8 -0
- package/dist/contracts/cli.js +3 -1
- package/dist/contracts/console-api.d.ts +19 -1
- package/dist/contracts/console-api.js +2 -1
- package/dist/contracts/integration-metadata.d.ts +2 -1
- package/dist/contracts/integration-metadata.js +2 -1
- package/dist/desktop-update.d.ts +1 -1
- package/dist/dispatch.js +7 -4
- package/dist/doctor.d.ts +53 -0
- package/dist/doctor.js +427 -0
- package/dist/evidence-pack.d.ts +1 -1
- package/dist/evidence-pack.js +2 -2
- package/dist/exec.d.ts +3 -0
- package/dist/exec.js +5 -4
- package/dist/flow-code.d.ts +2 -2
- package/dist/flow-code.js +4 -15
- package/dist/flow-engine.js +11 -6
- package/dist/flow-triggers.d.ts +8 -4
- package/dist/flow-triggers.js +45 -25
- package/dist/flow-unattended-words.d.ts +28 -0
- package/dist/flow-unattended-words.js +50 -0
- package/dist/flow-unattended.d.ts +227 -0
- package/dist/flow-unattended.js +776 -0
- package/dist/flows-cli.d.ts +28 -1
- package/dist/flows-cli.js +55 -10
- package/dist/flows-ui.d.ts +2 -1
- package/dist/flows-ui.js +4 -1
- package/dist/google-mail.d.ts +1 -0
- package/dist/google-mail.js +61 -18
- package/dist/integrations-ui.d.ts +2 -1
- package/dist/integrations-ui.js +6 -3
- package/dist/integrations.d.ts +17 -3
- package/dist/integrations.js +38 -18
- package/dist/invoke.js +300 -168
- package/dist/landed-cleanup.d.ts +26 -12
- package/dist/landed-cleanup.js +199 -85
- package/dist/lead-contract.d.ts +1 -1
- package/dist/lead-contract.js +3 -3
- package/dist/lead-tools.js +11 -3
- package/dist/mcp-connect.d.ts +8 -7
- package/dist/mcp-connect.js +49 -51
- package/dist/oauth-run-token.d.ts +51 -0
- package/dist/oauth-run-token.js +127 -0
- package/dist/operate.js +74 -17
- package/dist/plan-auto.d.ts +11 -0
- package/dist/plan-auto.js +62 -11
- package/dist/process-recovery-eligibility.d.ts +1 -1
- package/dist/project-access.d.ts +3 -0
- package/dist/project-access.js +3 -0
- package/dist/project-admission.d.ts +10 -6
- package/dist/project-admission.js +33 -11
- package/dist/project-delete-ui.d.ts +1 -0
- package/dist/project-delete-ui.js +4 -1
- package/dist/project-delete.d.ts +3 -1
- package/dist/project-delete.js +10 -4
- package/dist/project-file.d.ts +3 -0
- package/dist/project-file.js +16 -0
- package/dist/project-tools.d.ts +99 -25
- package/dist/project-tools.js +394 -98
- package/dist/provider-home.d.ts +22 -0
- package/dist/provider-home.js +99 -0
- package/dist/provider.d.ts +17 -3
- package/dist/provider.js +34 -10
- package/dist/remote-main.d.ts +61 -0
- package/dist/remote-main.js +179 -0
- package/dist/scope.d.ts +1 -1
- package/dist/serve.js +11 -3
- package/dist/server/flows.js +27 -5
- package/dist/server/render-tasks.d.ts +3 -0
- package/dist/server/render-tasks.js +3 -0
- package/dist/server/route-table.js +3 -0
- package/dist/server/runtime.d.ts +1 -1
- package/dist/server/settings.js +14 -5
- package/dist/server/task-views.js +2 -0
- package/dist/storage-sweep-child.js +3 -1
- package/dist/storage-sweep-process.d.ts +14 -0
- package/dist/storage-sweep-process.js +37 -3
- package/dist/storage-sweep-schedule.d.ts +30 -0
- package/dist/storage-sweep-schedule.js +164 -0
- package/dist/storage-sweep.d.ts +6 -5
- package/dist/storage-sweep.js +10 -70
- package/dist/storage-ui.d.ts +2 -0
- package/dist/storage-ui.js +7 -4
- package/dist/store.d.ts +75 -7
- package/dist/store.js +241 -17
- package/dist/subagent-tools.d.ts +1 -1
- package/dist/surface.js +10 -6
- package/dist/task-base.d.ts +35 -0
- package/dist/task-base.js +51 -0
- package/dist/teardown-git.d.ts +14 -0
- package/dist/teardown-git.js +119 -0
- package/dist/tool-broker.d.ts +37 -0
- package/dist/tool-broker.js +369 -0
- package/dist/tool-launcher.js +5 -4
- package/dist/tool-secret-store.d.ts +170 -0
- package/dist/tool-secret-store.js +834 -0
- package/dist/toolroll-update.js +4 -2
- package/dist/tools-ui.d.ts +7 -1
- package/dist/tools-ui.js +17 -8
- package/dist/work-index.js +5 -3
- package/dist/worktree.d.ts +64 -6
- package/dist/worktree.js +171 -35
- package/package.json +3 -1
- package/scripts/provider-canary.mjs +210 -31
package/dist/storage-sweep.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The
|
|
3
|
-
*
|
|
4
|
-
* (test-temp.ts), stops orphans Toolroll left running (orphan-sweep.ts), removes finished checkouts the cleanup
|
|
2
|
+
* The storage sweep: the plane cleans up after itself without anyone running a command. About once a day, when nothing
|
|
3
|
+
* is running or waiting (storage-sweep-schedule.ts: one service takes it, the cursor moves in the same transaction),
|
|
4
|
+
* it removes test temp folders nothing touched for a day (test-temp.ts), stops orphans Toolroll left running (orphan-sweep.ts), removes finished checkouts the cleanup
|
|
5
5
|
* setting lets go (checkout-cleanup.ts), keeps the current, previous and newest staged runtimes (staged-runtimes.ts)
|
|
6
6
|
* and removes shared dependency installs no checkout has used for a week (shared-deps.ts).
|
|
7
7
|
*
|
|
@@ -17,8 +17,9 @@
|
|
|
17
17
|
*
|
|
18
18
|
* What each sweep did is saved (the latest few) and in the ledger: `toolroll storage` and Settings → Storage show it.
|
|
19
19
|
* A clean-up by hand (`storage clean --yes`) is saved the same way. A part that failed, or had more than one pass
|
|
20
|
-
* takes, brings the next sweep forward to an hour later
|
|
21
|
-
* (the unit tests do, so a test never sweeps the machine
|
|
20
|
+
* takes, brings the next sweep forward to an hour later; it still waits for nothing to be running.
|
|
21
|
+
* `TOOLROLL_STORAGE_SWEEP=off` turns the automatic sweep off (the unit tests do, so a test never sweeps the machine
|
|
22
|
+
* it runs on).
|
|
22
23
|
*/
|
|
23
24
|
import { realpathSync } from "node:fs";
|
|
24
25
|
import { hostname } from "node:os";
|
|
@@ -29,11 +30,10 @@ import { processCensus } from "./run-closeout.js";
|
|
|
29
30
|
import { linkedKey, pruneUnusedShared, sharedDepsRoot, sharedUse, SHARED_UNUSED_MS } from "./shared-deps.js";
|
|
30
31
|
import { pruneStagedRuntimes, runtimesInUse, runtimeScriptPaths, stagePlan } from "./staged-runtimes.js";
|
|
31
32
|
import { bytesWords, diskBytes } from "./storage.js";
|
|
32
|
-
import { openStoreNoMigrate } from "./store.js";
|
|
33
33
|
import { removeStaleTestTemp } from "./test-temp.js";
|
|
34
34
|
import { worktreeProcessOccupancy } from "./worktree.js";
|
|
35
|
-
import { runSweepChild
|
|
36
|
-
const
|
|
35
|
+
import { runSweepChild } from "./storage-sweep-process.js";
|
|
36
|
+
export const SWEEP_CURSOR = "storage-sweep";
|
|
37
37
|
export const SWEEP_EVERY_MS = 86_400_000;
|
|
38
38
|
/** A sweep that failed somewhere, or left work for later, runs again this soon. */
|
|
39
39
|
export const RETRY_MS = 60 * 60_000;
|
|
@@ -46,67 +46,7 @@ const ITEMS_MAX = 20;
|
|
|
46
46
|
export function storageSweepOff(env = process.env) {
|
|
47
47
|
return (env["TOOLROLL_STORAGE_SWEEP"] ?? "").trim().toLowerCase() === "off";
|
|
48
48
|
}
|
|
49
|
-
export function
|
|
50
|
-
return now.getTime() - store.serviceCursor(CURSOR) >= SWEEP_EVERY_MS;
|
|
51
|
-
}
|
|
52
|
-
/** Claim and launch only. A hung child never holds reconciliation or the caller's store open. */
|
|
53
|
-
export function dailyStorageSweep(store, deps, now, supervisor = storageSweepSupervisor(deps.databaseFile)) {
|
|
54
|
-
if (storageSweepOff() || supervisor.running || !storageSweepDue(store, now()))
|
|
55
|
-
return null;
|
|
56
|
-
// This handle belongs to the flight, not to the command that has already returned by the time it finishes.
|
|
57
|
-
const connection = openStoreNoMigrate(deps.databaseFile);
|
|
58
|
-
if (!connection.ok)
|
|
59
|
-
throw new Error("Sweep result store unavailable");
|
|
60
|
-
const results = connection.store;
|
|
61
|
-
const at = now();
|
|
62
|
-
let completed = null;
|
|
63
|
-
let owned = false;
|
|
64
|
-
try {
|
|
65
|
-
const mine = store.transact(() => {
|
|
66
|
-
if (!storageSweepDue(store, at))
|
|
67
|
-
return false;
|
|
68
|
-
store.setServiceCursor(CURSOR, at.getTime(), at);
|
|
69
|
-
return true;
|
|
70
|
-
});
|
|
71
|
-
if (!mine)
|
|
72
|
-
return null;
|
|
73
|
-
const request = { version: 1, databaseFile: deps.databaseFile, poolRoot: deps.pool?.root ?? null, tempRoots: [...deps.tempRoots], actor: deps.actor ?? "worker", at: at.toISOString() };
|
|
74
|
-
owned = supervisor.start(request, result => {
|
|
75
|
-
const record = result.ok ? result.record : sweepFailure(request.at, request.actor, deps.pool !== null, result.reason);
|
|
76
|
-
try {
|
|
77
|
-
results.transact(() => {
|
|
78
|
-
if (!results.schemaCurrent())
|
|
79
|
-
throw new Error("Sweep result store changed");
|
|
80
|
-
saveSweep(results, record);
|
|
81
|
-
// Only this claim can reschedule itself. A later claim must never be overwritten by a late callback.
|
|
82
|
-
if (record.parts.some(one => one.failed > 0 || one.more === true || one.problem !== undefined) && results.serviceCursor(CURSOR) === at.getTime()) {
|
|
83
|
-
results.setServiceCursor(CURSOR, Math.max(0, now().getTime() - SWEEP_EVERY_MS + RETRY_MS), now());
|
|
84
|
-
}
|
|
85
|
-
});
|
|
86
|
-
completed = record;
|
|
87
|
-
}
|
|
88
|
-
catch {
|
|
89
|
-
// No exception/path from a process or database is safe to copy into a log.
|
|
90
|
-
console.error("Could not save the storage sweep result.");
|
|
91
|
-
}
|
|
92
|
-
finally {
|
|
93
|
-
results.close();
|
|
94
|
-
}
|
|
95
|
-
}, deps.owner);
|
|
96
|
-
if (!owned) {
|
|
97
|
-
store.transact(() => {
|
|
98
|
-
if (store.serviceCursor(CURSOR) === at.getTime())
|
|
99
|
-
store.setServiceCursor(CURSOR, Math.max(0, at.getTime() - SWEEP_EVERY_MS + RETRY_MS), now());
|
|
100
|
-
});
|
|
101
|
-
}
|
|
102
|
-
return completed;
|
|
103
|
-
}
|
|
104
|
-
finally {
|
|
105
|
-
if (!owned)
|
|
106
|
-
results.close();
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
function sweepFailure(at, actor, withPool, reason) {
|
|
49
|
+
export function sweepFailure(at, actor, withPool, reason) {
|
|
110
50
|
const problem = reason === "timeout" ? "The sweep process exceeded its time limit; some cleanup may have completed. Cleanup will retry later."
|
|
111
51
|
: reason === "stopped" ? "The sweep process was stopped; some cleanup may have completed. Cleanup will retry later."
|
|
112
52
|
: "The sweep process did not return a valid result; some cleanup may have completed.";
|
|
@@ -339,7 +279,7 @@ export function lastSweep(store, source) {
|
|
|
339
279
|
export function nextSweepAt(store) {
|
|
340
280
|
if (storageSweepOff())
|
|
341
281
|
return null;
|
|
342
|
-
const last = store.serviceCursor(
|
|
282
|
+
const last = store.serviceCursor(SWEEP_CURSOR);
|
|
343
283
|
return last === 0 ? null : new Date(last + SWEEP_EVERY_MS).toISOString();
|
|
344
284
|
}
|
|
345
285
|
const NOUNS = {
|
package/dist/storage-ui.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { type Html } from "./html.js";
|
|
2
2
|
import { type CheckoutPlan } from "./checkout-cleanup.js";
|
|
3
3
|
import { type SweepRecord } from "./storage-sweep.js";
|
|
4
|
+
import { type SweepSchedule } from "./storage-sweep-schedule.js";
|
|
4
5
|
import type { LandedSummary } from "./landed-cleanup.js";
|
|
5
6
|
export declare const STORAGE_CSS: string;
|
|
6
7
|
export type StorageView = {
|
|
@@ -9,6 +10,7 @@ export type StorageView = {
|
|
|
9
10
|
sweep?: {
|
|
10
11
|
last: SweepRecord | null;
|
|
11
12
|
off: boolean;
|
|
13
|
+
schedule?: SweepSchedule;
|
|
12
14
|
};
|
|
13
15
|
landed?: LandedSummary;
|
|
14
16
|
};
|
package/dist/storage-ui.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Settings → Storage: how much space task checkouts use, what a clean-up would free now, a Clean up button whose
|
|
3
3
|
* preview (what goes, what stays and why, with paths) sits behind the password, what the last storage sweep removed
|
|
4
|
-
* and when (its paths in a disclosure), what landed work's teardown did and still waits on (in a disclosure, with the
|
|
4
|
+
* and when (its paths in a disclosure) and why the next one waits, what landed work's teardown did and still waits on (in a disclosure, with the
|
|
5
5
|
* one-time command for older work), and when a finished task's clean checkout goes by itself. An instance operator's page.
|
|
6
6
|
*/
|
|
7
7
|
import { homedir } from "node:os";
|
|
@@ -10,6 +10,7 @@ import { html, postForm } from "./html.js";
|
|
|
10
10
|
import { previewDigest, whyWords } from "./checkout-cleanup.js";
|
|
11
11
|
import { CLEANUP_CHOICES, bytesWords } from "./storage.js";
|
|
12
12
|
import { sweepDetails, sweepWords } from "./storage-sweep.js";
|
|
13
|
+
import { sweepScheduleWords } from "./storage-sweep-schedule.js";
|
|
13
14
|
const plural = (count, one, many = `${one}s`) => `${count} ${count === 1 ? one : many}`;
|
|
14
15
|
export const STORAGE_CSS = `.storage{max-width:720px;min-width:0;overflow-wrap:anywhere}.storage h2{font-size:1.0625rem;margin:24px 0 4px}` +
|
|
15
16
|
`.storage .storage-state{display:grid;gap:12px}.storage .storage-state h2{margin:0}.storage .storage-state p{margin:0}` +
|
|
@@ -45,15 +46,17 @@ function whenWords(at) {
|
|
|
45
46
|
const date = new Date(at);
|
|
46
47
|
return Number.isNaN(date.getTime()) ? at : date.toLocaleString("en-US", { month: "short", day: "numeric", hour: "numeric", minute: "2-digit" });
|
|
47
48
|
}
|
|
48
|
-
/**
|
|
49
|
+
/** When the last sweep ran and what it did, then why the next one waits or when it is due; paths and problems behind Details. */
|
|
49
50
|
function sweepHtml(sweep) {
|
|
50
51
|
const last = sweep.last;
|
|
52
|
+
const schedule = sweep.schedule === undefined ? (sweep.off ? html `<p class="meta" data-sweep-state="off">Automatic sweep: off.</p>` : "")
|
|
53
|
+
: html `<p class="meta" data-sweep-state="${sweep.schedule.state}">Automatic sweep: ${sweepScheduleWords(sweep.schedule, whenWords)}</p>`;
|
|
51
54
|
if (last === null)
|
|
52
|
-
return html `<
|
|
55
|
+
return html `<div class="sweep" data-last-sweep=""><p>Not swept yet.</p>${schedule}</div>`;
|
|
53
56
|
const who = last.source === "manual" ? `Cleaned up by ${last.actor}` : "Swept";
|
|
54
57
|
const details = sweepDetails(last.parts);
|
|
55
58
|
const problem = last.parts.some(one => one.failed > 0 || one.problem !== undefined);
|
|
56
|
-
return html `<div class="sweep" data-last-sweep="${last.at}"><p${problem ? html ` class="problem"` : ""}>${who} <time datetime="${last.at}">${whenWords(last.at)}</time>. ${sweepWords(last.parts)}</p>${details.length === 0 ? "" : html `<details class="sweep-details"><summary>Details</summary><ul>${details.map(line => html `<li>${homeAsTilde(line)}</li>`)}</ul></details>`}</div>`;
|
|
59
|
+
return html `<div class="sweep" data-last-sweep="${last.at}"><p${problem ? html ` class="problem"` : ""}>${who} <time datetime="${last.at}">${whenWords(last.at)}</time>. ${sweepWords(last.parts)}</p>${schedule}${details.length === 0 ? "" : html `<details class="sweep-details"><summary>Details</summary><ul>${details.map(line => html `<li>${homeAsTilde(line)}</li>`)}</ul></details>`}</div>`;
|
|
57
60
|
}
|
|
58
61
|
/** Landed work, on demand: what its teardown did, what it waits on and why, and the one-time command for older work. */
|
|
59
62
|
function landedHtml(landed) {
|
package/dist/store.d.ts
CHANGED
|
@@ -78,6 +78,11 @@ export declare const FLOW_SEND_SCHEMA = "\nCREATE TABLE IF NOT EXISTS flow_send
|
|
|
78
78
|
* vocabulary and when — never text, tool names or arguments. Display state, not evidence;
|
|
79
79
|
* a finished run's row goes with the live log's own retention (sweepRunActivity). */
|
|
80
80
|
export declare const RUN_ACTIVITY_SCHEMA = "\nCREATE TABLE IF NOT EXISTS run_activity (\n run INTEGER PRIMARY KEY REFERENCES run(id) ON DELETE CASCADE,\n kind TEXT NOT NULL CHECK (kind IN ('session','message','edit','command','read','search','lookup','plan','delegate','tool')),\n at TEXT NOT NULL\n);\n";
|
|
81
|
+
/** A task branch moved to current main before an attempt (fresh base; v122, a new table: additive only): the branch
|
|
82
|
+
* had no commits of its own and no changes, so it started over from `to_rev`. `after_run` is the newest run id when it
|
|
83
|
+
* moved: the branch's whole-task diff runs from the first builder base recorded after it (firstBuilderBase), never from
|
|
84
|
+
* the older main it left. */
|
|
85
|
+
export declare const BRANCH_BASE_MOVE_SCHEMA = "\nCREATE TABLE IF NOT EXISTS branch_base_move (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n task_ref INTEGER NOT NULL REFERENCES task_ref(id) ON DELETE CASCADE,\n branch TEXT NOT NULL,\n from_rev TEXT NOT NULL,\n to_rev TEXT NOT NULL,\n after_run INTEGER NOT NULL,\n moved_at TEXT NOT NULL\n);\nCREATE INDEX IF NOT EXISTS branch_base_move_branch ON branch_base_move (task_ref, branch, id);\n";
|
|
81
86
|
/** Pausing a running Claude build (live steering, v121: additive only). A person's Pause asks the build to
|
|
82
87
|
* stop its current turn and keep its session: one row per request, bound to the exact run it was asked of, under the
|
|
83
88
|
* request id the asker chose (a repeated request is the same request). `note` is the steering note a Pause and steer
|
|
@@ -105,6 +110,10 @@ export declare const LEAD_FOLLOW_MESSAGE = "Automatic crew update: inspect the s
|
|
|
105
110
|
* nothing set up, such as no `gh` sign-in). `ok_at` and `error`/`error_at` keep the last success and the last
|
|
106
111
|
* failure across checks, so a row can say both. `account` is a display name only, never a credential. */
|
|
107
112
|
export declare const INTEGRATIONS_SCHEMA = "\nCREATE TABLE IF NOT EXISTS integration_check (\n key TEXT PRIMARY KEY,\n outcome TEXT NOT NULL CHECK (outcome IN ('ok', 'failed', 'absent')),\n account TEXT,\n detail TEXT,\n problem TEXT,\n checked_at TEXT NOT NULL,\n ok_at TEXT,\n error TEXT,\n error_at TEXT\n);\n";
|
|
113
|
+
/** Tool secrets (no version bump): which sealing key Toolroll made for the secrets it keeps in the keychain, as a
|
|
114
|
+
* digest of the key, never the key. A key found beside them that isn't this one was put there by something else and is
|
|
115
|
+
* refused (tool-secret-store.ts). */
|
|
116
|
+
export declare const TOOL_SECRET_KEY_SCHEMA = "\nCREATE TABLE IF NOT EXISTS tool_secret_key (\n id INTEGER PRIMARY KEY CHECK (id = 1),\n digest TEXT NOT NULL CHECK (length(digest) = 64),\n made_at TEXT NOT NULL\n);\n-- Where secrets were kept before Toolroll's folder, decided once at this database's first start (null: none) and never\n-- probed again, so a folder a build makes later under an old name is never migrated in.\nCREATE TABLE IF NOT EXISTS tool_secret_legacy (\n id INTEGER PRIMARY KEY CHECK (id = 1),\n dir TEXT,\n decided_at TEXT NOT NULL\n);\n";
|
|
108
117
|
export type BackupSettings = {
|
|
109
118
|
enabled: boolean;
|
|
110
119
|
everyHours: number;
|
|
@@ -161,7 +170,7 @@ export type SealedLedgerEntry = LedgerEntry & {
|
|
|
161
170
|
hash: string;
|
|
162
171
|
} | null;
|
|
163
172
|
};
|
|
164
|
-
export declare const SCHEMA_VERSION =
|
|
173
|
+
export declare const SCHEMA_VERSION = 123;
|
|
165
174
|
/** v118: the tables merged into `credential`, in the order they move (a person's API tokens keep their ids first). */
|
|
166
175
|
export declare const V118_MERGED_TABLES: Readonly<Record<string, CredentialKind>>;
|
|
167
176
|
/**
|
|
@@ -220,7 +229,10 @@ export declare const V115_DROPPED_TABLES: readonly string[];
|
|
|
220
229
|
* (planning_generation on task_ref, run and plan_revision, defaulting to 0, and decision.superseded_reason, null);
|
|
221
230
|
* the rehearsal checks every saved row reads the declared default (HISTORY_RULES' added columns). v120 only adds
|
|
222
231
|
* three nullable task_steer columns (the running build's steering folder), checked the same way. v121 only adds
|
|
223
|
-
* new tables and the columns in V121_ADDED_COLUMNS (null, or no sends), checked the same way.
|
|
232
|
+
* new tables and the columns in V121_ADDED_COLUMNS (null, or no sends), checked the same way. v122 only adds a new
|
|
233
|
+
* table (branch_base_move) and the nullable column in V122_ADDED_COLUMNS (a project's recorded remote), checked the
|
|
234
|
+
* same way. v123 only adds new tables (unattended flows, tool secrets) and the columns in V123_ADDED_COLUMNS ('mode',
|
|
235
|
+
* 0 or null), checked the same way.
|
|
224
236
|
*/
|
|
225
237
|
export declare const UPDATE_SAFE_MIGRATIONS: readonly number[];
|
|
226
238
|
/** v119: the columns it adds, by table, with the value every row saved before it reads (toolroll-update's HISTORY_RULES). */
|
|
@@ -250,6 +262,19 @@ export declare const V121_ADDED_COLUMNS: Readonly<Record<string, Readonly<Record
|
|
|
250
262
|
definition: string;
|
|
251
263
|
saved: string;
|
|
252
264
|
}>>>>;
|
|
265
|
+
/** v122: the column it adds, with the value every row saved before it reads: the remote URL an owner's project add
|
|
266
|
+
* recorded (projects added before it read none, until `repos add <project> --remote <url>` records one). */
|
|
267
|
+
export declare const V122_ADDED_COLUMNS: Readonly<Record<string, Readonly<Record<string, {
|
|
268
|
+
definition: string;
|
|
269
|
+
saved: string;
|
|
270
|
+
}>>>>;
|
|
271
|
+
/** v123: the columns it adds, with the value every row saved before it reads: which authority armed a plan's
|
|
272
|
+
* unchanged-plan approval (saved rows read the operating mode), whether a trigger's firing was the clock's own (saved
|
|
273
|
+
* firings read not), and what code an on-time script firing a grant signed for ran (saved firings read none). */
|
|
274
|
+
export declare const V123_ADDED_COLUMNS: Readonly<Record<string, Readonly<Record<string, {
|
|
275
|
+
definition: string;
|
|
276
|
+
saved: string;
|
|
277
|
+
}>>>>;
|
|
253
278
|
/** Whether a database settled at `version` reaches this build's schema through update-safe migrations alone. */
|
|
254
279
|
export declare function updateSafeSchema(version: number | null): boolean;
|
|
255
280
|
export type OAuthClientRow = {
|
|
@@ -1757,6 +1782,18 @@ export declare class Store {
|
|
|
1757
1782
|
/** The database's own file (null in memory): where the agent fence begins. */
|
|
1758
1783
|
databaseFile(): string | null;
|
|
1759
1784
|
close(): void;
|
|
1785
|
+
/** The digest of the sealing key Toolroll made for its tool secrets; null before it made one (or in an older database). */
|
|
1786
|
+
toolSecretKeyDigest(): string | null;
|
|
1787
|
+
/**
|
|
1788
|
+
* The folder secrets were kept in before Toolroll's own, as decided at this database's first start of a command that
|
|
1789
|
+
* can start builds (`record`): `probe` runs until then, and its answer (null: none) is kept for every later start.
|
|
1790
|
+
* Other commands never write, so a preview stays read-only and a busy database doesn't stop them.
|
|
1791
|
+
*/
|
|
1792
|
+
toolSecretLegacyDir(probe: () => string | null, now: Date, options: {
|
|
1793
|
+
record: boolean;
|
|
1794
|
+
}): string | null;
|
|
1795
|
+
/** Record a new sealing key's digest only if the one recorded is still `expected` (null: none yet). */
|
|
1796
|
+
swapToolSecretKeyDigest(expected: string | null, next: string, now: Date): boolean;
|
|
1760
1797
|
/**
|
|
1761
1798
|
* Creating a task also creates its overlay reference, because a task with no
|
|
1762
1799
|
* `TaskRef` cannot be claimed, held, or scheduled — it would be work the
|
|
@@ -2151,7 +2188,7 @@ export declare class Store {
|
|
|
2151
2188
|
* exactly what the signed digest was bound to. Returns false when the
|
|
2152
2189
|
* scope vanished mid-ceremony. */
|
|
2153
2190
|
sealScopeApproval(taskId: string, by: string, now: Date, mutation?: Mutation, basis?: {
|
|
2154
|
-
kind: "mode" | "chat";
|
|
2191
|
+
kind: "mode" | "chat" | "grant";
|
|
2155
2192
|
modeDigest: string;
|
|
2156
2193
|
}, approverKind?: ApproverKind): boolean;
|
|
2157
2194
|
/** Whether this task's scope carries a LIVE seal: approved, and the
|
|
@@ -2206,6 +2243,10 @@ export declare class Store {
|
|
|
2206
2243
|
* ceremony. Reconciliation drops mode-basis intents to waiting-human;
|
|
2207
2244
|
* `firing` rows are untouched — an issued call is one-shot (E1). */
|
|
2208
2245
|
revokeMode(repo: string, by: string, reason: string, now: Date): boolean;
|
|
2246
|
+
/** A flow's "runs on its own" grant ended (revoked, expired, renewed): the undispatched work it sealed falls back
|
|
2247
|
+
* to a person, as a mode's does, and plans it armed lose their pre-authorization. Running and finished work keeps
|
|
2248
|
+
* its history. */
|
|
2249
|
+
withdrawGrantApprovals(digest: string, now: Date): void;
|
|
2209
2250
|
/** F2/R-REVOKE: the ONE reconciliation road. newMode null = no live
|
|
2210
2251
|
* automerge authority (revocation, expiry, or a notify posture):
|
|
2211
2252
|
* mode-basis pending/claimed intents drop to waiting-human, leases
|
|
@@ -4350,6 +4391,20 @@ export declare class Store {
|
|
|
4350
4391
|
* legacy first-attempt behavior, unchanged byte-for-byte.
|
|
4351
4392
|
*/
|
|
4352
4393
|
firstBuilderBase(taskRef: number, branch: string): string | null;
|
|
4394
|
+
/** Where a task branch's attempts start now: a builder branch's pinned base, or the newest base any other attempt on
|
|
4395
|
+
* it recorded (a planner never commits). Null before any attempt on the branch recorded one, or after a move to
|
|
4396
|
+
* current main until the next attempt records its base. */
|
|
4397
|
+
recordedBranchBase(taskRef: number, branch: string): string | null;
|
|
4398
|
+
/** Record a task branch's move to current main, before git moves it: a move that then fails leaves the next
|
|
4399
|
+
* attempt's own base (still the old one) as the branch's origin, which is exactly right. */
|
|
4400
|
+
recordBranchBaseMove(taskRef: number, branch: string, from: string, to: string, now: Date): void;
|
|
4401
|
+
/** The newest move of a task branch to current main, or null. */
|
|
4402
|
+
latestBranchBaseMove(taskRef: number, branch: string): {
|
|
4403
|
+
from: string;
|
|
4404
|
+
to: string;
|
|
4405
|
+
afterRun: number;
|
|
4406
|
+
movedAt: string;
|
|
4407
|
+
} | null;
|
|
4353
4408
|
finishRun(id: number, result: {
|
|
4354
4409
|
outcome: "built" | "failed" | "refused" | "parked" | "no-change" | "interrupted";
|
|
4355
4410
|
reason?: string;
|
|
@@ -4385,6 +4440,10 @@ export declare class Store {
|
|
|
4385
4440
|
* other class is observational.
|
|
4386
4441
|
*/
|
|
4387
4442
|
stampTerminalClass(id: number, authMode: "subscription" | "api-key", terminalClass: TerminalClass): void;
|
|
4443
|
+
/** A launch refused before any model turn (an installed CLI too old for a
|
|
4444
|
+
* build's flags): the start stamp goes, its version and evidence stay. Only
|
|
4445
|
+
* while the run is open, so a settled run's account never changes. */
|
|
4446
|
+
withdrawProviderStart(id: number): void;
|
|
4388
4447
|
/** The race-refusal stamp (Phase 3 C5): the version that was REFUSED,
|
|
4389
4448
|
* recorded without provider_started_at — no provider process started. */
|
|
4390
4449
|
stampProviderVersion(id: number, providerVersion: string): void;
|
|
@@ -5657,7 +5716,7 @@ export declare class Store {
|
|
|
5657
5716
|
}, now: Date): number;
|
|
5658
5717
|
/** A person approves a held script (one an imported flow brought): from now on it runs. False when it wasn't held. */
|
|
5659
5718
|
approveFlowScript(repo: string, name: string): boolean;
|
|
5660
|
-
removeFlowScript(repo: string, name: string): boolean;
|
|
5719
|
+
removeFlowScript(repo: string, name: string, by?: string, now?: Date): boolean;
|
|
5661
5720
|
/** Claim a card's visit to a step zone. False when another pass holds it or it already finished. */
|
|
5662
5721
|
claimFlowStep(step: {
|
|
5663
5722
|
card: number;
|
|
@@ -5737,7 +5796,7 @@ export declare class Store {
|
|
|
5737
5796
|
lastOutcome?: string;
|
|
5738
5797
|
failures?: number;
|
|
5739
5798
|
hookHash?: string | null;
|
|
5740
|
-
}, now: Date): void;
|
|
5799
|
+
}, now: Date, by?: string): void;
|
|
5741
5800
|
/** Whether a trigger already handled this outside thing (an issue, a run, a schedule slot). */
|
|
5742
5801
|
flowTriggerSaw(trigger: number, key: string): boolean;
|
|
5743
5802
|
/** The card one outside thing made (v89: a chat message, so replies in its thread find it). */
|
|
@@ -5748,7 +5807,7 @@ export declare class Store {
|
|
|
5748
5807
|
* Record what a trigger did with one outside thing: the card it made, or why it made none, and (a standing order's
|
|
5749
5808
|
* firing) the task it filed. False when it was already recorded.
|
|
5750
5809
|
*/
|
|
5751
|
-
recordFlowTriggerEvent(trigger: number, key: string, card: number | null, note: string | null, now: Date, task?: string | null): boolean;
|
|
5810
|
+
recordFlowTriggerEvent(trigger: number, key: string, card: number | null, note: string | null, now: Date, task?: string | null, onTime?: boolean, ranScript?: string | null): boolean;
|
|
5752
5811
|
/** The last card a trigger made, if any. */
|
|
5753
5812
|
lastFlowTriggerCard(trigger: number): number | null;
|
|
5754
5813
|
/**
|
|
@@ -6004,7 +6063,15 @@ export declare class Store {
|
|
|
6004
6063
|
leadStepsOf(leadTurn: number): ChatTurn[];
|
|
6005
6064
|
/** Remember a project was opened. Upsert keeps added_at; recency always moves.
|
|
6006
6065
|
* A project added for the first time starts on Quick checks. */
|
|
6007
|
-
upsertProject(path: string, name: string, now: Date
|
|
6066
|
+
upsertProject(path: string, name: string, now: Date, admission?: {
|
|
6067
|
+
remoteUrl: string | null;
|
|
6068
|
+
}): void;
|
|
6069
|
+
/** Includes removed/legacy projects, so deleting a row never makes build-writable config authoritative again. */
|
|
6070
|
+
projectAdmissionKnown(path: string): boolean;
|
|
6071
|
+
/** Full structured URL audit, without the generic ledger's display-text truncation. */
|
|
6072
|
+
recordProjectRemote(actor: string, repo: string, previous: string | null, remoteUrl: string, now: Date): void;
|
|
6073
|
+
/** The remote URL captured on admission or explicitly supplied by the owner; null when none was (or the project was removed). */
|
|
6074
|
+
projectRemote(path: string): string | null;
|
|
6008
6075
|
/** A project removed from the lists (project-admission.ts): only its row goes; its tasks, results and settings stay. */
|
|
6009
6076
|
forgetProject(path: string): void;
|
|
6010
6077
|
/** Most recently opened first — the opener page's order. */
|
|
@@ -6013,6 +6080,7 @@ export declare class Store {
|
|
|
6013
6080
|
name: string;
|
|
6014
6081
|
addedAt: string;
|
|
6015
6082
|
lastOpenedAt: string;
|
|
6083
|
+
remoteUrl: string | null;
|
|
6016
6084
|
}[];
|
|
6017
6085
|
/**
|
|
6018
6086
|
* Tasks whose scope waits on a person's yes: proposed, not approved (or
|