toolroll 0.9.93 → 0.9.95
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 +79 -0
- package/dist/activity-line.d.ts +7 -4
- package/dist/activity-line.js +9 -7
- package/dist/agent-fence.d.ts +10 -0
- package/dist/agent-fence.js +6 -3
- package/dist/approval-authority.d.ts +7 -1
- package/dist/approval-authority.js +11 -2
- package/dist/approval-password.d.ts +31 -0
- package/dist/approval-password.js +26 -0
- package/dist/assignment-status.d.ts +1 -1
- package/dist/assignment-ui.js +3 -1
- package/dist/assignment.js +5 -0
- package/dist/attest.d.ts +3 -0
- package/dist/attest.js +10 -0
- package/dist/boot-identity.d.ts +2 -1
- package/dist/boot-identity.js +6 -4
- package/dist/bounded-spawn.d.ts +57 -0
- package/dist/bounded-spawn.js +220 -0
- package/dist/browser/terminal.js +42 -42
- package/dist/browser/workspace.css +1 -1
- package/dist/browser/workspace.js +32 -32
- package/dist/browser-crew.js +2 -0
- package/dist/browser-shell.d.ts +1 -1
- package/dist/browser-shell.js +2 -2
- package/dist/browser-workspace.d.ts +50 -2
- package/dist/browser-workspace.js +3 -3
- package/dist/build-review.js +2 -0
- package/dist/builder-restart.d.ts +21 -0
- package/dist/builder-restart.js +50 -0
- package/dist/builder.d.ts +11 -2
- package/dist/builder.js +234 -101
- 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 +26 -0
- package/dist/card-render.js +223 -0
- package/dist/card-sources.d.ts +68 -0
- package/dist/card-sources.js +234 -0
- package/dist/chat-acceptance.js +1 -1
- package/dist/chat-actions.d.ts +106 -9
- package/dist/chat-actions.js +473 -46
- 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 +37 -14
- package/dist/chat-controls.d.ts +4 -0
- package/dist/chat-controls.js +4 -0
- package/dist/chat-decide.d.ts +10 -16
- package/dist/chat-decide.js +79 -62
- 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 +4 -4
- 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/chat-voice.d.ts +1 -1
- package/dist/chat-voice.js +2 -2
- package/dist/check-facts.d.ts +3 -1
- package/dist/check-facts.js +57 -11
- package/dist/check-failure.d.ts +24 -3
- package/dist/check-failure.js +89 -13
- package/dist/check-levels-ui.d.ts +4 -0
- package/dist/check-levels-ui.js +10 -1
- package/dist/check-load.d.ts +85 -0
- package/dist/check-load.js +147 -0
- package/dist/check-only-standing.d.ts +36 -0
- package/dist/check-only-standing.js +39 -0
- package/dist/check-only.d.ts +15 -0
- package/dist/check-only.js +99 -0
- package/dist/check-repair.d.ts +47 -0
- package/dist/check-repair.js +240 -0
- package/dist/check-report.d.ts +2 -0
- package/dist/check-report.js +1 -1
- package/dist/check-stamp.d.ts +46 -0
- package/dist/check-stamp.js +93 -0
- package/dist/checkout-cleanup.d.ts +36 -5
- package/dist/checkout-cleanup.js +166 -14
- package/dist/claim.d.ts +6 -0
- package/dist/claim.js +13 -2
- package/dist/cli-help.d.ts +4 -1
- package/dist/cli-help.js +49 -30
- package/dist/cli.js +15 -1
- package/dist/code-extract.d.ts +44 -0
- package/dist/code-extract.js +88 -0
- package/dist/code-map-acts.d.ts +24 -0
- package/dist/code-map-acts.js +53 -0
- package/dist/code-map-admission.d.ts +52 -0
- package/dist/code-map-admission.js +295 -0
- package/dist/code-map-build.d.ts +63 -0
- package/dist/code-map-build.js +415 -0
- package/dist/code-map-cli.d.ts +153 -0
- package/dist/code-map-cli.js +103 -0
- package/dist/code-map-main.d.ts +1 -0
- package/dist/code-map-main.js +48 -0
- package/dist/code-map-read.d.ts +106 -0
- package/dist/code-map-read.js +171 -0
- package/dist/code-map-report.d.ts +37 -0
- package/dist/code-map-report.js +95 -0
- package/dist/code-map-shape.d.ts +172 -0
- package/dist/code-map-shape.js +327 -0
- package/dist/code-map-store.d.ts +136 -0
- package/dist/code-map-store.js +233 -0
- package/dist/coding-provider.d.ts +3 -1
- package/dist/coding-provider.js +12 -7
- package/dist/coding-update.js +3 -2
- package/dist/coding-workspace.d.ts +1 -1
- package/dist/coding-workspace.js +8 -8
- package/dist/console-chrome.js +2 -2
- package/dist/containment.d.ts +5 -0
- package/dist/containment.js +14 -1
- package/dist/contracts/chat-actions.d.ts +92 -0
- package/dist/contracts/chat-actions.js +20 -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/cli.d.ts +52 -0
- package/dist/contracts/cli.js +4 -0
- package/dist/contracts/console-api.d.ts +12 -3
- package/dist/contracts/console-api.js +12 -3
- 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/gateway-tools.d.ts +17 -0
- package/dist/contracts/gateway-tools.js +3 -1
- package/dist/contracts/lead-tools.d.ts +234 -0
- package/dist/contracts/lead-tools.js +25 -1
- package/dist/contracts/project-knowledge.d.ts +38 -5
- package/dist/contracts/project-knowledge.js +11 -5
- package/dist/contracts/project-memory.d.ts +3 -1
- package/dist/contracts/project-memory.js +3 -2
- package/dist/contracts/storage.d.ts +14 -0
- package/dist/contracts/storage.js +3 -1
- package/dist/contracts/store-json.d.ts +18 -0
- package/dist/contracts/youiyoux-request.d.ts +1 -1
- package/dist/contracts/youiyoux-request.js +1 -1
- package/dist/desktop-access.js +6 -2
- package/dist/discord-chat.js +14 -0
- package/dist/dispatch.d.ts +1 -1
- package/dist/dispatch.js +25 -16
- package/dist/dispose.d.ts +19 -0
- package/dist/dispose.js +55 -9
- package/dist/easy-start.js +2 -3
- package/dist/eval-oracle.js +4 -1
- package/dist/evals.js +2 -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/fast-start.d.ts +136 -0
- package/dist/fast-start.js +431 -0
- package/dist/fast-terms.d.ts +9 -0
- package/dist/fast-terms.js +23 -0
- package/dist/fenced-check-coverage.d.ts +62 -0
- package/dist/fenced-check-coverage.js +54 -0
- package/dist/findings.d.ts +224 -0
- package/dist/findings.js +449 -0
- package/dist/first-run.js +1 -1
- package/dist/flaky-ci.d.ts +31 -0
- package/dist/flaky-ci.js +149 -0
- package/dist/flaky-cli.d.ts +60 -0
- package/dist/flaky-cli.js +60 -0
- package/dist/flaky.d.ts +75 -9
- package/dist/flaky.js +255 -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-card-task.js +3 -0
- 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.d.ts +1 -1
- package/dist/flow-triggers.js +2 -2
- 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/github-import.d.ts +62 -0
- package/dist/github-import.js +146 -0
- package/dist/guides.js +15 -10
- package/dist/handover-note.d.ts +33 -0
- package/dist/handover-note.js +106 -0
- package/dist/invoke.d.ts +25 -2
- package/dist/invoke.js +157 -58
- package/dist/job-object-helper.ps1 +10 -3
- package/dist/keymap.d.ts +41 -0
- package/dist/keymap.js +51 -0
- package/dist/knowledge-cli.js +1 -1
- package/dist/knowledge-ui.d.ts +21 -4
- package/dist/knowledge-ui.js +75 -7
- package/dist/laptop-background.d.ts +16 -0
- package/dist/laptop-background.js +108 -2
- package/dist/lead-cli.js +26 -24
- package/dist/lead-context.js +1 -1
- package/dist/lead-contract.d.ts +1 -1
- package/dist/lead-contract.js +3 -2
- package/dist/lead-doors.d.ts +4 -0
- package/dist/lead-doors.js +2 -2
- package/dist/lead-progress.js +5 -0
- package/dist/lead-status.d.ts +2 -0
- package/dist/lead-status.js +6 -2
- package/dist/lead-tools.js +162 -34
- package/dist/lead.js +2 -2
- package/dist/lesson-notes.d.ts +81 -0
- package/dist/lesson-notes.js +336 -0
- package/dist/limits-ui.js +1 -1
- package/dist/local-owner.d.ts +1 -1
- package/dist/local-owner.js +16 -0
- package/dist/machine-check.d.ts +16 -0
- package/dist/machine-check.js +26 -0
- package/dist/machine-identity.d.ts +75 -0
- package/dist/machine-identity.js +170 -0
- package/dist/mcp-core.js +11 -1
- package/dist/memory-cli.d.ts +300 -1
- package/dist/memory-cli.js +62 -9
- package/dist/memory-pass.d.ts +16 -0
- package/dist/memory-pass.js +67 -3
- package/dist/memory-tidy.d.ts +181 -0
- package/dist/memory-tidy.js +523 -0
- package/dist/memory-use.d.ts +35 -0
- package/dist/memory-use.js +109 -0
- package/dist/merge-checklist.d.ts +55 -0
- package/dist/merge-checklist.js +182 -0
- package/dist/modes.d.ts +6 -6
- package/dist/modes.js +3 -1
- package/dist/needs-you.d.ts +31 -9
- package/dist/needs-you.js +110 -41
- package/dist/nightly-github.d.ts +2 -0
- package/dist/nightly-github.js +4 -4
- package/dist/operate-remote-arguments.js +7 -1
- package/dist/operate-remote.js +3 -1
- package/dist/operate.d.ts +6 -1
- package/dist/operate.js +565 -64
- package/dist/phase-routing.js +2 -2
- package/dist/plain-schema.d.ts +23 -0
- package/dist/plain-schema.js +94 -0
- package/dist/plain-words.d.ts +20 -0
- package/dist/plain-words.js +66 -0
- 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 +4 -2
- package/dist/process-liveness.d.ts +2 -0
- package/dist/process-liveness.js +61 -17
- package/dist/project-delete-ui.d.ts +19 -2
- package/dist/project-delete-ui.js +29 -1
- package/dist/project-delete.js +14 -1
- package/dist/project-knowledge.d.ts +18 -11
- package/dist/project-knowledge.js +39 -9
- package/dist/project-learning.d.ts +2 -1
- package/dist/project-learning.js +15 -45
- package/dist/project-memory.d.ts +5 -0
- package/dist/project-memory.js +22 -2
- package/dist/project-tools.d.ts +4 -4
- package/dist/project-tools.js +23 -7
- package/dist/proof.js +30 -5
- 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-auth.js +1 -1
- package/dist/provider-capture.d.ts +34 -0
- package/dist/provider-capture.js +53 -0
- package/dist/publish.js +9 -1
- package/dist/pull-request-flow.js +5 -0
- package/dist/push.d.ts +18 -2
- package/dist/push.js +40 -16
- package/dist/release-adapters.d.ts +9 -0
- package/dist/release-adapters.js +76 -0
- package/dist/release-auto.js +13 -13
- package/dist/release-card.d.ts +1 -2
- package/dist/release-card.js +11 -0
- package/dist/release-carry.d.ts +7 -2
- package/dist/release-carry.js +49 -10
- package/dist/release-cli.d.ts +4 -0
- package/dist/release-cli.js +29 -22
- package/dist/release-coverage.js +1 -1
- package/dist/release-next.d.ts +48 -0
- package/dist/release-next.js +161 -0
- package/dist/release.d.ts +20 -1
- package/dist/release.js +85 -9
- package/dist/remote-destination.d.ts +36 -0
- package/dist/remote-destination.js +217 -0
- package/dist/remote-main.d.ts +48 -0
- package/dist/remote-main.js +84 -5
- package/dist/repository-context.d.ts +3 -2
- package/dist/repository-context.js +112 -70
- package/dist/restart-certification.d.ts +1 -0
- package/dist/restart-certification.js +8 -6
- package/dist/result-acts.d.ts +27 -19
- package/dist/result-acts.js +36 -25
- package/dist/result-follow-ups.d.ts +2 -2
- package/dist/result-follow-ups.js +18 -4
- package/dist/result-review.d.ts +1 -1
- package/dist/route-change-check.d.ts +4 -0
- package/dist/route-change-check.js +13 -0
- package/dist/route-change.d.ts +22 -0
- package/dist/route-change.js +89 -0
- package/dist/route-hooks.js +3 -2
- package/dist/route-results.d.ts +6 -1
- package/dist/route-results.js +14 -5
- package/dist/run-closeout.d.ts +1 -1
- package/dist/run-closeout.js +7 -5
- package/dist/runner-process.js +3 -2
- package/dist/runner.js +2 -1
- package/dist/scope.d.ts +28 -4
- package/dist/scope.js +92 -28
- package/dist/scout.d.ts +1 -1
- package/dist/scout.js +2 -1
- package/dist/serve.d.ts +1 -1
- package/dist/serve.js +26 -18
- package/dist/server/chat.js +16 -14
- package/dist/server/chrome.d.ts +1 -1
- package/dist/server/chrome.js +26 -35
- package/dist/server/console.css +73 -0
- package/dist/server/guards.js +3 -0
- package/dist/server/home.d.ts +6 -0
- package/dist/server/home.js +21 -13
- package/dist/server/http.js +1 -1
- package/dist/server/kit.js +1 -1
- package/dist/server/merge-ready-view.d.ts +10 -0
- package/dist/server/merge-ready-view.js +30 -0
- package/dist/server/pages-assets.d.ts +1 -0
- package/dist/server/pages-assets.js +8 -5
- package/dist/server/pages.js +103 -82
- package/dist/server/render-chat.js +16 -3
- package/dist/server/render-code-map.d.ts +30 -0
- package/dist/server/render-code-map.js +137 -0
- package/dist/server/render-flaky.d.ts +20 -0
- package/dist/server/render-flaky.js +59 -0
- package/dist/server/render-follow-through.d.ts +11 -0
- package/dist/server/render-follow-through.js +68 -0
- package/dist/server/render-history.js +1 -1
- package/dist/server/render-new-task.d.ts +26 -1
- package/dist/server/render-new-task.js +30 -5
- package/dist/server/render-pages.d.ts +1 -175
- package/dist/server/render-pages.js +38 -313
- package/dist/server/render-projects.d.ts +2 -1
- package/dist/server/render-projects.js +9 -7
- package/dist/server/render-release.d.ts +2 -0
- package/dist/server/render-release.js +3 -3
- package/dist/server/render-results.d.ts +2 -0
- package/dist/server/render-results.js +68 -68
- package/dist/server/render-tasks.d.ts +16 -2
- package/dist/server/render-tasks.js +177 -141
- package/dist/server/retired-routes.d.ts +17 -0
- package/dist/server/retired-routes.js +53 -0
- package/dist/server/route-table.d.ts +3 -0
- package/dist/server/route-table.js +48 -12
- package/dist/server/settings.js +166 -34
- package/dist/server/task-views.js +66 -26
- package/dist/server/tasks.d.ts +2 -6
- package/dist/server/tasks.js +250 -321
- package/dist/server/welcome.js +1 -1
- package/dist/settings-groups-ui.d.ts +1 -0
- package/dist/settings-groups-ui.js +4 -2
- package/dist/settings-kit.js +3 -2
- package/dist/settings-proofs.js +3 -1
- package/dist/slack-chat.js +14 -1
- package/dist/steer-mailbox.d.ts +8 -1
- package/dist/steer-mailbox.js +164 -6
- package/dist/stop-proof.js +6 -4
- package/dist/storage-sweep-process.js +1 -1
- package/dist/storage-sweep.d.ts +5 -3
- package/dist/storage-sweep.js +30 -9
- package/dist/storage-ui.js +28 -17
- package/dist/storage.d.ts +27 -2
- package/dist/storage.js +39 -2
- package/dist/store.d.ts +89 -7
- package/dist/store.js +386 -114
- package/dist/surface.js +67 -6
- package/dist/sweep-quarantine.d.ts +1 -0
- package/dist/sweep-quarantine.js +6 -4
- package/dist/tamper-scan.d.ts +4 -0
- package/dist/tamper-scan.js +90 -0
- package/dist/task-aliases.d.ts +5 -0
- package/dist/task-aliases.js +9 -0
- package/dist/task-control.d.ts +2 -1
- package/dist/task-control.js +4 -1
- package/dist/task-outcome-cli.d.ts +2 -0
- package/dist/task-outcome-cli.js +17 -17
- package/dist/task-sizing.d.ts +5 -0
- package/dist/task-sizing.js +2 -0
- package/dist/task-source.d.ts +7 -0
- package/dist/task-source.js +14 -0
- package/dist/task-status.d.ts +9 -0
- package/dist/task-status.js +45 -49
- package/dist/teardown-git.d.ts +18 -0
- package/dist/teardown-git.js +105 -21
- package/dist/telegram-lead.js +23 -6
- package/dist/telegram-progress.js +5 -3
- package/dist/telegram-status.js +6 -4
- package/dist/telegram.js +12 -1
- package/dist/test-infra.d.ts +8 -0
- package/dist/test-infra.js +18 -0
- package/dist/tidy.js +1 -1
- package/dist/toolroll-update.js +19 -5
- package/dist/tui-contract.d.ts +24 -0
- package/dist/tui-source.js +67 -8
- package/dist/tui.js +51 -51
- package/dist/vanished-retry.d.ts +30 -0
- package/dist/vanished-retry.js +174 -0
- package/dist/work-index.d.ts +2 -0
- package/dist/work-index.js +95 -66
- package/dist/work-summary.d.ts +1 -1
- package/dist/work-summary.js +7 -2
- package/dist/workspace-ui.d.ts +7 -3
- package/dist/workspace-ui.js +38 -23
- package/dist/worktree.d.ts +12 -3
- package/dist/worktree.js +91 -14
- package/package.json +2 -1
- package/dist/server/render-next.d.ts +0 -63
- package/dist/server/render-next.js +0 -109
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* "Last included in a run" (docs/plans/learning-loops.md): one `memory_use` row per lesson, reference and decision in a
|
|
3
|
+
* run's frozen context, written in the transaction that freezes it. The only writer of `memory_use`; release-auto's
|
|
4
|
+
* learning scan (eval-hooks.ts learningWriteProblem) needs a person for any other. A policy path (release-auto.ts
|
|
5
|
+
* EVAL_POLICY).
|
|
6
|
+
*
|
|
7
|
+
* Usage, never benefit: nothing here says a run did better for having an item, and nothing reads it for authority. Old
|
|
8
|
+
* snapshots are backfilled from their own sha-verified bytes and nothing is inferred: a knowledge snapshot from before
|
|
9
|
+
* `capturedAt` has no time and no version, so its rows say so. Lead chat contexts aren't snapshotted and aren't counted.
|
|
10
|
+
*/
|
|
11
|
+
import { createHash } from "node:crypto";
|
|
12
|
+
import { readKnowledgeSelection } from "./contracts/project-knowledge.js";
|
|
13
|
+
const sha = (text) => createHash("sha256").update(text).digest("hex");
|
|
14
|
+
/** A run's role as a phase of the work. */
|
|
15
|
+
export const phaseOfRole = (role) => role === "planner" ? "plan" : role === "reviewer" ? "review" : "build";
|
|
16
|
+
function insertUse(store, row) {
|
|
17
|
+
store.handle.prepare(`INSERT INTO memory_use (run, repo, kind, item, version, phase, included_at) VALUES (?, ?, ?, ?, ?, ?, ?) ON CONFLICT (run, kind, item) DO NOTHING`)
|
|
18
|
+
.run(row.run, row.repo, row.kind, row.item, row.version, row.phase, row.at);
|
|
19
|
+
}
|
|
20
|
+
/** Every reference and decision in a run's frozen knowledge. Called in the transaction that freezes it; advisory, so a
|
|
21
|
+
* failure leaves the run's context exactly as it was. */
|
|
22
|
+
export function recordKnowledgeUse(store, input) {
|
|
23
|
+
const { selection } = input, phase = phaseOfRole(input.role), at = selection.capturedAt ?? null;
|
|
24
|
+
try {
|
|
25
|
+
store.savepoint(() => {
|
|
26
|
+
for (const ref of selection.references)
|
|
27
|
+
insertUse(store, { run: input.run, repo: input.repo, kind: "reference", item: ref.id, version: selection.capturedAt === undefined ? null : selection.revision, phase, at });
|
|
28
|
+
for (const one of selection.decisions ?? [])
|
|
29
|
+
insertUse(store, { run: input.run, repo: input.repo, kind: "decision", item: String(one.id), version: one.revision ?? null, phase, at });
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
catch { /* advisory: the run's context is unchanged */ }
|
|
33
|
+
}
|
|
34
|
+
/** The lessons in a run's frozen learning payload (its last line is the record). */
|
|
35
|
+
function lessonsOf(payload) {
|
|
36
|
+
try {
|
|
37
|
+
const record = JSON.parse(payload.trim().split("\n").at(-1));
|
|
38
|
+
if (typeof record.phase !== "string" || !Array.isArray(record.lessons))
|
|
39
|
+
return null;
|
|
40
|
+
const lessons = record.lessons.flatMap((one) => { const l = one; return Number.isSafeInteger(l.id) && Number.isSafeInteger(l.version) ? [{ id: Number(l.id), version: Number(l.version) }] : []; });
|
|
41
|
+
return { phase: record.phase, lessons };
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
/** Every lesson in a run's frozen learning context. As recordKnowledgeUse. */
|
|
48
|
+
export function recordLessonUse(store, input) {
|
|
49
|
+
const read = lessonsOf(input.payload);
|
|
50
|
+
if (read === null)
|
|
51
|
+
return;
|
|
52
|
+
try {
|
|
53
|
+
store.savepoint(() => { for (const one of read.lessons)
|
|
54
|
+
insertUse(store, { run: input.run, repo: input.repo, kind: "lesson", item: String(one.id), version: one.version, phase: read.phase, at: input.at }); });
|
|
55
|
+
}
|
|
56
|
+
catch { /* advisory: the run's context is unchanged */ }
|
|
57
|
+
}
|
|
58
|
+
const CURSOR_LESSONS = "memory-use:backfill-lessons", CURSOR_KNOWLEDGE = "memory-use:backfill-knowledge";
|
|
59
|
+
/**
|
|
60
|
+
* Backfill from snapshots older than this feature, a bounded batch at a time (the watch loop's learning pass): each
|
|
61
|
+
* snapshot's sha is verified first. Lesson rows take the snapshot's own time and version; knowledge rows from a snapshot
|
|
62
|
+
* with no `capturedAt` have no version and no time. Returns how many snapshots were read.
|
|
63
|
+
*/
|
|
64
|
+
export function backfillMemoryUse(store, now, limit = 200) {
|
|
65
|
+
const lessonFrom = store.serviceCursor(CURSOR_LESSONS), knowledgeFrom = store.serviceCursor(CURSOR_KNOWLEDGE);
|
|
66
|
+
const lessons = store.handle.prepare("SELECT run, repo, payload, sha, created_at FROM learning_snapshot WHERE run > ? ORDER BY run LIMIT ?").all(lessonFrom, limit);
|
|
67
|
+
const knowledge = store.handle.prepare("SELECT k.run, k.repo, k.payload, k.sha, r.role FROM knowledge_snapshot k JOIN run r ON r.id = k.run WHERE k.run > ? ORDER BY k.run LIMIT ?").all(knowledgeFrom, limit);
|
|
68
|
+
store.transact(() => {
|
|
69
|
+
for (const row of lessons) {
|
|
70
|
+
const payload = String(row["payload"]);
|
|
71
|
+
if (sha(payload) === row["sha"])
|
|
72
|
+
recordLessonUse(store, { run: Number(row["run"]), repo: String(row["repo"]), payload, at: String(row["created_at"]) });
|
|
73
|
+
}
|
|
74
|
+
for (const row of knowledge) {
|
|
75
|
+
const payload = String(row["payload"]);
|
|
76
|
+
if (sha(payload) !== row["sha"])
|
|
77
|
+
continue;
|
|
78
|
+
let parsed;
|
|
79
|
+
try {
|
|
80
|
+
parsed = JSON.parse(payload);
|
|
81
|
+
}
|
|
82
|
+
catch {
|
|
83
|
+
continue;
|
|
84
|
+
}
|
|
85
|
+
const read = readKnowledgeSelection(parsed);
|
|
86
|
+
if (read.ok)
|
|
87
|
+
recordKnowledgeUse(store, { run: Number(row["run"]), repo: String(row["repo"]), role: String(row["role"]), selection: read.value });
|
|
88
|
+
}
|
|
89
|
+
if (lessons.length > 0)
|
|
90
|
+
store.setServiceCursor(CURSOR_LESSONS, Number(lessons.at(-1)["run"]), now);
|
|
91
|
+
if (knowledge.length > 0)
|
|
92
|
+
store.setServiceCursor(CURSOR_KNOWLEDGE, Number(knowledge.at(-1)["run"]), now);
|
|
93
|
+
});
|
|
94
|
+
return lessons.length + knowledge.length;
|
|
95
|
+
}
|
|
96
|
+
/** A project's usage, by `<kind>:<item>`: its newest run, that run's time and how many runs had it. */
|
|
97
|
+
export function memoryUseOf(store, repo) {
|
|
98
|
+
const rows = store.handle.prepare(`SELECT u.kind, u.item, u.run AS last_run, u.included_at, t.runs FROM memory_use u
|
|
99
|
+
JOIN (SELECT kind, item, MAX(run) AS last_run, COUNT(*) AS runs FROM memory_use WHERE repo = ? GROUP BY kind, item) t ON t.kind = u.kind AND t.item = u.item AND t.last_run = u.run WHERE u.repo = ?`).all(repo, repo);
|
|
100
|
+
return new Map(rows.map(row => [`${String(row["kind"])}:${String(row["item"])}`, { lastRun: Number(row["last_run"]), lastAt: row["included_at"] == null ? null : String(row["included_at"]), runs: Number(row["runs"]) }]));
|
|
101
|
+
}
|
|
102
|
+
const DAY = new Intl.DateTimeFormat("en-US", { month: "short", day: "numeric", timeZone: "UTC" });
|
|
103
|
+
/** "Last included in a run: #4410, Nov 3 · 41 runs"; "#2210 (time not recorded)" for a backfilled row; "Not included yet". */
|
|
104
|
+
export function lastIncludedWords(use) {
|
|
105
|
+
if (use === undefined)
|
|
106
|
+
return "Not included yet";
|
|
107
|
+
const runs = `${use.runs.toLocaleString("en-US")} run${use.runs === 1 ? "" : "s"}`;
|
|
108
|
+
return `Last included in a run: #${use.lastRun}${use.lastAt === null ? " (time not recorded)" : `, ${DAY.format(new Date(use.lastAt))}`} · ${runs}`;
|
|
109
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/** "Can I merge?" (docs/plans/plain-toolroll.md P1.6): one checklist per task, read from the records the task page,
|
|
2
|
+
* the result page and the pull request row already read, with nothing recomputed and nothing checked live. Each row
|
|
3
|
+
* says one fact about the task's current result; a blocker carries one existing act the person can take: Run checks,
|
|
4
|
+
* Retry, or Ask the agent to fix (Send back with a note naming the blocker). Nothing here acts: it is a read, and every
|
|
5
|
+
* act it names is the person's own post through its usual door.
|
|
6
|
+
*
|
|
7
|
+
* Rows Toolroll keeps no record of (up to date with main; conflicts outside a batch check) say so, rather than guess:
|
|
8
|
+
* GitHub shows them on the pull request. */
|
|
9
|
+
import { type AssignmentAccess, type AssignmentSnapshot } from "./assignment.js";
|
|
10
|
+
import { type Store } from "./store.js";
|
|
11
|
+
export declare const CHECKLIST_KEYS: readonly ["plan", "build", "checks", "requirements", "pull-request", "pr-ci", "up-to-date", "conflicts", "comments", "release"];
|
|
12
|
+
export type ChecklistKey = (typeof CHECKLIST_KEYS)[number];
|
|
13
|
+
/** yes: done; no: in the way (with its act when one exists); waiting: under way, nothing to do yet; unknown: Toolroll
|
|
14
|
+
* keeps no record of it; skip: doesn't apply to this task. */
|
|
15
|
+
export type ChecklistMark = "yes" | "no" | "waiting" | "unknown" | "skip";
|
|
16
|
+
/** The existing act a blocker carries. `fix`: Send back, with `note` as its feedback (empty: send the saved notes). */
|
|
17
|
+
export type ChecklistAct = {
|
|
18
|
+
kind: "run-checks";
|
|
19
|
+
run: number;
|
|
20
|
+
} | {
|
|
21
|
+
kind: "retry";
|
|
22
|
+
taskId: string;
|
|
23
|
+
} | {
|
|
24
|
+
kind: "fix";
|
|
25
|
+
run: number;
|
|
26
|
+
note: string;
|
|
27
|
+
};
|
|
28
|
+
export type ChecklistRow = {
|
|
29
|
+
key: ChecklistKey;
|
|
30
|
+
label: string;
|
|
31
|
+
mark: ChecklistMark;
|
|
32
|
+
say: string;
|
|
33
|
+
act: ChecklistAct | null;
|
|
34
|
+
};
|
|
35
|
+
export type MergeChecklist = {
|
|
36
|
+
taskId: string;
|
|
37
|
+
activeTaskId: string;
|
|
38
|
+
run: number | null;
|
|
39
|
+
head: string | null;
|
|
40
|
+
/** yes: nothing Toolroll records is in the way; no: something is (the first `no` row); not-yet: only waiting rows. */
|
|
41
|
+
answer: "yes" | "no" | "not-yet" | "merged";
|
|
42
|
+
sentence: string;
|
|
43
|
+
rows: ChecklistRow[];
|
|
44
|
+
};
|
|
45
|
+
export declare const CHECKLIST_LABELS: Readonly<Record<ChecklistKey, string>>;
|
|
46
|
+
/** The one sentence for a row Toolroll keeps no record of. */
|
|
47
|
+
export declare const NOT_RECORDED = "Toolroll doesn't record this. The pull request on GitHub shows it.";
|
|
48
|
+
/** The act labels, the same words the result page uses. */
|
|
49
|
+
export declare const CHECKLIST_ACT_LABELS: Readonly<Record<ChecklistAct["kind"], string>>;
|
|
50
|
+
/** The checklist for a task's current result, as `access` may see it; null when the task isn't visible there. */
|
|
51
|
+
export declare function mergeChecklistOf(store: Store, taskId: string, now: Date, access: AssignmentAccess, root?: string): MergeChecklist | null;
|
|
52
|
+
/** The checklist from an assignment snapshot already read (the task page reads one). */
|
|
53
|
+
export declare function checklistFromAssignment(store: Store, taskId: string, assignment: AssignmentSnapshot): MergeChecklist;
|
|
54
|
+
/** The checklist as plain lines (the CLI, the lead, the TUI): the answer, then one line per row that applies. */
|
|
55
|
+
export declare function checklistLines(list: MergeChecklist): string[];
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
/** "Can I merge?" (docs/plans/plain-toolroll.md P1.6): one checklist per task, read from the records the task page,
|
|
2
|
+
* the result page and the pull request row already read, with nothing recomputed and nothing checked live. Each row
|
|
3
|
+
* says one fact about the task's current result; a blocker carries one existing act the person can take: Run checks,
|
|
4
|
+
* Retry, or Ask the agent to fix (Send back with a note naming the blocker). Nothing here acts: it is a read, and every
|
|
5
|
+
* act it names is the person's own post through its usual door.
|
|
6
|
+
*
|
|
7
|
+
* Rows Toolroll keeps no record of (up to date with main; conflicts outside a batch check) say so, rather than guess:
|
|
8
|
+
* GitHub shows them on the pull request. */
|
|
9
|
+
import { assignmentOf } from "./assignment.js";
|
|
10
|
+
import { pullRequestFollowOf, pullRequestViewOf, publishingOf } from "./pull-request-flow.js";
|
|
11
|
+
import { releaseCiHoldOf, releaseCiRunningOf } from "./release-ci-hold.js";
|
|
12
|
+
import { isRevisionFeedback } from "./result-review.js";
|
|
13
|
+
import { approvalOf, deployGateScope } from "./scope.js";
|
|
14
|
+
import { shipChecksForTask } from "./store.js";
|
|
15
|
+
import { approvedCheckStateOf } from "./task-status.js";
|
|
16
|
+
export const CHECKLIST_KEYS = ["plan", "build", "checks", "requirements", "pull-request", "pr-ci", "up-to-date", "conflicts", "comments", "release"];
|
|
17
|
+
export const CHECKLIST_LABELS = {
|
|
18
|
+
plan: "Plan approved",
|
|
19
|
+
build: "Build finished",
|
|
20
|
+
checks: "Project checks passed on this commit",
|
|
21
|
+
requirements: "Requirements met",
|
|
22
|
+
"pull-request": "Pull request open",
|
|
23
|
+
"pr-ci": "PR CI passed on this exact commit",
|
|
24
|
+
"up-to-date": "Up to date with main",
|
|
25
|
+
conflicts: "No conflicts",
|
|
26
|
+
comments: "Review comments answered",
|
|
27
|
+
release: "Release check passed",
|
|
28
|
+
};
|
|
29
|
+
/** The one sentence for a row Toolroll keeps no record of. */
|
|
30
|
+
export const NOT_RECORDED = "Toolroll doesn't record this. The pull request on GitHub shows it.";
|
|
31
|
+
/** The act labels, the same words the result page uses. */
|
|
32
|
+
export const CHECKLIST_ACT_LABELS = { "run-checks": "Run checks", retry: "Retry", fix: "Ask the agent to fix" };
|
|
33
|
+
const short = (sha) => sha == null ? "this commit" : sha.slice(0, 7);
|
|
34
|
+
/** The checklist for a task's current result, as `access` may see it; null when the task isn't visible there. */
|
|
35
|
+
export function mergeChecklistOf(store, taskId, now, access, root) {
|
|
36
|
+
const assignment = assignmentOf(store, taskId, now, access, root);
|
|
37
|
+
if (assignment === null)
|
|
38
|
+
return null;
|
|
39
|
+
return checklistFromAssignment(store, taskId, assignment);
|
|
40
|
+
}
|
|
41
|
+
/** The checklist from an assignment snapshot already read (the task page reads one). */
|
|
42
|
+
export function checklistFromAssignment(store, taskId, assignment) {
|
|
43
|
+
const active = assignment.activeTaskId;
|
|
44
|
+
const scope = store.getScope(active);
|
|
45
|
+
const task = store.getTask(active);
|
|
46
|
+
const receipt = assignment.receipt;
|
|
47
|
+
const run = receipt?.runId ?? null;
|
|
48
|
+
const head = receipt?.head ?? null;
|
|
49
|
+
const rows = [];
|
|
50
|
+
const row = (key, mark, say, act = null) => rows.push({ key, label: CHECKLIST_LABELS[key], mark, say, act });
|
|
51
|
+
// Plan approved: the approval as dispatch reads it.
|
|
52
|
+
if (scope === null)
|
|
53
|
+
row("plan", "no", "There's no plan yet.");
|
|
54
|
+
else if (approvalOf(scope).approved)
|
|
55
|
+
row("plan", "yes", scope.approvedBy == null ? "Approved." : `Approved by ${scope.approvedBy}.`);
|
|
56
|
+
else
|
|
57
|
+
row("plan", "no", "The plan waits for your approval.");
|
|
58
|
+
// Build finished: a result is recorded; a failed task retries.
|
|
59
|
+
if (task?.state === "failed")
|
|
60
|
+
row("build", "no", "The last build failed.", { kind: "retry", taskId: active });
|
|
61
|
+
else if (receipt !== null)
|
|
62
|
+
row("build", "yes", `Build #${receipt.runId} finished.`);
|
|
63
|
+
else if (assignment.state === "working" || assignment.state === "checking")
|
|
64
|
+
row("build", "waiting", "Building now.");
|
|
65
|
+
else
|
|
66
|
+
row("build", "waiting", "Nothing is built yet.");
|
|
67
|
+
// Project checks on this commit: the approved check as the Checks row reads it.
|
|
68
|
+
const check = receipt === null ? null : approvedCheckStateOf(receipt.checks);
|
|
69
|
+
if (receipt === null || check === null)
|
|
70
|
+
row("checks", "waiting", "Waits for a build.");
|
|
71
|
+
else if (check === "passed")
|
|
72
|
+
row("checks", "yes", receipt.checks.release != null && receipt.checks.status !== "passed" ? `Covered by release check #${receipt.checks.release.run}.` : `Passed on ${short(head)}.`);
|
|
73
|
+
else if (check === "failed")
|
|
74
|
+
row("checks", "no", `Failed on ${short(head)}${receipt.checks.exitCode === null ? "" : ` (exit ${receipt.checks.exitCode})`}.`, { kind: "fix", run: receipt.runId, note: `The project checks failed on ${short(head)}${receipt.checks.exitCode === null ? "" : ` (exit ${receipt.checks.exitCode})`}. Fix them so they pass.` });
|
|
75
|
+
else if (check === "running")
|
|
76
|
+
row("checks", "waiting", "Running now.");
|
|
77
|
+
else if (check === "off")
|
|
78
|
+
row("checks", "waiting", "Checks are off for this project; they run at release.");
|
|
79
|
+
else
|
|
80
|
+
row("checks", "no", check === "unreadable" ? "The check result couldn't be read." : "No check ran on this commit.", { kind: "run-checks", run: receipt.runId });
|
|
81
|
+
// Requirements: the result's own blockers, as Accept reads them.
|
|
82
|
+
const criteria = assignment.readiness?.blockers.filter(one => one.key === "criteria" || one.key === "high") ?? [];
|
|
83
|
+
if (receipt === null)
|
|
84
|
+
row("requirements", "waiting", "Waits for a build.");
|
|
85
|
+
else if (criteria.length > 0)
|
|
86
|
+
row("requirements", "no", criteria[0].message, { kind: "fix", run: receipt.runId, note: criteria.map(one => one.message).join("\n") });
|
|
87
|
+
else if (assignment.readiness?.verdict === "refuted")
|
|
88
|
+
row("requirements", "no", "The result doesn't match its plan.", { kind: "fix", run: receipt.runId, note: "The result doesn't match its plan. Fix it so it does." });
|
|
89
|
+
else
|
|
90
|
+
row("requirements", "yes", "Every requirement is met.");
|
|
91
|
+
// The pull request and its CI, as the task's pull request row reads them.
|
|
92
|
+
const view = run === null ? null : pullRequestViewOf(store, run);
|
|
93
|
+
const publishing = publishingOf(store, assignment.repo);
|
|
94
|
+
let merged = false;
|
|
95
|
+
if (view === null) {
|
|
96
|
+
if (!publishing.on) {
|
|
97
|
+
row("pull-request", "skip", "This project doesn't open pull requests.");
|
|
98
|
+
row("pr-ci", "skip", "No pull request.");
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
row("pull-request", "waiting", receipt === null ? "Opens once it's built and accepted." : "Opens when you accept it.");
|
|
102
|
+
row("pr-ci", "waiting", "Runs once the pull request opens.");
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
else {
|
|
106
|
+
merged = view.state === "merged";
|
|
107
|
+
if (merged)
|
|
108
|
+
row("pull-request", "yes", view.prNumber === null ? "Merged." : `#${view.prNumber} merged.`);
|
|
109
|
+
else if (view.state === "opening")
|
|
110
|
+
row("pull-request", "waiting", "Opening now.");
|
|
111
|
+
else if (view.state === "failed" || view.state === "closed")
|
|
112
|
+
row("pull-request", "no", view.detail);
|
|
113
|
+
else
|
|
114
|
+
row("pull-request", "yes", `#${view.prNumber} is open.`);
|
|
115
|
+
const publication = store.publicationForRun(view.runId);
|
|
116
|
+
const follow = publication === null ? null : pullRequestFollowOf(store, publication.id);
|
|
117
|
+
const ship = shipChecksForTask(store, active);
|
|
118
|
+
const exact = publication !== null && follow !== null && follow.readyHead === publication.headSha;
|
|
119
|
+
if (merged)
|
|
120
|
+
row("pr-ci", "yes", "Merged.");
|
|
121
|
+
else if (view.state === "ready" || (view.state === "waiting" && view.fullCheck !== null))
|
|
122
|
+
row("pr-ci", exact ? "yes" : "waiting", exact ? `Passed on ${short(publication.headSha)}.` : "Passed, on an earlier commit.");
|
|
123
|
+
else if (view.state === "failing") {
|
|
124
|
+
const failing = ship?.checks.filter(one => one.state === "failed").map(one => one.workflow === null ? one.name : `${one.workflow} / ${one.name}`) ?? [];
|
|
125
|
+
const said = `Failed on ${short(publication?.headSha)}${failing.length === 0 ? "" : `: ${failing.slice(0, 3).join(", ")}${failing.length > 3 ? ", …" : ""}`}.`;
|
|
126
|
+
// A revision Toolroll already filed with the failure is the fix under way: no second one from here.
|
|
127
|
+
if (view.revisionTask !== null)
|
|
128
|
+
row("pr-ci", "no", `${said} Revision ${view.revisionTask} was filed with the failure.`);
|
|
129
|
+
else
|
|
130
|
+
row("pr-ci", "no", said, receipt === null ? null : { kind: "fix", run: receipt.runId, note: `PR CI failed on ${short(publication?.headSha)}${failing.length === 0 ? "" : ` (${failing.join(", ")})`}. Fix it so it passes.` });
|
|
131
|
+
}
|
|
132
|
+
else if (view.state === "running")
|
|
133
|
+
row("pr-ci", "waiting", "Running now.");
|
|
134
|
+
else if (view.state === "opening")
|
|
135
|
+
row("pr-ci", "waiting", "Runs once the pull request opens.");
|
|
136
|
+
else
|
|
137
|
+
row("pr-ci", view.state === "failed" || view.state === "closed" ? "skip" : "waiting", view.state === "failed" || view.state === "closed" ? "No open pull request." : "No CI has reported yet.");
|
|
138
|
+
}
|
|
139
|
+
// Up to date with main and conflicts: Toolroll keeps no record of either, except a batch check's conflict.
|
|
140
|
+
row("up-to-date", merged ? "yes" : "unknown", merged ? "Merged." : NOT_RECORDED);
|
|
141
|
+
if (merged)
|
|
142
|
+
row("conflicts", "yes", "Merged.");
|
|
143
|
+
else if (receipt?.checks.batch?.state === "conflict")
|
|
144
|
+
row("conflicts", "no", "It conflicted with another result in its batch check.", { kind: "fix", run: receipt.runId, note: "It conflicts with another change. Rebase it on main and resolve the conflict." });
|
|
145
|
+
else
|
|
146
|
+
row("conflicts", "unknown", NOT_RECORDED);
|
|
147
|
+
// Review comments: the saved notes and pull request review comments not yet sent back.
|
|
148
|
+
const notes = run === null ? [] : store.liveDiffComments(run).filter(one => isRevisionFeedback(one));
|
|
149
|
+
if (run === null)
|
|
150
|
+
row("comments", "waiting", "Waits for a build.");
|
|
151
|
+
else if (notes.length === 0)
|
|
152
|
+
row("comments", "yes", "None open.");
|
|
153
|
+
else
|
|
154
|
+
row("comments", "no", `${notes.length} note${notes.length === 1 ? "" : "s"} not sent back yet.`, { kind: "fix", run, note: "" });
|
|
155
|
+
// A release: its own check, as the release card reads it.
|
|
156
|
+
if (scope !== null && deployGateScope(scope)) {
|
|
157
|
+
if (releaseCiHoldOf(store, active) !== null || releaseCiRunningOf(store, active) !== null)
|
|
158
|
+
row("release", "waiting", "GitHub's checks are still running.");
|
|
159
|
+
else if (receipt !== null && receipt.checks.level === "full" && receipt.checks.status === "passed")
|
|
160
|
+
row("release", "yes", `The full check passed on ${short(head)}.`);
|
|
161
|
+
else if (receipt !== null && receipt.checks.status === "failed")
|
|
162
|
+
row("release", "no", "The release check failed.", { kind: "fix", run: receipt.runId, note: "The release check failed. Fix it so it passes." });
|
|
163
|
+
else
|
|
164
|
+
row("release", "waiting", "The release check hasn't run on this commit yet.");
|
|
165
|
+
}
|
|
166
|
+
else
|
|
167
|
+
row("release", "skip", "Not a release.");
|
|
168
|
+
const first = rows.find(one => one.mark === "no");
|
|
169
|
+
const unknown = rows.filter(one => one.mark === "unknown").map(one => one.label.toLowerCase());
|
|
170
|
+
const answer = merged ? "merged" : first !== undefined ? "no" : rows.some(one => one.mark === "waiting") ? "not-yet" : "yes";
|
|
171
|
+
const sentence = answer === "merged" ? "Already merged."
|
|
172
|
+
: answer === "no" ? `Not yet: ${first.label.toLowerCase()} — ${first.say}`
|
|
173
|
+
: answer === "not-yet" ? `Not yet: ${rows.find(one => one.mark === "waiting").label.toLowerCase()} — ${rows.find(one => one.mark === "waiting").say}`
|
|
174
|
+
: `Yes, as far as Toolroll records.${unknown.length === 0 ? "" : ` Check ${unknown.join(" and ")} on GitHub.`}`;
|
|
175
|
+
return { taskId, activeTaskId: active, run, head, answer, sentence, rows };
|
|
176
|
+
}
|
|
177
|
+
/** The checklist as plain lines (the CLI, the lead, the TUI): the answer, then one line per row that applies. */
|
|
178
|
+
export function checklistLines(list) {
|
|
179
|
+
const MARK = { yes: "✓", no: "✗", waiting: "…", unknown: "?", skip: "–" };
|
|
180
|
+
return [`Can I merge ${list.activeTaskId}? ${list.sentence}`,
|
|
181
|
+
...list.rows.filter(one => one.mark !== "skip").map(one => ` ${MARK[one.mark]} ${one.label}: ${one.say}${one.act === null ? "" : ` [${CHECKLIST_ACT_LABELS[one.act.kind]}]`}`)];
|
|
182
|
+
}
|
package/dist/modes.d.ts
CHANGED
|
@@ -53,12 +53,10 @@ export type ModeTerms = {
|
|
|
53
53
|
* fallback; fallback chains were removed in v115). Always false on new
|
|
54
54
|
* modes; retained for digest and audit compatibility. */
|
|
55
55
|
allowPaidFallback: boolean;
|
|
56
|
-
/** Whether this mode AUTHORIZES
|
|
57
|
-
* auto-
|
|
58
|
-
*
|
|
59
|
-
*
|
|
60
|
-
* short/refuted run with named unresolved criteria still gets exactly
|
|
61
|
-
* one drafted repair — it simply waits unapproved. */
|
|
56
|
+
/** Whether this mode AUTHORIZES repairing a failed check: drafting and
|
|
57
|
+
* auto-approving each attempt (check-repair.ts). Legacy modes default FALSE,
|
|
58
|
+
* a new authority is never inherited, only freshly signed. Without it a
|
|
59
|
+
* failed check waits for a person, whose repair takes the normal approval. */
|
|
62
60
|
repairAuto: boolean;
|
|
63
61
|
/** The signed cap on repair attempts per chain (0..3), counted over the
|
|
64
62
|
* chain rooted at the original task. Meaningless (read as 0) unless
|
|
@@ -78,6 +76,8 @@ export type ModeTerms = {
|
|
|
78
76
|
absoluteExpiry: string;
|
|
79
77
|
};
|
|
80
78
|
export declare const MODE_MAX_DAYS = 7;
|
|
79
|
+
/** Repairs of one failed check's chain: what a person can start, and what the console's choice signs. The CLI signs 1 to 3. */
|
|
80
|
+
export declare const CHECK_REPAIR_LIMIT = 2;
|
|
81
81
|
/** The presets are STARTING POINTS the ceremony renders in full — the
|
|
82
82
|
* signature always covers the resolved terms, never a label. */
|
|
83
83
|
export declare function presetTerms(name: ModeName, absoluteExpiry: string): ModeTerms;
|
package/dist/modes.js
CHANGED
|
@@ -17,6 +17,8 @@ import { createHash } from "node:crypto";
|
|
|
17
17
|
import { CHAT_PROVIDERS, isChatProvider } from "./contracts/chat-tables.js";
|
|
18
18
|
import { canonicalJson } from "./canonical-json.js";
|
|
19
19
|
export const MODE_MAX_DAYS = 7;
|
|
20
|
+
/** Repairs of one failed check's chain: what a person can start, and what the console's choice signs. The CLI signs 1 to 3. */
|
|
21
|
+
export const CHECK_REPAIR_LIMIT = 2;
|
|
20
22
|
/** The presets are STARTING POINTS the ceremony renders in full — the
|
|
21
23
|
* signature always covers the resolved terms, never a label. */
|
|
22
24
|
export function presetTerms(name, absoluteExpiry) {
|
|
@@ -181,7 +183,7 @@ export function modeWords(terms) {
|
|
|
181
183
|
...(terms.allowPaidFallback
|
|
182
184
|
? ["a historical paid-fallback grant is retained on record but no longer used"] : []),
|
|
183
185
|
...(terms.repairAuto
|
|
184
|
-
? ["
|
|
186
|
+
? [`a failed check repairs itself, at most ${terms.repairMaxAttempts} ${terms.repairMaxAttempts === 1 ? "try" : "tries"} per task, inside the plan you approved and under the limits above; a repair that plan doesn't cover, and the last failure, come to you`] : []),
|
|
185
187
|
...(terms.chatApprove
|
|
186
188
|
? [`your paired ${chatNames(chatApproveChatsOf(terms))} chat may approve this repository's plans and merge its ready pull requests, two taps each, without your password; a plan that widens permissions, exceeds the per-attempt cap above or touches protected paths still opens Toolroll`] : []),
|
|
187
189
|
`everything above ends at ${terms.absoluteExpiry.slice(0, 16).replace("T", " ")} — revoking it earlier is one click, and every act it covered falls back to its own ceremony`,
|
package/dist/needs-you.d.ts
CHANGED
|
@@ -6,11 +6,14 @@
|
|
|
6
6
|
* The words never name the machine's internals; `plainSentence` keeps a
|
|
7
7
|
* recorded reason only when it is free of them. */
|
|
8
8
|
/** What a person is asked for. */
|
|
9
|
-
export type NeedKey = "approval" | "card" | "answer" | "questions" | "sign-in" | "stop-unproven" | "hold" | "choose-project" | "define-task" | "fix-request" | "choose-agent" | "fix-dependency" | "add-requirement" | "connect-builder" | "start-builder" | "vanished" | "review-result" | "rebuild" | "replan" | "earlier-version" | "other";
|
|
9
|
+
export type NeedKey = "approval" | "card" | "answer" | "questions" | "sign-in" | "stop-unproven" | "hold" | "storage" | "choose-project" | "define-task" | "fix-request" | "choose-agent" | "fix-dependency" | "add-requirement" | "connect-builder" | "start-builder" | "vanished" | "review-result" | "rebuild" | "replan" | "earlier-version" | "history" | "finding" | "other";
|
|
10
10
|
/** What the work waits for when no person can act. */
|
|
11
|
-
export type WaitKey = "build-stopping" | "build-finishing" | "build-checking" | "other-computer" | "card-reply" | "card-time" | "card-ci";
|
|
11
|
+
export type WaitKey = "build-stopping" | "build-finishing" | "build-checking" | "other-computer" | "card-reply" | "card-time" | "card-ci" | "plan-next" | "research-next" | "builders-busy" | "retry-later" | "app-update" | "other-task";
|
|
12
12
|
/** The action's code: the WorkAction that owns the act, or one of the acts a surface renders itself. */
|
|
13
|
-
|
|
13
|
+
/** The reason a storage hold carries before the check's own words (dispose.ts holdForStorage; dispatch.ts and
|
|
14
|
+
* work-index.ts read it back). */
|
|
15
|
+
export declare const STORAGE_HOLD_PREFIX = "protected-storage \u2014 ";
|
|
16
|
+
export type NeedActionCode = "approve-scope" | "approve-card" | "answer-decision" | "inspect-decisions" | "sign-in" | "recheck-stopped" | "inspect-hold" | "place-task" | "write-scope" | "select-agent" | "repair-dependency" | "repair-capability" | "start-worker" | "reconcile-run" | "open-result" | "retry-task" | "inspect-task" | "inspect-findings" | "unhold";
|
|
14
17
|
export type NeedAction = {
|
|
15
18
|
code: NeedActionCode;
|
|
16
19
|
label: string;
|
|
@@ -23,10 +26,13 @@ export declare const START_BUILDER_HREF = "/start-builder";
|
|
|
23
26
|
export declare const startBuilderHref: (taskId: string | null) => string;
|
|
24
27
|
/** What starts a builder: run on the machine where the project lives, in the project's folder. */
|
|
25
28
|
export declare const START_BUILDER_COMMAND = "toolroll up";
|
|
26
|
-
/** `build`: the run a sentence names; `provider`: the agent that signed out
|
|
29
|
+
/** `build`: the run a sentence names; `provider`: the agent that signed out; `task`: another task it names (an
|
|
30
|
+
* earlier version); `retry`: when Toolroll tries again, in words ("in 4 minutes"). */
|
|
27
31
|
export type NeedContext = {
|
|
28
32
|
build?: number | null;
|
|
29
33
|
provider?: string | null;
|
|
34
|
+
task?: string | null;
|
|
35
|
+
retry?: string | null;
|
|
30
36
|
};
|
|
31
37
|
/** `useReason`: which recorded reasons say what is needed better than the default words. */
|
|
32
38
|
type Need = {
|
|
@@ -69,9 +75,9 @@ export type ResultHoldUp = {
|
|
|
69
75
|
export declare function resultHoldUpSentence(facts: Partial<ResultHoldUp>): string;
|
|
70
76
|
export declare const NEED_ASK: Readonly<Record<NeedKey, Ask>>;
|
|
71
77
|
export declare const WAITS: Readonly<Record<WaitKey, (context: NeedContext) => string>>;
|
|
72
|
-
/** Words that name the machine's internals; no Needs you or Waiting sentence carries
|
|
73
|
-
|
|
74
|
-
export
|
|
78
|
+
/** Words that name the machine's internals (plain-words.ts, the one table); no Needs you or Waiting sentence carries
|
|
79
|
+
* them, and a recorded reason that does is replaced by the need's own words. */
|
|
80
|
+
export { BANNED_WORDS, PLAIN_WORDS, bannedWordsIn, hasInternalWords } from "./plain-words.js";
|
|
75
81
|
/** The sentence for a need: its recorded reason when the need keeps one and
|
|
76
82
|
* it reads plainly, otherwise the need's own words. */
|
|
77
83
|
export declare function needSentence(key: NeedKey, reason: string | null, context?: NeedContext): string;
|
|
@@ -89,7 +95,24 @@ export declare function processNeedOf(fact: {
|
|
|
89
95
|
wait: WaitKey;
|
|
90
96
|
build: number;
|
|
91
97
|
} | null;
|
|
92
|
-
/**
|
|
98
|
+
/** The stages a code reads as (task-status.ts TaskStage). */
|
|
99
|
+
export type CodeStage = "queued" | "planning" | "needs-you" | "waiting" | "building" | "checking" | "reviewing" | "finished" | "complete" | "failed" | "stopped";
|
|
100
|
+
/** Every dispatch and work-index code, as what it means for a person (docs/plans/plain-toolroll.md P1.2): a need with
|
|
101
|
+
* the act that resolves it, a wait (worded as what it waits for), or a plain state. A code is exactly one of these.
|
|
102
|
+
* `act` is the work-index row's own act for the code, the same act it had before this table: a need keeps its act, a
|
|
103
|
+
* wait offers none. `stopped` and `failed` keep their own act too (Resume, Retry). */
|
|
104
|
+
export type CodeReading = {
|
|
105
|
+
stage: CodeStage;
|
|
106
|
+
need?: NeedKey;
|
|
107
|
+
wait?: WaitKey;
|
|
108
|
+
act?: NeedActionCode | "inspect-stop" | "resume-run" | "unhold" | "answer-agent" | "inspect-run" | null;
|
|
109
|
+
};
|
|
110
|
+
export declare const CODE_READING: Readonly<Record<string, CodeReading>>;
|
|
111
|
+
/** A code that waits on Toolroll or another task: no person is asked. */
|
|
112
|
+
export declare const isWaitCode: (code: string) => boolean;
|
|
113
|
+
/** Notification kinds that need nothing from a person: they stay in the activity log and never ping a phone. */
|
|
114
|
+
export declare const ACTIVITY_ONLY_KINDS: ReadonlySet<string>;
|
|
115
|
+
/** Dispatch and work-index codes that wait on a person, as their need (read from CODE_READING). */
|
|
93
116
|
export declare const CODE_NEED: Readonly<Record<string, NeedKey>>;
|
|
94
117
|
/** A stopped run's recorded reason code, in words (the run record, the thread, a failed task's status). */
|
|
95
118
|
export declare const RUN_REASON_WORDS: Readonly<Record<string, string>>;
|
|
@@ -139,4 +162,3 @@ export declare function missedRequirementLine(statement: string): string;
|
|
|
139
162
|
export declare const RETRY_NOTE_LIMIT = 500;
|
|
140
163
|
/** Retry's note, prefilled with the suggestion: cut to what the field takes, at a word, so the form always posts. */
|
|
141
164
|
export declare function retryNoteOf(suggestion: string): string;
|
|
142
|
-
export {};
|