toolroll 0.9.94 → 0.9.96
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 +17 -1
- package/dist/agent-fence.d.ts +6 -0
- package/dist/agent-fence.js +2 -2
- package/dist/assignment-status.d.ts +1 -1
- package/dist/assignment-ui.js +2 -0
- package/dist/attest.d.ts +3 -0
- package/dist/attest.js +10 -0
- package/dist/browser/terminal.js +1 -1
- package/dist/browser/workspace.css +1 -1
- package/dist/browser/workspace.js +24 -24
- package/dist/browser-crew.js +2 -0
- package/dist/browser-workspace.d.ts +5 -0
- package/dist/build-review.js +2 -0
- package/dist/builder.d.ts +7 -2
- package/dist/builder.js +183 -79
- package/dist/card-catalog.d.ts +209 -0
- package/dist/card-catalog.js +133 -0
- package/dist/card-cli.d.ts +43 -0
- package/dist/card-cli.js +44 -0
- package/dist/card-render.d.ts +43 -0
- package/dist/card-render.js +260 -0
- package/dist/card-sources.d.ts +68 -0
- package/dist/card-sources.js +234 -0
- package/dist/chat-actions.d.ts +95 -8
- package/dist/chat-actions.js +449 -45
- package/dist/chat-approval.d.ts +13 -0
- package/dist/chat-approval.js +39 -9
- package/dist/chat-card-part.d.ts +11 -0
- package/dist/chat-card-part.js +18 -0
- package/dist/chat-card.d.ts +46 -0
- package/dist/chat-card.js +99 -0
- package/dist/chat-channel.d.ts +2 -0
- package/dist/chat-channel.js +26 -14
- package/dist/chat-controls.d.ts +4 -0
- package/dist/chat-controls.js +4 -0
- package/dist/chat-decide.d.ts +3 -14
- package/dist/chat-decide.js +43 -54
- package/dist/chat-delivery.js +13 -4
- package/dist/chat-flow.d.ts +0 -27
- package/dist/chat-flow.js +31 -2
- package/dist/chat-quiet.js +1 -1
- package/dist/chat-task-actions.d.ts +3 -2
- package/dist/chat-task-actions.js +19 -5
- package/dist/chat-terms.d.ts +14 -2
- package/dist/chat-terms.js +35 -0
- package/dist/check-failure.d.ts +2 -0
- package/dist/check-failure.js +34 -2
- package/dist/check-repair.d.ts +47 -0
- package/dist/check-repair.js +240 -0
- package/dist/claim.d.ts +6 -0
- package/dist/claim.js +13 -2
- package/dist/cli-help.d.ts +1 -1
- package/dist/cli-help.js +2 -0
- package/dist/cli.js +4 -0
- package/dist/coding-provider.d.ts +1 -1
- package/dist/coding-provider.js +9 -5
- package/dist/coding-workspace.d.ts +1 -1
- package/dist/coding-workspace.js +4 -4
- package/dist/contracts/chat-actions.d.ts +83 -0
- package/dist/contracts/chat-actions.js +18 -0
- package/dist/contracts/chat-card.d.ts +91 -0
- package/dist/contracts/chat-card.js +54 -0
- package/dist/contracts/chat-content.d.ts +191 -0
- package/dist/contracts/chat-content.js +4 -0
- package/dist/contracts/console-api.d.ts +2 -0
- package/dist/contracts/console-api.js +2 -0
- package/dist/contracts/flow-propose.d.ts +8 -1
- package/dist/contracts/flow-propose.js +3 -1
- package/dist/contracts/flow-send.d.ts +126 -0
- package/dist/contracts/flow-send.js +3 -0
- package/dist/contracts/lead-tools.d.ts +173 -0
- package/dist/contracts/lead-tools.js +15 -0
- package/dist/contracts/store-json.d.ts +16 -0
- package/dist/discord-chat.js +14 -0
- package/dist/dispatch.d.ts +1 -1
- package/dist/dispatch.js +7 -1
- package/dist/dispose.d.ts +19 -0
- package/dist/dispose.js +47 -7
- package/dist/eval-oracle.js +4 -1
- package/dist/evidence-pair.d.ts +53 -0
- package/dist/evidence-pair.js +128 -0
- package/dist/exhaustion.d.ts +17 -4
- package/dist/exhaustion.js +44 -4
- package/dist/export.js +1 -1
- package/dist/failing-first.d.ts +31 -0
- package/dist/failing-first.js +44 -0
- package/dist/fallback-schema.d.ts +8 -0
- package/dist/fallback-schema.js +40 -0
- package/dist/fallback.d.ts +138 -0
- package/dist/fallback.js +605 -0
- package/dist/findings.d.ts +224 -0
- package/dist/findings.js +449 -0
- package/dist/fleet-schema.d.ts +17 -0
- package/dist/fleet-schema.js +135 -0
- package/dist/flow-browser.js +2 -2
- package/dist/flow-code.d.ts +2 -2
- package/dist/flow-code.js +9 -5
- package/dist/flow-result-card.d.ts +22 -0
- package/dist/flow-result-card.js +55 -0
- package/dist/flow-send.js +12 -9
- package/dist/flow-steps.js +1 -1
- package/dist/flow-triggers.js +1 -1
- package/dist/flow-unattended.d.ts +26 -0
- package/dist/flow-unattended.js +12 -3
- package/dist/flows-ui.js +10 -2
- package/dist/follow-through-brief.d.ts +12 -0
- package/dist/follow-through-brief.js +31 -0
- package/dist/follow-through-cli.d.ts +23 -0
- package/dist/follow-through-cli.js +153 -0
- package/dist/git-incident.d.ts +16 -0
- package/dist/git-incident.js +69 -6
- package/dist/handover-note.d.ts +33 -0
- package/dist/handover-note.js +106 -0
- package/dist/invoke.d.ts +20 -1
- package/dist/invoke.js +108 -44
- package/dist/lead-cli.js +26 -24
- package/dist/lead-contract.js +1 -0
- package/dist/lead-doors.d.ts +4 -0
- package/dist/lead-doors.js +2 -2
- package/dist/lead-progress.js +2 -0
- package/dist/lead-tools.js +111 -32
- package/dist/lead.js +1 -1
- package/dist/local-owner.js +5 -0
- package/dist/modes.d.ts +6 -6
- package/dist/modes.js +3 -1
- package/dist/needs-you.d.ts +5 -2
- package/dist/needs-you.js +14 -2
- package/dist/operate-remote-arguments.js +1 -0
- package/dist/operate-remote.js +1 -1
- package/dist/operate.d.ts +1 -1
- package/dist/operate.js +165 -14
- package/dist/plan-login.d.ts +14 -0
- package/dist/plan-login.js +58 -0
- package/dist/planner.d.ts +1 -1
- package/dist/planner.js +2 -1
- package/dist/project-delete-ui.d.ts +12 -0
- package/dist/project-delete-ui.js +18 -1
- package/dist/project-delete.js +6 -0
- package/dist/project-knowledge.d.ts +6 -6
- package/dist/project-tools.d.ts +4 -4
- package/dist/project-tools.js +23 -7
- package/dist/protected-storage-look.d.ts +1 -0
- package/dist/protected-storage-look.js +13 -0
- package/dist/protected-storage.d.ts +70 -39
- package/dist/protected-storage.js +196 -147
- package/dist/provider-capture.d.ts +34 -0
- package/dist/provider-capture.js +53 -0
- package/dist/release-carry.js +10 -1
- package/dist/release.js +9 -1
- package/dist/scope.d.ts +22 -3
- package/dist/scope.js +71 -20
- package/dist/scout.d.ts +1 -1
- package/dist/scout.js +2 -1
- package/dist/serve.js +2 -0
- package/dist/server/chat.js +2 -2
- package/dist/server/console.css +50 -0
- package/dist/server/render-chat.js +14 -1
- package/dist/server/render-follow-through.d.ts +11 -0
- package/dist/server/render-follow-through.js +68 -0
- package/dist/server/render-results.js +1 -1
- package/dist/server/render-tasks.d.ts +3 -0
- package/dist/server/render-tasks.js +24 -5
- package/dist/server/route-table.js +3 -0
- package/dist/server/settings.js +37 -12
- package/dist/server/task-views.js +5 -0
- package/dist/server/tasks.js +76 -0
- package/dist/settings-groups-ui.d.ts +1 -0
- package/dist/settings-groups-ui.js +3 -1
- package/dist/settings-kit.js +3 -2
- package/dist/settings-proofs.js +3 -1
- package/dist/setup-guide.d.ts +2 -2
- package/dist/slack-chat.js +14 -1
- package/dist/steer-mailbox.d.ts +8 -1
- package/dist/steer-mailbox.js +164 -6
- package/dist/store.d.ts +11 -4
- package/dist/store.js +93 -30
- package/dist/surface.js +24 -4
- package/dist/task-control.d.ts +2 -1
- package/dist/task-status.js +5 -0
- package/dist/teardown-git.d.ts +2 -0
- package/dist/teardown-git.js +75 -19
- package/dist/telegram-lead.js +23 -6
- package/dist/telegram.js +12 -1
- package/dist/toolroll-update.js +2 -0
- package/dist/work-index.js +22 -7
- package/dist/work-summary.d.ts +1 -1
- package/dist/work-summary.js +5 -2
- package/dist/workspace-ui.d.ts +3 -1
- package/dist/workspace-ui.js +10 -1
- package/dist/worktree.js +23 -1
- package/package.json +2 -1
package/dist/project-tools.js
CHANGED
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
* the agent. A tool connected by signing in gives a run only an access token
|
|
20
20
|
* of its own (oauth-run-token.ts).
|
|
21
21
|
*/
|
|
22
|
+
import { prepareProtectedStorage, storageRefusalOf } from "./protected-storage.js";
|
|
22
23
|
import { inReadOnlyRequest } from "./read-only-request.js";
|
|
23
24
|
import { toolRefusal } from "./policy.js";
|
|
24
25
|
import { createHash } from "node:crypto";
|
|
@@ -572,17 +573,21 @@ export async function callProjectTool(spec, values, name, args, options) {
|
|
|
572
573
|
|| (result.structuredContent === undefined ? "" : JSON.stringify(result.structuredContent));
|
|
573
574
|
return { ok: true, text, isError: result.isError === true };
|
|
574
575
|
}
|
|
575
|
-
function exchange(spec, values, request, options) {
|
|
576
|
+
async function exchange(spec, values, request, options) {
|
|
577
|
+
// The server's fence may still be on its way (toolServerFor): an answer that isn't used is never an unhandled failure.
|
|
578
|
+
const served = Promise.resolve(options.server);
|
|
579
|
+
served.catch(() => undefined);
|
|
576
580
|
const missing = missingSecrets(spec, values);
|
|
577
581
|
if (missing.length > 0)
|
|
578
|
-
return
|
|
582
|
+
return { ok: false, problem: `Set ${missing.join(", ")} first.` };
|
|
579
583
|
const timeoutMs = options.timeoutMs ?? 60_000;
|
|
580
584
|
if (spec.transport === "http")
|
|
581
585
|
return exchangeHttp(spec, values, timeoutMs, request);
|
|
582
586
|
// A local server starts only in the server fence its caller made (toolServerFor), never bare.
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
587
|
+
const server = await served;
|
|
588
|
+
if ("problem" in server)
|
|
589
|
+
return { ok: false, problem: server.problem };
|
|
590
|
+
return exchangeStdio(spec, values, timeoutMs, options.env ?? process.env, options.omitEnv ?? [], request, server.fence);
|
|
586
591
|
}
|
|
587
592
|
function exchangeStdio(spec, values, timeoutMs, base, omit, request, fence) {
|
|
588
593
|
return new Promise(resolve => {
|
|
@@ -1137,7 +1142,7 @@ export function splitCommandLine(line) {
|
|
|
1137
1142
|
* byte a build wrote can load into a process that holds the tool's secrets. Required: where this machine can't confine
|
|
1138
1143
|
* it, it doesn't start unless an instance operator allowed unconfined agents.
|
|
1139
1144
|
*/
|
|
1140
|
-
export function toolServerFor(store, repo, options = {}) {
|
|
1145
|
+
export async function toolServerFor(store, repo, options = {}) {
|
|
1141
1146
|
const databaseFile = store.databaseFile();
|
|
1142
1147
|
if (databaseFile === null || databaseFile === "" || databaseFile === ":memory:")
|
|
1143
1148
|
return { fence: null };
|
|
@@ -1149,7 +1154,18 @@ export function toolServerFor(store, repo, options = {}) {
|
|
|
1149
1154
|
const poolRoots = [join(dirname(databaseFile), "worktrees"), ...store.listWorktrees().map(record => poolRootOf(record.path, record.repo))];
|
|
1150
1155
|
const cache = buildCacheFolder(repo, home);
|
|
1151
1156
|
const untrusted = existsSync(cache) ? [realpathSync(cache)] : [];
|
|
1152
|
-
|
|
1157
|
+
// The storage check, awaited off this thread (protected-storage.ts): the console's Test button never waits on it.
|
|
1158
|
+
let storage;
|
|
1159
|
+
try {
|
|
1160
|
+
storage = await prepareProtectedStorage(home);
|
|
1161
|
+
}
|
|
1162
|
+
catch (error) {
|
|
1163
|
+
const refused = storageRefusalOf(error);
|
|
1164
|
+
if (refused === null)
|
|
1165
|
+
throw error;
|
|
1166
|
+
return { problem: refused.message };
|
|
1167
|
+
}
|
|
1168
|
+
return { fence: fenceFor("tool-server", { databaseFile, worktree: null, home, boundary: null, binding: null, runFolders: runFolders(null), poolRoots, storage, extra: untrusted }) };
|
|
1153
1169
|
}
|
|
1154
1170
|
/** Each project's `.mcp.json` as the console last read it off its thread (its background pass): what its pages and the
|
|
1155
1171
|
* lead offer, so neither reads a project folder on the console's thread. */
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The storage check's child process (protected-storage.ts prepareProtectedStorage): it finds the protected roots, reads
|
|
3
|
+
* Firefox's profiles.ini and walks every present root here, where a listing that waits on a macOS privacy prompt holds
|
|
4
|
+
* up only this process. It writes `at\t<root>` before each walk and `done\t<answer>` at the end; the parent kills it at
|
|
5
|
+
* its limit and refuses the launch.
|
|
6
|
+
*/
|
|
7
|
+
import { protectedStorageHere } from "./protected-storage.js";
|
|
8
|
+
const request = JSON.parse(process.argv[2] ?? "{}");
|
|
9
|
+
if (typeof request.home !== "string" || typeof request.platform !== "string" || request.env === null || typeof request.env !== "object")
|
|
10
|
+
process.exit(2);
|
|
11
|
+
const env = Object.fromEntries(Object.entries(request.env).filter((one) => typeof one[1] === "string"));
|
|
12
|
+
const answer = protectedStorageHere(request.home, env, request.platform, () => { }, undefined, root => { process.stdout.write(`at\t${JSON.stringify(root)}\n`); });
|
|
13
|
+
process.stdout.write(`done\t${JSON.stringify(answer)}\n`);
|
|
@@ -21,47 +21,78 @@ export declare const PROTECTED_WALK: {
|
|
|
21
21
|
};
|
|
22
22
|
/** The roots by name, under the (real) home folder and the overrides the plane's environment names. */
|
|
23
23
|
export declare function protectedStorageNames(home?: string, env?: Readonly<Record<string, string | undefined>>, platform?: NodeJS.Platform): string[];
|
|
24
|
+
/** What one launch keeps out: every root by name (`names`), and every protected path it denies (`denies`). */
|
|
25
|
+
export type ProtectedStorage = {
|
|
26
|
+
names: string[];
|
|
27
|
+
denies: string[];
|
|
28
|
+
};
|
|
24
29
|
/**
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
30
|
+
* The storage check, run right here: every root by name and by real path, every link inside a present root that leads
|
|
31
|
+
* outward (where it leads, by real path and as spelled), and the overrides. `unfinished` names each present root whose
|
|
32
|
+
* walk met an error other than "not there" or "not allowed": its links aren't all known. A link macOS makes in a
|
|
33
|
+
* sandboxed app's container to the same place under the home folder (its Desktop, Downloads, Fonts…) is the system's
|
|
34
|
+
* own mirror of the person's folders, not the app's data, and isn't followed (systemMirror).
|
|
29
35
|
*
|
|
30
|
-
* On a Mac
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
* (`containers`, containersListable) shows they can be listed without waiting. A look that fails any other way refuses
|
|
34
|
-
* the launch (it throws). When macOS is waiting on the person, the containers stay denied by name and real path, and
|
|
35
|
-
* the outward links the last complete walk found (kept in the plane's own state folder, linkCacheFile) stay denied too;
|
|
36
|
-
* with none kept, only the roots are denied, and that is said once.
|
|
36
|
+
* On a Mac a listing (or an open) inside another app's data can wait until a person answers a privacy prompt, so there
|
|
37
|
+
* this runs only in the check's own child process (prepareProtectedStorage), never on a thread that serves anything.
|
|
38
|
+
* `at` is told each root before its walk starts, so a check that runs out of time can name the app it was waiting on.
|
|
37
39
|
*/
|
|
38
|
-
export declare function
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
|
|
43
|
-
|
|
40
|
+
export declare function protectedStorageHere(home?: string, env?: Readonly<Record<string, string | undefined>>, platform?: NodeJS.Platform, say?: (line: string) => void, list?: (path: string) => import("node:fs").Dirent[], at?: (root: string) => void): ProtectedStorage & {
|
|
41
|
+
unfinished: string[];
|
|
42
|
+
};
|
|
43
|
+
/** Every protected path, checked right here (protectedStorageHere), for a caller that has no prepared check. */
|
|
44
|
+
export declare function protectedStorageDenies(home?: string, env?: Readonly<Record<string, string | undefined>>, platform?: NodeJS.Platform, say?: (line: string) => void, list?: (path: string) => import("node:fs").Dirent[]): string[];
|
|
45
|
+
/** How long the storage check may take before the launch is refused (a slow Mac finishes well inside it). */
|
|
46
|
+
export declare const STORAGE_LOOK_MS = 10000;
|
|
47
|
+
/** What the check asked of its child, and how the child's run ended. */
|
|
48
|
+
export type StorageLookRequest = {
|
|
49
|
+
home: string;
|
|
50
|
+
env: Record<string, string>;
|
|
51
|
+
platform: NodeJS.Platform;
|
|
52
|
+
};
|
|
53
|
+
export type StorageLookResult = {
|
|
54
|
+
kind: "done";
|
|
55
|
+
storage: ProtectedStorage;
|
|
56
|
+
unfinished: string[];
|
|
57
|
+
} | {
|
|
58
|
+
kind: "timed-out";
|
|
59
|
+
at: string | null;
|
|
60
|
+
} | {
|
|
61
|
+
kind: "failed";
|
|
62
|
+
detail: string;
|
|
63
|
+
};
|
|
64
|
+
export type StorageLook = (request: StorageLookRequest) => Promise<StorageLookResult>;
|
|
65
|
+
/** Why a launch didn't start: the storage check couldn't finish. Its words survive every catch (storageRefusalOf). */
|
|
66
|
+
export declare class ProtectedStorageRefusal extends Error {
|
|
67
|
+
readonly apps: readonly string[];
|
|
68
|
+
readonly why: "timed-out" | "unfinished" | "failed";
|
|
69
|
+
readonly code: "protected-storage";
|
|
70
|
+
constructor(apps: readonly string[], why: "timed-out" | "unfinished" | "failed", message: string);
|
|
71
|
+
}
|
|
72
|
+
/** The storage refusal inside a caught error, when it is one. */
|
|
73
|
+
export declare function storageRefusalOf(error: unknown): ProtectedStorageRefusal | null;
|
|
74
|
+
/** Which program macOS must allow: the one this plane runs as. A launchd service is its program itself; a plane started
|
|
75
|
+
* from a terminal asks as that terminal app. */
|
|
76
|
+
export declare function storageAccessHolder(env?: Readonly<Record<string, string | undefined>>, execPath?: string, versions?: NodeJS.ProcessVersions): string;
|
|
77
|
+
/** Why nothing was launched, and what the person does about it. Never says macOS is asking: that isn't known. */
|
|
78
|
+
export declare function storageRefusalWords(apps: readonly string[], why: ProtectedStorageRefusal["why"], holder: string): string;
|
|
44
79
|
/**
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
*
|
|
80
|
+
* The storage check for one launch, awaited: what it denies, from a walk that finished just now. On a Mac the whole check
|
|
81
|
+
* (finding the roots, reading profiles.ini, every walk) runs in a child process, so a listing that waits on a privacy
|
|
82
|
+
* prompt holds up only that child; the thread that asked keeps serving. A check that doesn't finish within
|
|
83
|
+
* STORAGE_LOOK_MS, fails, or leaves a present root's walk unfinished refuses the launch (ProtectedStorageRefusal): no
|
|
84
|
+
* earlier walk stands in for it, since a link can move inside a root at any time. Checks asked for at once share one child.
|
|
50
85
|
*/
|
|
51
|
-
export declare function
|
|
52
|
-
/**
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
|
|
64
|
-
export declare function readLinkCache(file: string, home: string): string[] | null;
|
|
65
|
-
/** Keep a complete walk's links: written aside (owner-only) and renamed into place, only into a state folder that is
|
|
66
|
-
* already there. A failed write keeps whatever was kept before. */
|
|
67
|
-
export declare function writeLinkCache(file: string, home: string, targets: readonly string[]): void;
|
|
86
|
+
export declare function prepareProtectedStorage(home?: string, env?: Readonly<Record<string, string | undefined>>, platform?: NodeJS.Platform, look?: StorageLook, holder?: string): Promise<ProtectedStorage>;
|
|
87
|
+
/** Where the check's child script is: beside this module once built, else the built copy (a run from source). */
|
|
88
|
+
export declare function storageLookScript(): string;
|
|
89
|
+
/** A finished child's lines as the check's answer: `at\t<root>` before each walk, `done\t<answer>` once at the end. */
|
|
90
|
+
export declare function readLook(ran: SpawnedLook): StorageLookResult;
|
|
91
|
+
/** How a child ran: everything it wrote, and whether it finished, ran out of time (killed) or failed some other way. */
|
|
92
|
+
export type SpawnedLook = {
|
|
93
|
+
stdout: string;
|
|
94
|
+
outcome: "done" | "timed-out" | "failed";
|
|
95
|
+
detail: string;
|
|
96
|
+
};
|
|
97
|
+
/** Run a child without waiting on this thread: its output, bounded, and how it ended. Killed at `limitMs`. */
|
|
98
|
+
export declare function spawnLook(command: string, args: readonly string[], limitMs: number): Promise<SpawnedLook>;
|