toolroll 0.9.59 → 0.9.61
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 +26 -0
- package/README.md +8 -6
- package/dist/agent-board.d.ts +208 -0
- package/dist/agent-board.js +454 -0
- package/dist/agent-fence.d.ts +19 -0
- package/dist/agent-fence.js +100 -8
- package/dist/agent-pulse.d.ts +43 -0
- package/dist/agent-pulse.js +214 -0
- package/dist/agent-turns.d.ts +52 -0
- package/dist/agent-turns.js +137 -0
- package/dist/agents-board.d.ts +101 -0
- package/dist/agents-board.js +225 -0
- package/dist/assignment-adapters.d.ts +2 -1
- package/dist/assignment-adapters.js +1 -1
- package/dist/assignment-delivery.d.ts +16 -0
- package/dist/assignment-delivery.js +54 -28
- package/dist/assignment-status.d.ts +14 -5
- package/dist/assignment-status.js +70 -39
- package/dist/assignment.d.ts +10 -2
- package/dist/assignment.js +21 -14
- package/dist/bin.js +11 -2
- package/dist/brief-fence.d.ts +9 -0
- package/dist/brief-fence.js +22 -0
- package/dist/browser/workspace.css +2 -2
- package/dist/browser/workspace.js +29 -25
- package/dist/browser-crew.js +2 -0
- package/dist/browser-workspace.d.ts +79 -1
- package/dist/browser-workspace.js +1 -0
- package/dist/builder.d.ts +8 -0
- package/dist/builder.js +178 -29
- package/dist/chat-channel.js +10 -1
- package/dist/chat-core.d.ts +6 -0
- package/dist/chat-core.js +8 -0
- package/dist/chat-delivery.js +22 -0
- package/dist/chat-messages.js +8 -1
- package/dist/chat-quiet.js +1 -0
- package/dist/chat-voice.d.ts +2 -0
- package/dist/chat-voice.js +2 -0
- package/dist/checkout-cleanup.d.ts +3 -0
- package/dist/checkout-cleanup.js +11 -2
- package/dist/cli-fast.d.ts +8 -0
- package/dist/cli-fast.js +18 -0
- package/dist/cli-help.d.ts +5 -0
- package/dist/cli-help.js +91 -0
- package/dist/cli.d.ts +6 -5
- package/dist/cli.js +17 -96
- package/dist/contracts/console-api.d.ts +3 -1
- package/dist/contracts/console-api.js +5 -1
- package/dist/contracts/lead-tools.d.ts +16 -2
- package/dist/contracts/lead-tools.js +5 -1
- package/dist/design/tokens.css +234 -0
- package/dist/desktop-update.d.ts +1 -1
- package/dist/discord.js +2 -1
- package/dist/evidence-pack.js +1 -1
- package/dist/evidence.d.ts +28 -0
- package/dist/evidence.js +87 -17
- package/dist/exec.d.ts +32 -0
- package/dist/exec.js +229 -10
- package/dist/flow-actions.js +2 -1
- package/dist/guides.js +14 -11
- package/dist/invoke.js +110 -18
- package/dist/landed-cleanup.d.ts +157 -0
- package/dist/landed-cleanup.js +707 -0
- package/dist/lead-cli.js +22 -19
- package/dist/lead-contract.js +1 -1
- package/dist/lead-doors.js +49 -2
- package/dist/lead-follow.d.ts +2 -0
- package/dist/lead-follow.js +138 -88
- package/dist/lead-tools.js +48 -8
- package/dist/live-input.d.ts +68 -0
- package/dist/live-input.js +254 -0
- package/dist/live.d.ts +1 -1
- package/dist/live.js +4 -2
- package/dist/mailbox.js +3 -2
- package/dist/maintenance.d.ts +2 -0
- package/dist/maintenance.js +5 -2
- package/dist/mcp-core.js +1 -1
- package/dist/operate-remote-arguments.js +5 -1
- package/dist/operate-remote.js +1 -1
- package/dist/operate.d.ts +1 -1
- package/dist/operate.js +201 -19
- package/dist/orphan-sweep.d.ts +2 -0
- package/dist/orphan-sweep.js +5 -3
- package/dist/project-delete-ui.d.ts +11 -0
- package/dist/project-delete-ui.js +29 -2
- package/dist/project-tools.d.ts +7 -11
- package/dist/project-tools.js +13 -37
- package/dist/provider.d.ts +73 -8
- package/dist/provider.js +87 -17
- package/dist/result-completion.d.ts +7 -0
- package/dist/result-completion.js +9 -0
- package/dist/runner.d.ts +4 -2
- package/dist/runner.js +3 -3
- package/dist/serve.js +22 -3
- package/dist/server/chrome.d.ts +6 -3
- package/dist/server/chrome.js +8 -4
- package/dist/server/console.css +9 -64
- package/dist/server/live.d.ts +3 -0
- package/dist/server/live.js +35 -2
- package/dist/server/pages.js +59 -35
- package/dist/server/render-chat.js +14 -2
- package/dist/server/render-tasks.d.ts +14 -2
- package/dist/server/render-tasks.js +38 -20
- package/dist/server/route-table.js +4 -1
- package/dist/server/settings.js +2 -1
- package/dist/server/task-views.js +10 -0
- package/dist/server/tasks.js +63 -0
- package/dist/shared-deps.d.ts +9 -4
- package/dist/shared-deps.js +89 -13
- package/dist/slack-socket.d.ts +12 -0
- package/dist/slack-socket.js +29 -0
- package/dist/slack.d.ts +0 -7
- package/dist/slack.js +2 -24
- package/dist/staged-runtimes.d.ts +16 -4
- package/dist/staged-runtimes.js +160 -38
- package/dist/steer-live.d.ts +19 -0
- package/dist/steer-live.js +93 -0
- package/dist/steer-mailbox.d.ts +39 -0
- package/dist/steer-mailbox.js +207 -0
- package/dist/steer-status.d.ts +25 -0
- package/dist/steer-status.js +44 -0
- package/dist/storage-sweep-child.d.ts +1 -0
- package/dist/storage-sweep-child.js +76 -0
- package/dist/storage-sweep-process.d.ts +41 -0
- package/dist/storage-sweep-process.js +187 -0
- package/dist/storage-sweep.d.ts +30 -6
- package/dist/storage-sweep.js +214 -28
- package/dist/storage-ui.d.ts +2 -0
- package/dist/storage-ui.js +16 -4
- package/dist/storage.d.ts +6 -0
- package/dist/storage.js +35 -0
- package/dist/store.d.ts +202 -2
- package/dist/store.js +440 -13
- package/dist/surface.js +5 -3
- package/dist/sweep-gate.d.ts +10 -0
- package/dist/sweep-gate.js +18 -0
- package/dist/sweep-quarantine.d.ts +28 -0
- package/dist/sweep-quarantine.js +153 -0
- package/dist/task-status.d.ts +2 -0
- package/dist/task-status.js +5 -1
- package/dist/team-updates.js +3 -3
- package/dist/test-temp.d.ts +6 -3
- package/dist/test-temp.js +15 -9
- package/dist/toolroll-update.js +15 -2
- package/dist/work-index.d.ts +1 -0
- package/dist/work-index.js +32 -12
- package/dist/work-summary.d.ts +2 -2
- package/dist/workspace-revision.js +3 -1
- package/dist/worktree.d.ts +3 -1
- package/dist/worktree.js +93 -10
- package/package.json +21 -21
- package/scripts/provider-canary.mjs +235 -147
|
@@ -64,6 +64,8 @@ export declare function finishedCheckouts(store: Store, now: Date, repo?: string
|
|
|
64
64
|
taskId: string | null;
|
|
65
65
|
finishedAt: string;
|
|
66
66
|
}[];
|
|
67
|
+
/** Why a checkout stays as a clean-up by hand reads it (in use, or its task not done with it), before its files; null: it may go. */
|
|
68
|
+
export declare function checkoutKeepWhy(pool: WorktreePool, row: WorktreeRow, statuses: ReturnType<typeof taskStatuses>, now: Date): KeepWhy | null;
|
|
67
69
|
/**
|
|
68
70
|
* What a clean-up would remove now, how much space it would free, and what stays and why. `manual` is a clean-up by
|
|
69
71
|
* hand (it doesn't wait for the setting); otherwise it is the worker's pass under the setting. Reads only.
|
|
@@ -92,6 +94,7 @@ export declare function cleanCheckouts(store: Store, pool: WorktreePool, now: ()
|
|
|
92
94
|
actor: string;
|
|
93
95
|
repo?: string;
|
|
94
96
|
only?: ReadonlySet<string>;
|
|
97
|
+
spare?: (path: string) => boolean;
|
|
95
98
|
}): Promise<CleanResult>;
|
|
96
99
|
export type SlimResult = {
|
|
97
100
|
slimmed: {
|
package/dist/checkout-cleanup.js
CHANGED
|
@@ -242,6 +242,10 @@ function keptFor(pool, row, statuses, now, cleanup) {
|
|
|
242
242
|
const dueAt = new Date(Date.parse(since) + days * DAY_MS).toISOString();
|
|
243
243
|
return dueAt > now.toISOString() ? { why: "not due yet", taskId, dueAt } : { why: null, taskId };
|
|
244
244
|
}
|
|
245
|
+
/** Why a checkout stays as a clean-up by hand reads it (in use, or its task not done with it), before its files; null: it may go. */
|
|
246
|
+
export function checkoutKeepWhy(pool, row, statuses, now) {
|
|
247
|
+
return keptFor(pool, row, statuses, now, "manual").why;
|
|
248
|
+
}
|
|
245
249
|
async function eachAtMost(items, limit, work) {
|
|
246
250
|
const out = new Array(items.length);
|
|
247
251
|
let next = 0;
|
|
@@ -298,11 +302,16 @@ export async function cleanCheckouts(store, pool, now, options) {
|
|
|
298
302
|
const sizes = new Map();
|
|
299
303
|
const wanted = (row, fresh) => {
|
|
300
304
|
// Right before a checkout goes, where its task stands is read afresh, and its size taken for the ledger.
|
|
305
|
+
// `spare`: live work uses it (storage-sweep.ts), asked at both looks.
|
|
301
306
|
if (fresh)
|
|
302
307
|
statuses = taskStatuses(store, now());
|
|
303
|
-
const go = keptFor(pool, row, statuses, now(), options.manual ? "manual" : cleanup).why === null;
|
|
304
|
-
if (go && fresh)
|
|
308
|
+
const go = keptFor(pool, row, statuses, now(), options.manual ? "manual" : cleanup).why === null && options.spare?.(row.path) !== true;
|
|
309
|
+
if (go && fresh) {
|
|
305
310
|
sizes.set(row.path, diskBytes([row.path]).get(row.path) ?? 0);
|
|
311
|
+
// du can be slow. The reservation excludes a concurrent checkout lease, and this last read also catches
|
|
312
|
+
// an open run/claim or task change that arrived while size was measured in the sweep child.
|
|
313
|
+
return keptFor(pool, row, taskStatuses(store, now()), now(), options.manual ? "manual" : cleanup).why === null && options.spare?.(row.path) !== true;
|
|
314
|
+
}
|
|
306
315
|
return go;
|
|
307
316
|
};
|
|
308
317
|
const pruned = await pool.prune(rows, wanted, options.manual ? Infinity : AUTO_MAX);
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The answers that need nothing but this file: `--version` and the top-level
|
|
3
|
+
* usage. The bin asks here before importing the CLI, so neither loads the
|
|
4
|
+
* store, the contracts or a single command family. main() asks here too, so
|
|
5
|
+
* both roads print the same bytes.
|
|
6
|
+
*/
|
|
7
|
+
/** The line to print and exit 0 with, or null when the CLI has to run. */
|
|
8
|
+
export declare function quickAnswer(argv: readonly string[]): string | null;
|
package/dist/cli-fast.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The answers that need nothing but this file: `--version` and the top-level
|
|
3
|
+
* usage. The bin asks here before importing the CLI, so neither loads the
|
|
4
|
+
* store, the contracts or a single command family. main() asks here too, so
|
|
5
|
+
* both roads print the same bytes.
|
|
6
|
+
*/
|
|
7
|
+
import { HELP } from "./cli-help.js";
|
|
8
|
+
import { PACKAGE_VERSION } from "./version.js";
|
|
9
|
+
/** Exactly the invocations whose whole answer is top-level usage — anything more goes through the CLI. */
|
|
10
|
+
const HELP_INVOCATIONS = new Set(["--help", "-h", "help"]);
|
|
11
|
+
/** The line to print and exit 0 with, or null when the CLI has to run. */
|
|
12
|
+
export function quickAnswer(argv) {
|
|
13
|
+
if (argv[0] === "--version" || argv[0] === "-v")
|
|
14
|
+
return PACKAGE_VERSION;
|
|
15
|
+
if (argv.length === 1 && HELP_INVOCATIONS.has(argv[0]))
|
|
16
|
+
return HELP;
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The top-level usage text, on its own so `toolroll --help` can print it
|
|
3
|
+
* without loading every command family (see cli-fast.ts).
|
|
4
|
+
*/
|
|
5
|
+
export declare const HELP = "toolroll \u2014 a control plane for unattended coding agents\n\nUsage\n toolroll [path...] report what is in flight\n toolroll pulls report what is waiting on a person\n toolroll graph report which work graph is already here\n toolroll repos list connected repositories, and how to adjust\n toolroll repos add <path> add a project; it is in the console at once (no path: the repo you are in)\n toolroll repos remove <path>\n take it out of the console; its tasks and results stay\n toolroll repos add-from-github <owner/name> --root <dir>\n preview, then clone and connect (--yes)\n toolroll link put `toolroll` on your PATH\n toolroll unlink take it off again\n toolroll update update to the latest release: verified, drained, undoable\n (preview first; --yes, --now, --at HH:MM, --rollback)\n toolroll release <branch> release Toolroll itself: gate, your approval, deploy, merge, tag, publish\n (resumable: rerun to continue; --help)\n toolroll contract the machine contract: envelope version + capabilities\n (--commands dumps the declared command guide)\n toolroll skills install --claude-code [--dir <path>]\n install this binary's guides for Claude Code (preview first)\n toolroll skills install teach a repo's agents this queue exists (preview first)\n toolroll skills list the guides this exact binary serves\n toolroll skills get <name> print one guide (version-matched, never stale)\n toolroll demo a seeded throwaway sandbox \u2014 see it working in 90 seconds\n toolroll up app + builder for every saved project \u2014 the normal start\n toolroll onboard make your agent Toolroll's lead: add this repo, install its skill (--yes), offer starter flows (--starter)\n toolroll status running, queued, ready results, release check and plan windows\n toolroll health recent server latency, write waits and live streams\n toolroll integrations which integrations work, and what to do about the ones that don't (--json)\n toolroll lead token mint your lead agent's credential: its own work pings nobody\n toolroll lead say \"<text>\" (the lead) one short message in its person's chat\n\nOperating the queue \u2014 `toolroll task` prints the whole surface,\nand any queue command + --help prints it too\n toolroll approver add <name>\n mint the credential that lets a person say yes\n toolroll ready what could be dispatched right now\n toolroll check-progress <run> current or final approved check progress\n toolroll task wait <id> [--timeout <seconds>]\n wait for this attempt to finish or need a person\n toolroll task add <title> queue work\n toolroll task scope <id> --goal <text>\n state what success is; approval binds to it\n toolroll task approve <id>\n the yes \u2014 nothing builds without one\n toolroll claim <id> --runner <name>\n toolroll heartbeat <lease> / worker release <lease> / reap\n toolroll tick --runner <name> --token <t> --repo <path>\n one unattended pass over the ready set\n toolroll flows list | show <id> | create | edit | trigger | script | card | archive\n set up and inspect flows (writes preview until --yes)\n toolroll chat --as <you> --token <t>\n talk to your lead: one conversation across every\n project; it proposes, you confirm (--say \"\u2026\" for one turn)\n toolroll serve --repo <path> advanced: run only the console\n (--editor vscode with --runner: file links\n open in VS Code on the device you browse from)\n toolroll watch / daemon install advanced: run only the builder\n toolroll reconcile recover what the last stretch left behind\n\nWith nothing connected it reports everything it can find below the working\ndirectory. Once you connect repositories it reports those instead.\n\nOptions\n --all report everything discoverable, ignoring connected repos\n --depth <n> directory levels to descend (default: 6)\n --hidden include dot-directories, which are skipped by default\n --dirty also read each working tree for uncommitted files\n --local branches only: no network, no pull requests, no issues\n --json emit a machine-readable envelope instead of a report\n -o <file> also write that envelope to a file (requires --json)\n -h, --help show this\n\nNothing is written, installed, or configured. Every repository is read\nthrough git with --no-optional-locks, so a scan never contends for the\nindex lock with an editor you have open.\n\n--dirty is off by default because reading a working tree is unbounded\nwork: on a large or cloud-synced repo `git status` can take minutes,\nwhere listing branches takes milliseconds.\n\nlink shows what it would do and changes nothing; add --yes to apply it,\nor --to <dir> to choose where. It never uses sudo, never leaves your\nhome directory, and never touches a file it did not create.";
|
package/dist/cli-help.js
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The top-level usage text, on its own so `toolroll --help` can print it
|
|
3
|
+
* without loading every command family (see cli-fast.ts).
|
|
4
|
+
*/
|
|
5
|
+
import { DEFAULT_MAX_DEPTH } from "./scan.js";
|
|
6
|
+
export const HELP = `toolroll — a control plane for unattended coding agents
|
|
7
|
+
|
|
8
|
+
Usage
|
|
9
|
+
toolroll [path...] report what is in flight
|
|
10
|
+
toolroll pulls report what is waiting on a person
|
|
11
|
+
toolroll graph report which work graph is already here
|
|
12
|
+
toolroll repos list connected repositories, and how to adjust
|
|
13
|
+
toolroll repos add <path> add a project; it is in the console at once (no path: the repo you are in)
|
|
14
|
+
toolroll repos remove <path>
|
|
15
|
+
take it out of the console; its tasks and results stay
|
|
16
|
+
toolroll repos add-from-github <owner/name> --root <dir>
|
|
17
|
+
preview, then clone and connect (--yes)
|
|
18
|
+
toolroll link put \`toolroll\` on your PATH
|
|
19
|
+
toolroll unlink take it off again
|
|
20
|
+
toolroll update update to the latest release: verified, drained, undoable
|
|
21
|
+
(preview first; --yes, --now, --at HH:MM, --rollback)
|
|
22
|
+
toolroll release <branch> release Toolroll itself: gate, your approval, deploy, merge, tag, publish
|
|
23
|
+
(resumable: rerun to continue; --help)
|
|
24
|
+
toolroll contract the machine contract: envelope version + capabilities
|
|
25
|
+
(--commands dumps the declared command guide)
|
|
26
|
+
toolroll skills install --claude-code [--dir <path>]
|
|
27
|
+
install this binary's guides for Claude Code (preview first)
|
|
28
|
+
toolroll skills install teach a repo's agents this queue exists (preview first)
|
|
29
|
+
toolroll skills list the guides this exact binary serves
|
|
30
|
+
toolroll skills get <name> print one guide (version-matched, never stale)
|
|
31
|
+
toolroll demo a seeded throwaway sandbox — see it working in 90 seconds
|
|
32
|
+
toolroll up app + builder for every saved project — the normal start
|
|
33
|
+
toolroll onboard make your agent Toolroll's lead: add this repo, install its skill (--yes), offer starter flows (--starter)
|
|
34
|
+
toolroll status running, queued, ready results, release check and plan windows
|
|
35
|
+
toolroll health recent server latency, write waits and live streams
|
|
36
|
+
toolroll integrations which integrations work, and what to do about the ones that don't (--json)
|
|
37
|
+
toolroll lead token mint your lead agent's credential: its own work pings nobody
|
|
38
|
+
toolroll lead say "<text>" (the lead) one short message in its person's chat
|
|
39
|
+
|
|
40
|
+
Operating the queue — \`toolroll task\` prints the whole surface,
|
|
41
|
+
and any queue command + --help prints it too
|
|
42
|
+
toolroll approver add <name>
|
|
43
|
+
mint the credential that lets a person say yes
|
|
44
|
+
toolroll ready what could be dispatched right now
|
|
45
|
+
toolroll check-progress <run> current or final approved check progress
|
|
46
|
+
toolroll task wait <id> [--timeout <seconds>]
|
|
47
|
+
wait for this attempt to finish or need a person
|
|
48
|
+
toolroll task add <title> queue work
|
|
49
|
+
toolroll task scope <id> --goal <text>
|
|
50
|
+
state what success is; approval binds to it
|
|
51
|
+
toolroll task approve <id>
|
|
52
|
+
the yes — nothing builds without one
|
|
53
|
+
toolroll claim <id> --runner <name>
|
|
54
|
+
toolroll heartbeat <lease> / worker release <lease> / reap
|
|
55
|
+
toolroll tick --runner <name> --token <t> --repo <path>
|
|
56
|
+
one unattended pass over the ready set
|
|
57
|
+
toolroll flows list | show <id> | create | edit | trigger | script | card | archive
|
|
58
|
+
set up and inspect flows (writes preview until --yes)
|
|
59
|
+
toolroll chat --as <you> --token <t>
|
|
60
|
+
talk to your lead: one conversation across every
|
|
61
|
+
project; it proposes, you confirm (--say "…" for one turn)
|
|
62
|
+
toolroll serve --repo <path> advanced: run only the console
|
|
63
|
+
(--editor vscode with --runner: file links
|
|
64
|
+
open in VS Code on the device you browse from)
|
|
65
|
+
toolroll watch / daemon install advanced: run only the builder
|
|
66
|
+
toolroll reconcile recover what the last stretch left behind
|
|
67
|
+
|
|
68
|
+
With nothing connected it reports everything it can find below the working
|
|
69
|
+
directory. Once you connect repositories it reports those instead.
|
|
70
|
+
|
|
71
|
+
Options
|
|
72
|
+
--all report everything discoverable, ignoring connected repos
|
|
73
|
+
--depth <n> directory levels to descend (default: ${DEFAULT_MAX_DEPTH})
|
|
74
|
+
--hidden include dot-directories, which are skipped by default
|
|
75
|
+
--dirty also read each working tree for uncommitted files
|
|
76
|
+
--local branches only: no network, no pull requests, no issues
|
|
77
|
+
--json emit a machine-readable envelope instead of a report
|
|
78
|
+
-o <file> also write that envelope to a file (requires --json)
|
|
79
|
+
-h, --help show this
|
|
80
|
+
|
|
81
|
+
Nothing is written, installed, or configured. Every repository is read
|
|
82
|
+
through git with --no-optional-locks, so a scan never contends for the
|
|
83
|
+
index lock with an editor you have open.
|
|
84
|
+
|
|
85
|
+
--dirty is off by default because reading a working tree is unbounded
|
|
86
|
+
work: on a large or cloud-synced repo \`git status\` can take minutes,
|
|
87
|
+
where listing branches takes milliseconds.
|
|
88
|
+
|
|
89
|
+
link shows what it would do and changes nothing; add --yes to apply it,
|
|
90
|
+
or --to <dir> to choose where. It never uses sudo, never leaves your
|
|
91
|
+
home directory, and never touches a file it did not create.`;
|
package/dist/cli.d.ts
CHANGED
|
@@ -14,9 +14,10 @@ import { previewGithubRepo, cloneGithubRepo } from "./onboard.js";
|
|
|
14
14
|
import { type SessionCliOptions } from "./session-cli.js";
|
|
15
15
|
import { type TeamCliOptions } from "./team-cli.js";
|
|
16
16
|
import { type RemoteExecOptions } from "./remote-exec.js";
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
19
|
-
import {
|
|
17
|
+
import type { UpdateCliDeps } from "./toolroll-update-cli.js";
|
|
18
|
+
import type { ReleaseCliDeps } from "./release-cli.js";
|
|
19
|
+
import type { OperateOptions } from "./operate.js";
|
|
20
|
+
import { HELP } from "./cli-help.js";
|
|
20
21
|
export type CliOptions = {
|
|
21
22
|
roots: string[];
|
|
22
23
|
/** The positional tokens exactly as typed, index-aligned with `roots` —
|
|
@@ -41,7 +42,8 @@ export type ParseResult = {
|
|
|
41
42
|
error: string;
|
|
42
43
|
};
|
|
43
44
|
type Write = (line: string) => void;
|
|
44
|
-
|
|
45
|
+
/** The top-level usage text (cli-help.ts), re-exported where it always lived. */
|
|
46
|
+
export { HELP };
|
|
45
47
|
export declare function parseArgs(argv: readonly string[]): ParseResult;
|
|
46
48
|
/** The commands that operate the queue rather than report on the world. */
|
|
47
49
|
/** Every verb the CLI routes OUTSIDE runOperate. Exported (with
|
|
@@ -143,4 +145,3 @@ export declare const CONTRACT_FLAGS: readonly ["json", "commands"];
|
|
|
143
145
|
export declare function isDirectInvocation(moduleUrl: string, entry: string | undefined, toRealPath?: (path: string) => string): boolean;
|
|
144
146
|
/** The process entry the bin calls: the SQLite notice hushed, the exit code set. */
|
|
145
147
|
export declare function runCliProcess(argv: readonly string[]): Promise<void>;
|
|
146
|
-
export {};
|
package/dist/cli.js
CHANGED
|
@@ -29,106 +29,23 @@ import { runSessionCommand, SESSION_CLI_ACTIONS } from "./session-cli.js";
|
|
|
29
29
|
import { maybeRunTeamCommand, TEAM_CLI_ACTIONS } from "./team-cli.js";
|
|
30
30
|
import { deprecationWarning } from "./deprecations.js";
|
|
31
31
|
import { maybeRunRemoteCommand } from "./remote-exec.js";
|
|
32
|
-
import { runHealthCommand } from "./health-cli.js";
|
|
33
32
|
import { discover, inspectAll } from "./discover.js";
|
|
34
33
|
import { readPulls } from "./pulls.js";
|
|
35
34
|
import { detectGraphs, chooseBackend, setupOptions, LABELS as GRAPH_LABELS, } from "./graph.js";
|
|
36
35
|
import { openStore, openStoreReadOnly, databasePath } from "./store.js";
|
|
37
|
-
import { PACKAGE_VERSION } from "./version.js";
|
|
38
|
-
import { runUpdateCommand } from "./toolroll-update-cli.js";
|
|
39
|
-
import { runReleaseCommand } from "./release-cli.js";
|
|
40
|
-
import { runOperate, OPERATE_HELP } from "./operate.js";
|
|
41
36
|
import { renderReport, renderPulls, renderGraph } from "./render.js";
|
|
42
|
-
import { readRemote } from "./remote.js";
|
|
43
37
|
import { DEFAULT_MAX_DEPTH } from "./scan.js";
|
|
38
|
+
import { HELP } from "./cli-help.js";
|
|
39
|
+
import { quickAnswer } from "./cli-fast.js";
|
|
44
40
|
import { BIN_NAME, chooseTarget, planLink, applyLink, planUnlink, applyUnlink, } from "./link.js";
|
|
45
41
|
const USAGE_EXIT = 2;
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
toolroll repos add <path> add a project; it is in the console at once (no path: the repo you are in)
|
|
54
|
-
toolroll repos remove <path>
|
|
55
|
-
take it out of the console; its tasks and results stay
|
|
56
|
-
toolroll repos add-from-github <owner/name> --root <dir>
|
|
57
|
-
preview, then clone and connect (--yes)
|
|
58
|
-
toolroll link put \`toolroll\` on your PATH
|
|
59
|
-
toolroll unlink take it off again
|
|
60
|
-
toolroll update update to the latest release: verified, drained, undoable
|
|
61
|
-
(preview first; --yes, --now, --at HH:MM, --rollback)
|
|
62
|
-
toolroll release <branch> release Toolroll itself: gate, your approval, deploy, merge, tag, publish
|
|
63
|
-
(resumable: rerun to continue; --help)
|
|
64
|
-
toolroll contract the machine contract: envelope version + capabilities
|
|
65
|
-
(--commands dumps the declared command guide)
|
|
66
|
-
toolroll skills install --claude-code [--dir <path>]
|
|
67
|
-
install this binary's guides for Claude Code (preview first)
|
|
68
|
-
toolroll skills install teach a repo's agents this queue exists (preview first)
|
|
69
|
-
toolroll skills list the guides this exact binary serves
|
|
70
|
-
toolroll skills get <name> print one guide (version-matched, never stale)
|
|
71
|
-
toolroll demo a seeded throwaway sandbox — see it working in 90 seconds
|
|
72
|
-
toolroll up app + builder for every saved project — the normal start
|
|
73
|
-
toolroll onboard make your agent Toolroll's lead: add this repo, install its skill (--yes), offer starter flows (--starter)
|
|
74
|
-
toolroll status running, queued, ready results, release check and plan windows
|
|
75
|
-
toolroll health recent server latency, write waits and live streams
|
|
76
|
-
toolroll integrations which integrations work, and what to do about the ones that don't (--json)
|
|
77
|
-
toolroll lead token mint your lead agent's credential: its own work pings nobody
|
|
78
|
-
toolroll lead say "<text>" (the lead) one short message in its person's chat
|
|
79
|
-
|
|
80
|
-
Operating the queue — \`toolroll task\` prints the whole surface,
|
|
81
|
-
and any queue command + --help prints it too
|
|
82
|
-
toolroll approver add <name>
|
|
83
|
-
mint the credential that lets a person say yes
|
|
84
|
-
toolroll ready what could be dispatched right now
|
|
85
|
-
toolroll check-progress <run> current or final approved check progress
|
|
86
|
-
toolroll task wait <id> [--timeout <seconds>]
|
|
87
|
-
wait for this attempt to finish or need a person
|
|
88
|
-
toolroll task add <title> queue work
|
|
89
|
-
toolroll task scope <id> --goal <text>
|
|
90
|
-
state what success is; approval binds to it
|
|
91
|
-
toolroll task approve <id>
|
|
92
|
-
the yes — nothing builds without one
|
|
93
|
-
toolroll claim <id> --runner <name>
|
|
94
|
-
toolroll heartbeat <lease> / worker release <lease> / reap
|
|
95
|
-
toolroll tick --runner <name> --token <t> --repo <path>
|
|
96
|
-
one unattended pass over the ready set
|
|
97
|
-
toolroll flows list | show <id> | create | edit | trigger | script | card | archive
|
|
98
|
-
set up and inspect flows (writes preview until --yes)
|
|
99
|
-
toolroll chat --as <you> --token <t>
|
|
100
|
-
talk to your lead: one conversation across every
|
|
101
|
-
project; it proposes, you confirm (--say "…" for one turn)
|
|
102
|
-
toolroll serve --repo <path> advanced: run only the console
|
|
103
|
-
(--editor vscode with --runner: file links
|
|
104
|
-
open in VS Code on the device you browse from)
|
|
105
|
-
toolroll watch / daemon install advanced: run only the builder
|
|
106
|
-
toolroll reconcile recover what the last stretch left behind
|
|
107
|
-
|
|
108
|
-
With nothing connected it reports everything it can find below the working
|
|
109
|
-
directory. Once you connect repositories it reports those instead.
|
|
110
|
-
|
|
111
|
-
Options
|
|
112
|
-
--all report everything discoverable, ignoring connected repos
|
|
113
|
-
--depth <n> directory levels to descend (default: ${DEFAULT_MAX_DEPTH})
|
|
114
|
-
--hidden include dot-directories, which are skipped by default
|
|
115
|
-
--dirty also read each working tree for uncommitted files
|
|
116
|
-
--local branches only: no network, no pull requests, no issues
|
|
117
|
-
--json emit a machine-readable envelope instead of a report
|
|
118
|
-
-o <file> also write that envelope to a file (requires --json)
|
|
119
|
-
-h, --help show this
|
|
120
|
-
|
|
121
|
-
Nothing is written, installed, or configured. Every repository is read
|
|
122
|
-
through git with --no-optional-locks, so a scan never contends for the
|
|
123
|
-
index lock with an editor you have open.
|
|
124
|
-
|
|
125
|
-
--dirty is off by default because reading a working tree is unbounded
|
|
126
|
-
work: on a large or cloud-synced repo \`git status\` can take minutes,
|
|
127
|
-
where listing branches takes milliseconds.
|
|
128
|
-
|
|
129
|
-
link shows what it would do and changes nothing; add --yes to apply it,
|
|
130
|
-
or --to <dir> to choose where. It never uses sudo, never leaves your
|
|
131
|
-
home directory, and never touches a file it did not create.`;
|
|
42
|
+
/** The queue's commands live in operate.ts, the largest module graph here: loaded when one of them runs, not before. */
|
|
43
|
+
async function runOperate(command, argv, write, options) {
|
|
44
|
+
const operate = await import("./operate.js");
|
|
45
|
+
return operate.runOperate(command, argv, write, options);
|
|
46
|
+
}
|
|
47
|
+
/** The top-level usage text (cli-help.ts), re-exported where it always lived. */
|
|
48
|
+
export { HELP };
|
|
132
49
|
export function parseArgs(argv) {
|
|
133
50
|
const roots = [];
|
|
134
51
|
const rawRoots = [];
|
|
@@ -290,8 +207,9 @@ export function extractOutputFlag(argv) {
|
|
|
290
207
|
return { args, ...(outputFile === undefined ? {} : { outputFile }) };
|
|
291
208
|
}
|
|
292
209
|
export async function main(argv, write = line => console.log(line), mainOptions = {}) {
|
|
293
|
-
|
|
294
|
-
|
|
210
|
+
const quick = quickAnswer(argv);
|
|
211
|
+
if (quick !== null) {
|
|
212
|
+
write(quick);
|
|
295
213
|
return 0;
|
|
296
214
|
}
|
|
297
215
|
const extracted = extractOutputFlag(argv);
|
|
@@ -392,8 +310,9 @@ async function dispatch(argv, write, mainOptions) {
|
|
|
392
310
|
if (argv[0] === "routine")
|
|
393
311
|
return routinesMoved(argv, write);
|
|
394
312
|
// A saved API token sends commands marked remote to the central server, before anything local opens.
|
|
313
|
+
// Command families below load when their command runs, so one command never pays for the others.
|
|
395
314
|
if (argv[0] === 'health')
|
|
396
|
-
return runHealthCommand(argv.slice(1), write, mainOptions.team ?? mainOptions.remote);
|
|
315
|
+
return (await import("./health-cli.js")).runHealthCommand(argv.slice(1), write, mainOptions.team ?? mainOptions.remote);
|
|
397
316
|
const central = await maybeRunRemoteCommand(argv, mainOptions.remote ?? mainOptions.team);
|
|
398
317
|
if (typeof central === "number")
|
|
399
318
|
return central;
|
|
@@ -415,8 +334,9 @@ async function dispatch(argv, write, mainOptions) {
|
|
|
415
334
|
return runLinkCommand(first, rest, write, mainOptions.binSource);
|
|
416
335
|
}
|
|
417
336
|
if (first === "update")
|
|
418
|
-
return runUpdateCommand(rest, write, mainOptions.update);
|
|
337
|
+
return (await import("./toolroll-update-cli.js")).runUpdateCommand(rest, write, mainOptions.update);
|
|
419
338
|
if (first === "release") {
|
|
339
|
+
const { runReleaseCommand } = await import("./release-cli.js");
|
|
420
340
|
return runReleaseCommand(rest, write, { releaseLease: lease => runOperate("worker", ["release", ...lease], write, mainOptions.operate ?? {}), ...mainOptions.release });
|
|
421
341
|
}
|
|
422
342
|
if (first === "contract")
|
|
@@ -500,6 +420,7 @@ async function dispatch(argv, write, mainOptions) {
|
|
|
500
420
|
async function maybeReadRemote(repos, options) {
|
|
501
421
|
if (options.local)
|
|
502
422
|
return undefined;
|
|
423
|
+
const { readRemote } = await import("./remote.js");
|
|
503
424
|
return readRemote(repos.map(repo => ({ path: repo.path, remoteUrl: repo.remoteUrl })));
|
|
504
425
|
}
|
|
505
426
|
function configFile() {
|
|
@@ -156,7 +156,8 @@ export declare const CONSOLE_FORMS: {
|
|
|
156
156
|
readonly revise: FormContract<"batch" | "return" | "source">;
|
|
157
157
|
readonly followUp: FormContract<"level" | "return">;
|
|
158
158
|
readonly resolveIncident: FormContract<"return">;
|
|
159
|
-
readonly taskSteer: FormContract<"note">;
|
|
159
|
+
readonly taskSteer: FormContract<"note" | "return" | "run">;
|
|
160
|
+
readonly taskReply: FormContract<"answer" | "question">;
|
|
160
161
|
readonly taskHold: FormContract<"reason">;
|
|
161
162
|
readonly taskBlock: FormContract<"on">;
|
|
162
163
|
readonly taskRepairDependency: FormContract<"blocker" | "operation" | "replacement">;
|
|
@@ -173,6 +174,7 @@ export declare const CONSOLE_FORMS: {
|
|
|
173
174
|
readonly taskAcceptProof: FormContract<"note" | "return" | "run">;
|
|
174
175
|
readonly taskComplete: FormContract<"accept" | "note" | "publish" | "receipt" | "return" | "run">;
|
|
175
176
|
readonly taskStop: FormContract<"return" | "run">;
|
|
177
|
+
readonly taskPause: FormContract<"mode" | "note" | "request" | "return" | "run">;
|
|
176
178
|
readonly taskResume: FormContract<"nonce" | "return" | "run" | "token">;
|
|
177
179
|
};
|
|
178
180
|
export type ConsoleFormName = keyof typeof CONSOLE_FORMS;
|
|
@@ -167,7 +167,8 @@ export const CONSOLE_FORMS = {
|
|
|
167
167
|
followUp: formContract("POST /r/<run>/checks|add-tests", ["return", "level"]),
|
|
168
168
|
resolveIncident: formContract("POST /i/<id>/resolve", ["return"]),
|
|
169
169
|
// A task's verbs (/t/<task>/<verb>), one body each.
|
|
170
|
-
taskSteer: formContract("POST /t/<task>/steer", ["note"]),
|
|
170
|
+
taskSteer: formContract("POST /t/<task>/steer", ["note", "return", "run"]),
|
|
171
|
+
taskReply: formContract("POST /t/<task>/reply", ["question", "answer"]),
|
|
171
172
|
taskHold: formContract("POST /t/<task>/hold", ["reason"]),
|
|
172
173
|
taskBlock: formContract("POST /t/<task>/block|unblock", ["on"]),
|
|
173
174
|
taskRepairDependency: formContract("POST /t/<task>/repair-dependency", ["blocker", "operation", "replacement"]),
|
|
@@ -184,6 +185,9 @@ export const CONSOLE_FORMS = {
|
|
|
184
185
|
taskAcceptProof: formContract("POST /t/<task>/accept-proof", ["run", "note", "return"]),
|
|
185
186
|
taskComplete: formContract("POST /t/<task>/complete", ["receipt", "run", "accept", "note", "publish", "return"]),
|
|
186
187
|
taskStop: formContract("POST /t/<task>/stop", ["run", "return"]),
|
|
188
|
+
// Pause, or Pause and steer when a note rides along, or Resume (mode=resume): the exact run shown, and the page's own
|
|
189
|
+
// request id.
|
|
190
|
+
taskPause: formContract("POST /t/<task>/pause", ["run", "request", "note", "mode", "return"]),
|
|
187
191
|
taskResume: formContract("POST /t/<task>/resume|resume-arm", ["run", "token", "nonce", "return"]),
|
|
188
192
|
};
|
|
189
193
|
/** The console POSTs whose handlers read no field (sign-out not even the shared guard): their contract is the empty form. */
|
|
@@ -656,7 +656,14 @@ export declare const LEAD_TOOL_INPUTS: {
|
|
|
656
656
|
}, z.core.$strict>;
|
|
657
657
|
readonly propose_steer: z.ZodObject<{
|
|
658
658
|
task: z.ZodString;
|
|
659
|
-
note: z.ZodString
|
|
659
|
+
note: z.ZodOptional<z.ZodString>;
|
|
660
|
+
mode: z.ZodOptional<z.ZodEnum<{
|
|
661
|
+
note: "note";
|
|
662
|
+
pause: "pause";
|
|
663
|
+
"pause-and-steer": "pause-and-steer";
|
|
664
|
+
resume: "resume";
|
|
665
|
+
}>>;
|
|
666
|
+
question: z.ZodOptional<z.ZodNumber>;
|
|
660
667
|
}, z.core.$strict>;
|
|
661
668
|
readonly propose_dependency_repair: z.ZodObject<{
|
|
662
669
|
task: z.ZodString;
|
|
@@ -1318,7 +1325,14 @@ export declare const LEAD_TOOL_READ_INPUTS: {
|
|
|
1318
1325
|
}, z.core.$strict>;
|
|
1319
1326
|
readonly propose_steer: z.ZodObject<{
|
|
1320
1327
|
task: z.ZodString;
|
|
1321
|
-
note: z.ZodString
|
|
1328
|
+
note: z.ZodOptional<z.ZodString>;
|
|
1329
|
+
mode: z.ZodOptional<z.ZodEnum<{
|
|
1330
|
+
note: "note";
|
|
1331
|
+
pause: "pause";
|
|
1332
|
+
"pause-and-steer": "pause-and-steer";
|
|
1333
|
+
resume: "resume";
|
|
1334
|
+
}>>;
|
|
1335
|
+
question: z.ZodOptional<z.ZodNumber>;
|
|
1322
1336
|
}, z.core.$strict>;
|
|
1323
1337
|
readonly propose_dependency_repair: z.ZodObject<{
|
|
1324
1338
|
task: z.ZodString;
|
|
@@ -130,7 +130,11 @@ export const LEAD_TOOL_INPUTS = {
|
|
|
130
130
|
propose_reserve: z.strictObject({ task: taskRef, worker: text("workerName").nullable() }),
|
|
131
131
|
propose_hold: z.strictObject({ task: taskRef, reason: text("proposalReason") }),
|
|
132
132
|
propose_unhold: z.strictObject({ task: taskRef }),
|
|
133
|
-
|
|
133
|
+
// mode: a note (the default), Pause (stop a running Claude build's turn, keep the build), Pause and steer, or Resume
|
|
134
|
+
// (a paused build goes on where it stopped, without a note).
|
|
135
|
+
// question: a running agent's open question (Agents board); the note is its reply, sent as an ordinary note.
|
|
136
|
+
propose_steer: z.strictObject({ task: taskRef, note: note.optional(), mode: z.enum(["note", "pause", "pause-and-steer", "resume"]).optional(),
|
|
137
|
+
question: z.number().int().positive().optional().describe("A running agent's open question (get_task agentQuestions): the note becomes its reply and closes it.") }),
|
|
134
138
|
propose_dependency_repair: z.strictObject({ task: taskRef, blocker: taskRef, operation: z.enum(["retry", "unlink", "replace"]), replacement: taskRef.optional() }),
|
|
135
139
|
propose_scope: z.strictObject({ task: taskRef, goal: scopeText, not: scopeText.nullable().optional(), touches: touches.optional(), acceptance }),
|
|
136
140
|
propose_agents: z.strictObject({
|