toolroll 0.9.74 → 0.9.75

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.
Files changed (83) hide show
  1. package/CHANGELOG.md +31 -0
  2. package/dist/assignment.d.ts +3 -0
  3. package/dist/assignment.js +27 -8
  4. package/dist/browser/workspace.js +27 -27
  5. package/dist/browser-workspace.d.ts +1 -1
  6. package/dist/chat-acceptance.d.ts +4 -1
  7. package/dist/chat-acceptance.js +13 -3
  8. package/dist/cli.js +1 -1
  9. package/dist/coding-handoff.js +4 -3
  10. package/dist/coding-ui.js +2 -2
  11. package/dist/coding-workspace.js +16 -4
  12. package/dist/contracts/console-api.d.ts +5 -1
  13. package/dist/contracts/console-api.js +10 -0
  14. package/dist/control-ui.d.ts +3 -2
  15. package/dist/control-ui.js +7 -2
  16. package/dist/demo.js +5 -3
  17. package/dist/desktop-update.d.ts +3 -0
  18. package/dist/desktop-update.js +43 -9
  19. package/dist/first-run.d.ts +8 -5
  20. package/dist/first-run.js +39 -6
  21. package/dist/flow-card-task.js +3 -2
  22. package/dist/flow-unattended.d.ts +2 -0
  23. package/dist/flow-unattended.js +12 -1
  24. package/dist/integrations.d.ts +4 -3
  25. package/dist/integrations.js +5 -6
  26. package/dist/lead-contract.d.ts +1 -1
  27. package/dist/lead-contract.js +2 -2
  28. package/dist/lead-follow.js +3 -1
  29. package/dist/openrouter-models.d.ts +5 -2
  30. package/dist/openrouter-models.js +7 -4
  31. package/dist/operate.js +2 -0
  32. package/dist/project-learning.js +44 -6
  33. package/dist/project-tools.js +19 -1
  34. package/dist/pull-request-ui.d.ts +1 -1
  35. package/dist/pull-request-ui.js +5 -1
  36. package/dist/push.d.ts +2 -0
  37. package/dist/push.js +24 -19
  38. package/dist/read-only-request.d.ts +4 -0
  39. package/dist/read-only-request.js +15 -0
  40. package/dist/repository-context.js +6 -1
  41. package/dist/result-follow-ups.js +20 -1
  42. package/dist/result-review.js +5 -1
  43. package/dist/serve.js +162 -6
  44. package/dist/server/agents-live-filed.d.ts +17 -0
  45. package/dist/server/agents-live-filed.js +97 -0
  46. package/dist/server/agents-live-room.js +4 -1
  47. package/dist/server/chat.js +31 -23
  48. package/dist/server/http.d.ts +5 -0
  49. package/dist/server/last-checks.d.ts +17 -0
  50. package/dist/server/last-checks.js +22 -0
  51. package/dist/server/pages.js +18 -4
  52. package/dist/server/people-tokens.js +7 -4
  53. package/dist/server/render-pages.d.ts +2 -1
  54. package/dist/server/render-pages.js +28 -24
  55. package/dist/server/render-results.d.ts +11 -2
  56. package/dist/server/render-results.js +54 -12
  57. package/dist/server/render-settings.js +3 -3
  58. package/dist/server/render-tasks.js +7 -4
  59. package/dist/server/route-table.js +14 -1
  60. package/dist/server/runtime.d.ts +16 -1
  61. package/dist/server/settings.js +82 -29
  62. package/dist/server/task-views.js +0 -1
  63. package/dist/server/tasks.js +11 -2
  64. package/dist/storage-ui.d.ts +2 -0
  65. package/dist/storage-ui.js +1 -1
  66. package/dist/storage.js +2 -1
  67. package/dist/store.d.ts +3 -0
  68. package/dist/store.js +33 -9
  69. package/dist/subagent-work.js +3 -0
  70. package/dist/task-status.d.ts +28 -1
  71. package/dist/task-status.js +93 -11
  72. package/dist/teardown-git.d.ts +27 -1
  73. package/dist/teardown-git.js +185 -39
  74. package/dist/telegram-progress.js +4 -4
  75. package/dist/telegram-status.js +8 -3
  76. package/dist/tool-secret-store.js +8 -0
  77. package/dist/toolroll-update-ui.d.ts +2 -0
  78. package/dist/toolroll-update-ui.js +4 -3
  79. package/dist/toolroll-update.js +10 -9
  80. package/dist/work-index.js +29 -12
  81. package/dist/workspace-ui.d.ts +5 -0
  82. package/dist/workspace-ui.js +38 -10
  83. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,36 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.9.75 — 2026-10-27
4
+
5
+ - **Opening a page only shows it.** Pages no longer run checks, tidy up or
6
+ call out as you open them. Sign-ins, integrations, update checks, storage
7
+ and Codex's tools are checked in the background, and Models, Updates,
8
+ Storage, Pull requests, Tools, Project setup and the GitHub listing show
9
+ their last answer and when it was checked, with a **Check now** button to
10
+ ask again. On a coding session, **Review for shipping** and the changes
11
+ view are buttons, so a link preview or prefetch can't run them. Reading a
12
+ checkout an agent wrote never runs that checkout's own git settings.
13
+ - **Reading an agent's checkout can't be raced into running a filter.** Git
14
+ reads the checkout through a private copy of its settings taken once, so a
15
+ filter the agent adds to its git config and `.git/info/attributes` after
16
+ that copy never runs.
17
+ - **The task card never contradicts itself.** One answer to "did the
18
+ approved check pass" across the task page, the road, the Tasks list, the
19
+ result page and chat. A check whose saved log can't be read is never
20
+ shown as passed, and a check whose command was approved again since it ran
21
+ says so: "The check command changed since this check; run checks again."
22
+ - **Lead-filed runs nest under the lead on Agents → Live.** Runs your own
23
+ lead filed sit under its tile. Once its turn has gone, they stay grouped
24
+ under a quiet "Filed by lead chat" header. The lead's full screen lists
25
+ every task it filed. Only you see what your lead filed.
26
+ - **The lead passes asks to a helper instead of answering for them.** "Ask
27
+ Maya to …" now reaches Maya even when she seems to lack a tool or the
28
+ knowledge for it; she says so herself or asks you first.
29
+ - **A helper's "can't" reaches whoever asked.** When a helper can't do
30
+ something asked at its desk, its note (or its reason) goes back to the
31
+ person or agent who asked, instead of waiting in an inbox.
32
+ - Database: schema v136 (unchanged).
33
+
3
34
  ## 0.9.74 — 2026-10-27
4
35
 
5
36
  - **Agents → Live: every agent and subagent at a glance.** A read-only grid
@@ -28,6 +28,9 @@ export type AssignmentChecks = {
28
28
  batch?: ChecksBatch | null;
29
29
  /** Checks Off: the passing full release check that contains this commit (release-coverage.ts), read now, never sealed. */
30
30
  release?: ReleaseCoverage | null;
31
+ /** Why a saved check can't be read, when it is the project's check command approved again since it ran (its files
32
+ * are intact; running checks again settles it). Presentation only, never sealed. */
33
+ cause?: "command-changed" | null;
31
34
  };
32
35
  export type AssignmentReceipt = {
33
36
  digest: string;
@@ -21,7 +21,7 @@ import { requiredCheckCommandFor, runCheckLevel } from "./check-levels.js";
21
21
  import { followUpChecksOf, withFollowUps } from "./result-follow-ups.js";
22
22
  import { buildReviewOf, findingWords } from "./review-switch.js";
23
23
  import { NEEDS, WAITS, processNeedOf, resultHoldUpSentence } from "./needs-you.js";
24
- import { assignmentStageOf, checkBackingOf, completionBlockersOf, requirementWordOf } from "./task-status.js";
24
+ import { assignmentStageOf, checkBackingOf, completionBlockersOf, receiptChecksOf, requirementWordOf } from "./task-status.js";
25
25
  import { releaseCoverageOf } from "./release-coverage.js";
26
26
  import { leadClaimOf } from "./lead-voice.js";
27
27
  /** Status-first handoff for routine reads. Fetch get_assignment only when
@@ -53,7 +53,7 @@ function olderStoreSafe(read, absent) {
53
53
  }
54
54
  }
55
55
  /** A check as the receipt digest seals it: presentation-only fields (check-levels.ts) left out. */
56
- const sealedChecks = ({ level: _level, running: _running, batch: _batch, release: _release, ...proof }) => proof;
56
+ const sealedChecks = ({ level: _level, running: _running, batch: _batch, release: _release, cause: _cause, ...proof }) => proof;
57
57
  const OWNER_ACTION = "assignment claimed";
58
58
  const CHECK_ACTION = COMPLETION_ACTION;
59
59
  const actorOf = (owner) => `${owner.kind}:${owner.id}`;
@@ -87,7 +87,7 @@ function ownerOf(store, rootId, repo) {
87
87
  // Report the recorded check outcome, never turn a model verdict into a check.
88
88
  // Follow-up checks on the same commit (Run checks) upgrade a pass and show a failure.
89
89
  export function assignmentChecksForRun(store, root, runId, now) {
90
- const own = buildChecks(store, root, runId);
90
+ const own = recordedFailureStands(store, runId, buildChecks(store, root, runId));
91
91
  const run = store.getRun(runId);
92
92
  const followUps = followUpChecksOf(store, runId, now, root);
93
93
  if (followUps.length === 0)
@@ -106,6 +106,18 @@ export function assignmentChecksForRun(store, root, runId, now) {
106
106
  ...(changed ? { status: read.status, level: read.level, exitCode: read.exitCode, logArtifactId: latest?.logArtifactId ?? own.logArtifactId,
107
107
  detail: read.status === "passed" ? `${words} passed.` : `${words} failed (exit ${read.exitCode}).` } : {}) };
108
108
  }
109
+ /** A failure the builder recorded (run_check) stands when its saved receipt can't be read now or says nothing ran:
110
+ * fail closed, every surface reads the same known failure and its exit code (task-status.ts approvedCheckOf). */
111
+ function recordedFailureStands(store, runId, own) {
112
+ if (own.status !== "unavailable" && own.status !== "not-run")
113
+ return own;
114
+ const recorded = olderStoreSafe(() => store.runCheckFor(runId), null);
115
+ if (recorded?.status !== "failed")
116
+ return own;
117
+ return { ...own, status: "failed", exitCode: recorded.exitCode,
118
+ detail: `${own.level === "quick" ? "Quick checks" : "Checks"} failed${recorded.exitCode === null ? "" : ` (exit ${recorded.exitCode})`}. ${own.detail}` };
119
+ }
120
+ const COMMAND_MISSING_OR_CHANGED = "The original approved verification command is missing or changed.";
109
121
  function buildChecks(store, root, runId) {
110
122
  const level = runCheckLevel(store, runId);
111
123
  const unavailable = (detail) => ({ status: "unavailable", exitCode: null, command: null, logArtifactId: null, detail, level });
@@ -113,8 +125,13 @@ function buildChecks(store, root, runId) {
113
125
  return unavailable("Saved checks are unavailable.");
114
126
  try {
115
127
  const gate = verificationEvidence(store, root, runId);
116
- if (!gate.ok)
117
- return unavailable(gate.problem);
128
+ if (!gate.ok) {
129
+ // The approved command changed since this check ran: nothing is missing, the check just no longer binds to it.
130
+ const run = store.getRun(runId), repo = run === null ? null : store.refById(run.taskRef)?.repo ?? null;
131
+ const live = repo === null ? null : store.liveVerifyCommand(repo);
132
+ const changed = gate.problem === COMMAND_MISSING_OR_CHANGED && live !== null && run !== null && live.approvedAt > run.startedAt;
133
+ return changed ? { ...unavailable(gate.problem), cause: "command-changed" } : unavailable(gate.problem);
134
+ }
118
135
  const receipt = gate.bytes === null ? null : JSON.parse(gate.bytes);
119
136
  if (receipt === null)
120
137
  return { ...unavailable(level === "off" ? "Checks were off for this build." : "No machine check is recorded."), status: "not-run" };
@@ -390,10 +407,12 @@ function readinessOf(store, receipt, repo, review) {
390
407
  const high = review === null || review.sentBackAs !== null || review.state !== "reviewed" ? 0 : review.high.length;
391
408
  const checkRequired = olderStoreSafe(() => requiredCheckCommandFor(store, repo, receipt.taskId, receipt.checks.level), null) !== null;
392
409
  const matrix = receipt.proof?.matrix ?? [];
393
- const backing = checkBackingOf(receipt.checks);
394
- const verdict = shownVerdictOf(receipt.proof?.verdict ?? null, { checkFailed: !report && receipt.checks.status === "failed", highFindings: high,
410
+ // The approved check as every surface reads it: a recorded pass the saved receipt can't show doesn't count.
411
+ const checks = receiptChecksOf(receipt);
412
+ const backing = checkBackingOf(checks);
413
+ const verdict = shownVerdictOf(receipt.proof?.verdict ?? null, { checkFailed: !report && checks?.status === "failed", highFindings: high,
395
414
  reviewPending: review?.state === "pending", criteriaPassed: matrix.every(row => requirementWordOf(row, null, backing) === "Met") });
396
- const blockers = completionBlockersOf({ report, checks: receipt.checks, checkRequired, matrix, verdict: receipt.proof?.verdict ?? null,
415
+ const blockers = completionBlockersOf({ report, checks, checkRequired, matrix, verdict: receipt.proof?.verdict ?? null,
397
416
  accepted: receipt.proofAcceptance !== null, high });
398
417
  return { verdict, checksOff: !report && receipt.checks.level === "off", blockers };
399
418
  }