toolroll 0.9.8 → 0.9.9
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 +22 -0
- package/dist/assignment-brief.d.ts +2 -0
- package/dist/assignment-brief.js +2 -1
- package/dist/assignment-presentation.js +3 -1
- package/dist/assignment-status.d.ts +1 -1
- package/dist/assignment-ui.js +5 -0
- package/dist/assignment.d.ts +9 -0
- package/dist/assignment.js +39 -7
- package/dist/browser/workspace.css +1 -1
- package/dist/browser/workspace.js +18 -18
- package/dist/browser-crew.js +4 -0
- package/dist/browser-workspace.d.ts +40 -0
- package/dist/builder.d.ts +2 -0
- package/dist/builder.js +114 -8
- package/dist/chat-controls.d.ts +1 -1
- package/dist/chat-controls.js +1 -1
- package/dist/check-progress.js +4 -3
- package/dist/checkout-cleanup.d.ts +40 -2
- package/dist/checkout-cleanup.js +129 -9
- package/dist/desktop-update.d.ts +52 -0
- package/dist/desktop-update.js +147 -5
- package/dist/evidence.d.ts +6 -0
- package/dist/evidence.js +8 -0
- package/dist/first-run.d.ts +1 -1
- package/dist/first-run.js +7 -5
- package/dist/lead-context.d.ts +1 -1
- package/dist/lead-context.js +4 -2
- package/dist/lead-status.d.ts +10 -1
- package/dist/lead-status.js +21 -24
- package/dist/needs-you.d.ts +55 -0
- package/dist/needs-you.js +83 -0
- package/dist/operate.d.ts +2 -0
- package/dist/operate.js +112 -14
- package/dist/plane-review.js +4 -0
- package/dist/process-recovery-eligibility.d.ts +1 -0
- package/dist/project-learning.d.ts +3 -3
- package/dist/project-learning.js +28 -17
- package/dist/proof.d.ts +3 -1
- package/dist/proof.js +4 -2
- package/dist/result-completion.d.ts +4 -0
- package/dist/result-completion.js +11 -0
- package/dist/review-context.d.ts +3 -0
- package/dist/review-context.js +45 -5
- package/dist/run-closeout.d.ts +89 -0
- package/dist/run-closeout.js +302 -0
- package/dist/serve.d.ts +15 -1
- package/dist/serve.js +129 -14
- package/dist/setup-guide.d.ts +2 -2
- package/dist/shared-deps.d.ts +94 -0
- package/dist/shared-deps.js +365 -0
- package/dist/storage.js +2 -0
- package/dist/store.d.ts +36 -0
- package/dist/store.js +125 -29
- package/dist/task-status.d.ts +18 -4
- package/dist/task-status.js +35 -18
- package/dist/telegram-progress.js +2 -1
- package/dist/telegram-status.js +3 -3
- package/dist/test-temp.d.ts +19 -0
- package/dist/test-temp.js +98 -0
- package/dist/toolroll-update-ui.js +7 -2
- package/dist/toolroll-update.d.ts +21 -1
- package/dist/toolroll-update.js +135 -5
- package/dist/work-index.d.ts +11 -0
- package/dist/work-index.js +103 -16
- package/dist/work-summary.d.ts +3 -1
- package/dist/workspace-ui.js +1 -1
- package/dist/worktree.d.ts +16 -0
- package/dist/worktree.js +47 -0
- package/package.json +1 -1
package/dist/work-summary.d.ts
CHANGED
|
@@ -8,7 +8,9 @@ export type WorkTarget = {
|
|
|
8
8
|
decisionId: number | null;
|
|
9
9
|
};
|
|
10
10
|
export type WorkAction = {
|
|
11
|
-
|
|
11
|
+
/** `confirm-stopped`: an approver confirms a finished build stopped (behind the password);
|
|
12
|
+
* `sign-in`: the agent's sign-in, in Settings. */
|
|
13
|
+
code: DispatchAction | "inspect-task" | "inspect-run" | "inspect-stop" | "inspect-decisions" | "reconcile-run" | "open-pr" | "confirm-stopped" | "sign-in";
|
|
12
14
|
label: string;
|
|
13
15
|
target: WorkTarget;
|
|
14
16
|
access: "read" | "operator-control" | "proposal-only" | "operator-handoff";
|
package/dist/workspace-ui.js
CHANGED
|
@@ -291,7 +291,7 @@ const DISPATCH_ACTION_LABELS = {
|
|
|
291
291
|
"place-task": "Choose a project",
|
|
292
292
|
"write-scope": "Define the task",
|
|
293
293
|
"select-agent": "Choose an agent",
|
|
294
|
-
"approve-scope": "
|
|
294
|
+
"approve-scope": "Approve plan",
|
|
295
295
|
"answer-decision": "Answer the question",
|
|
296
296
|
unhold: "Review hold",
|
|
297
297
|
"inspect-hold": "Review hold",
|
package/dist/worktree.d.ts
CHANGED
|
@@ -76,6 +76,8 @@ export type KeptWhy = "has changes" | "has commits" | "unreadable" | "git refuse
|
|
|
76
76
|
* something is in there.
|
|
77
77
|
*/
|
|
78
78
|
export declare const MARKER = ".standing-orders-lease";
|
|
79
|
+
/** What a kept checkout drops once its run ends (only where .gitignore hides it): dependencies and build output. */
|
|
80
|
+
export declare const SLIM_NAMES: readonly string[];
|
|
79
81
|
/** Creating a worktree copies a tree; it is local work but not instant. */
|
|
80
82
|
export declare const WORKTREE_TIMEOUT_MS = 60000;
|
|
81
83
|
/**
|
|
@@ -251,6 +253,20 @@ export declare class WorktreePool {
|
|
|
251
253
|
why: KeptWhy;
|
|
252
254
|
}[];
|
|
253
255
|
}>;
|
|
256
|
+
/**
|
|
257
|
+
* Drop a let-go, idle checkout's dependencies and build output: the folders .gitignore hides that are named like
|
|
258
|
+
* them (SLIM_NAMES). Its work, tracked or untracked, is untouched. The setup stamp goes first, so the next lease
|
|
259
|
+
* runs the project's setup again and restores them. `wanted` is asked again right before anything goes; `deps`
|
|
260
|
+
* false keeps node_modules (no setup would restore it).
|
|
261
|
+
*/
|
|
262
|
+
slim(row: WorktreeRow, wanted: (row: WorktreeRow) => boolean, deps?: boolean): Promise<{
|
|
263
|
+
ok: true;
|
|
264
|
+
dropped: string[];
|
|
265
|
+
bytes: number;
|
|
266
|
+
} | {
|
|
267
|
+
ok: false;
|
|
268
|
+
message: string;
|
|
269
|
+
}>;
|
|
254
270
|
/**
|
|
255
271
|
* Throw away a let-go checkout kept for its changes, on purpose: the working copy and what is uncommitted in it
|
|
256
272
|
* go; its branch, and every commit on it, stays. Refused while anything holds it.
|
package/dist/worktree.js
CHANGED
|
@@ -30,6 +30,7 @@ import { run } from "./exec.js";
|
|
|
30
30
|
import { currentBootId, provenDeadByBootChange } from "./boot-identity.js";
|
|
31
31
|
import { HANDOFF_PREFIX, MAILBOX_SUFFIX, looksLikeProtocolFile, readMailbox } from "./evidence.js";
|
|
32
32
|
import { parseHandoff } from "./decision.js";
|
|
33
|
+
import { diskBytes } from "./storage.js";
|
|
33
34
|
/**
|
|
34
35
|
* The note a lease leaves in the checkout, naming the process holding it.
|
|
35
36
|
*
|
|
@@ -40,6 +41,8 @@ import { parseHandoff } from "./decision.js";
|
|
|
40
41
|
export const MARKER = ".standing-orders-lease";
|
|
41
42
|
/** Checkouts this process is leasing or removing right now: a lease and storage retention never overlap on one. */
|
|
42
43
|
const busy = new Map();
|
|
44
|
+
/** What a kept checkout drops once its run ends (only where .gitignore hides it): dependencies and build output. */
|
|
45
|
+
export const SLIM_NAMES = ["node_modules", "dist", "build", "out", ".next", ".nuxt", ".svelte-kit", ".turbo", ".parcel-cache", "coverage", "target"];
|
|
43
46
|
/** Creating a worktree copies a tree; it is local work but not instant. */
|
|
44
47
|
export const WORKTREE_TIMEOUT_MS = 60_000;
|
|
45
48
|
const GIT = "git";
|
|
@@ -706,6 +709,50 @@ export class WorktreePool {
|
|
|
706
709
|
}
|
|
707
710
|
return { removed, kept };
|
|
708
711
|
}
|
|
712
|
+
/**
|
|
713
|
+
* Drop a let-go, idle checkout's dependencies and build output: the folders .gitignore hides that are named like
|
|
714
|
+
* them (SLIM_NAMES). Its work, tracked or untracked, is untouched. The setup stamp goes first, so the next lease
|
|
715
|
+
* runs the project's setup again and restores them. `wanted` is asked again right before anything goes; `deps`
|
|
716
|
+
* false keeps node_modules (no setup would restore it).
|
|
717
|
+
*/
|
|
718
|
+
async slim(row, wanted, deps = true) {
|
|
719
|
+
const idle = (now) => now !== null && now.runner === null && now.releasedAt !== null && now.releasedAt === row.releasedAt && !this.inUse(row.path).held;
|
|
720
|
+
if (busy.has(row.path) || !existsSync(row.path) || !idle(this.store.getWorktree(row.path)))
|
|
721
|
+
return { ok: false, message: `${row.path} is in use` };
|
|
722
|
+
const listed = await this.runner(GIT, [...READ_ONLY, "ls-files", "--others", "--ignored", "--exclude-standard", "--directory", "-z"], { cwd: row.path, timeoutMs: WORKTREE_TIMEOUT_MS });
|
|
723
|
+
if (listed.code !== 0)
|
|
724
|
+
return { ok: false, message: `git couldn't list ${row.path}` };
|
|
725
|
+
const drop = listed.stdout.split("\0").filter(one => one.endsWith("/")).map(one => one.slice(0, -1))
|
|
726
|
+
.filter(one => { const name = one.split("/").at(-1); return SLIM_NAMES.includes(name) && (deps || name !== "node_modules"); });
|
|
727
|
+
if (drop.length === 0)
|
|
728
|
+
return { ok: true, dropped: [], bytes: 0 };
|
|
729
|
+
busy.set(row.path, "removing");
|
|
730
|
+
const note = join(row.path, MARKER);
|
|
731
|
+
let held = false;
|
|
732
|
+
try {
|
|
733
|
+
const now = this.store.getWorktree(row.path);
|
|
734
|
+
if (!idle(now) || !wanted(now))
|
|
735
|
+
return { ok: false, message: `${row.path} is in use` };
|
|
736
|
+
// Held while it slims: another process's lease sees this process in it.
|
|
737
|
+
try {
|
|
738
|
+
writeFileSync(note, `${process.pid} storage-retention slimming ${currentBootId() ?? "unknown"} ${hostname()}\n`, "utf8");
|
|
739
|
+
held = true;
|
|
740
|
+
}
|
|
741
|
+
catch {
|
|
742
|
+
return { ok: false, message: `${row.path} couldn't be held` };
|
|
743
|
+
}
|
|
744
|
+
const sizes = diskBytes(drop.map(one => join(row.path, one)));
|
|
745
|
+
this.store.forgetWorktreeSetup(row.path);
|
|
746
|
+
for (const one of drop)
|
|
747
|
+
rmSync(join(row.path, one), { recursive: true, force: true, maxRetries: 3 });
|
|
748
|
+
return { ok: true, dropped: drop, bytes: [...sizes.values()].reduce((sum, one) => sum + one, 0) };
|
|
749
|
+
}
|
|
750
|
+
finally {
|
|
751
|
+
if (held)
|
|
752
|
+
rmSync(note, { force: true });
|
|
753
|
+
busy.delete(row.path);
|
|
754
|
+
}
|
|
755
|
+
}
|
|
709
756
|
/**
|
|
710
757
|
* Throw away a let-go checkout kept for its changes, on purpose: the working copy and what is uncommitted in it
|
|
711
758
|
* go; its branch, and every commit on it, stays. Refused while anything holds it.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "toolroll",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.9",
|
|
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"
|