toolroll 0.9.6 → 0.9.8

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 (102) hide show
  1. package/CHANGELOG.md +64 -1
  2. package/dist/actor.d.ts +21 -0
  3. package/dist/actor.js +48 -0
  4. package/dist/assignment-adapters.d.ts +2 -0
  5. package/dist/assignment-adapters.js +2 -0
  6. package/dist/assignment-ui.js +3 -1
  7. package/dist/assignment.d.ts +15 -0
  8. package/dist/assignment.js +80 -16
  9. package/dist/browser/workspace.css +2 -2
  10. package/dist/browser/workspace.js +28 -24
  11. package/dist/browser-workspace.d.ts +117 -2
  12. package/dist/build-review.d.ts +38 -0
  13. package/dist/build-review.js +341 -0
  14. package/dist/builder.d.ts +1 -0
  15. package/dist/builder.js +33 -13
  16. package/dist/chat-actions.js +2 -1
  17. package/dist/chat-delivery.js +2 -0
  18. package/dist/chat-quiet.js +11 -1
  19. package/dist/chat-task-actions.d.ts +13 -0
  20. package/dist/chat-task-actions.js +19 -1
  21. package/dist/check-levels-ui.d.ts +26 -0
  22. package/dist/check-levels-ui.js +84 -0
  23. package/dist/check-levels.d.ts +67 -0
  24. package/dist/check-levels.js +171 -0
  25. package/dist/claim.d.ts +22 -0
  26. package/dist/claim.js +43 -0
  27. package/dist/cli.d.ts +1 -1
  28. package/dist/cli.js +6 -0
  29. package/dist/demo-chat.js +4 -1
  30. package/dist/dispatch.js +9 -3
  31. package/dist/dispose.d.ts +12 -3
  32. package/dist/dispose.js +19 -5
  33. package/dist/exec.d.ts +5 -0
  34. package/dist/exec.js +30 -4
  35. package/dist/export.js +3 -2
  36. package/dist/first-run.d.ts +34 -0
  37. package/dist/first-run.js +37 -1
  38. package/dist/flow-gallery-ui.d.ts +30 -0
  39. package/dist/flow-gallery-ui.js +85 -0
  40. package/dist/flow-gallery.d.ts +111 -0
  41. package/dist/flow-gallery.js +445 -0
  42. package/dist/flow-share.d.ts +102 -0
  43. package/dist/flow-share.js +614 -0
  44. package/dist/flow-starters.d.ts +2 -0
  45. package/dist/flow-starters.js +1 -1
  46. package/dist/flow-steps.js +7 -0
  47. package/dist/flow-triggers.js +2 -0
  48. package/dist/flows-cli.d.ts +56 -0
  49. package/dist/flows-cli.js +109 -3
  50. package/dist/flows-ui.d.ts +15 -1
  51. package/dist/flows-ui.js +31 -6
  52. package/dist/guides.js +27 -2
  53. package/dist/invoke.js +5 -0
  54. package/dist/lead-context.js +6 -2
  55. package/dist/mate-doors.d.ts +0 -15
  56. package/dist/mate-doors.js +5 -1
  57. package/dist/mate-tools.js +9 -4
  58. package/dist/models-ui.js +1 -1
  59. package/dist/modes.d.ts +3 -1
  60. package/dist/modes.js +3 -1
  61. package/dist/operate.d.ts +4 -1
  62. package/dist/operate.js +711 -98
  63. package/dist/process-custody.js +8 -0
  64. package/dist/project-concurrency.d.ts +62 -0
  65. package/dist/project-concurrency.js +116 -0
  66. package/dist/project-delete-ui.d.ts +7 -0
  67. package/dist/project-delete-ui.js +19 -2
  68. package/dist/project-delete.js +4 -0
  69. package/dist/provider.js +16 -0
  70. package/dist/pull-request-flow.d.ts +9 -0
  71. package/dist/pull-request-flow.js +21 -3
  72. package/dist/result-follow-ups.d.ts +101 -0
  73. package/dist/result-follow-ups.js +333 -0
  74. package/dist/retention-ui.d.ts +3 -1
  75. package/dist/retention-ui.js +4 -4
  76. package/dist/retention.d.ts +13 -6
  77. package/dist/retention.js +50 -12
  78. package/dist/review-switch.d.ts +41 -0
  79. package/dist/review-switch.js +88 -0
  80. package/dist/reviewer.d.ts +24 -2
  81. package/dist/reviewer.js +49 -1
  82. package/dist/scope.js +11 -0
  83. package/dist/serve.d.ts +211 -2
  84. package/dist/serve.js +1038 -145
  85. package/dist/store.d.ts +112 -4
  86. package/dist/store.js +447 -27
  87. package/dist/surface.js +36 -9
  88. package/dist/tailnet.d.ts +11 -0
  89. package/dist/tailnet.js +47 -0
  90. package/dist/task-outcome-cli.js +2 -2
  91. package/dist/task-status.d.ts +13 -3
  92. package/dist/task-status.js +38 -16
  93. package/dist/team-cli.js +3 -0
  94. package/dist/telegram-status.js +2 -2
  95. package/dist/verification-evidence.js +21 -1
  96. package/dist/webhooks.js +5 -0
  97. package/dist/work-index.js +39 -6
  98. package/dist/work-summary.d.ts +0 -4
  99. package/dist/work-summary.js +4 -1
  100. package/dist/workspace-ui.d.ts +6 -1
  101. package/dist/workspace-ui.js +14 -11
  102. package/package.json +1 -1
@@ -43,6 +43,9 @@ export type ResultFacts = {
43
43
  /** A no-change conclusion's two presence facts (handoff + sealed diff);
44
44
  * undefined when the caller did not read them. */
45
45
  recordComplete?: boolean;
46
+ /** The check level this result now stands at (check-levels.ts): Off reads
47
+ * Ready for review, saying no check ran, until a follow-up check passes. */
48
+ checkLevel?: "quick" | "full" | "off" | null;
46
49
  /** This exact run's independent review (v50 retry projection), read
47
50
  * per run so an older selected result keeps its own words; undefined
48
51
  * when the caller did not read it, null when never requested. */
@@ -65,11 +68,13 @@ export type ReviewFacts = {
65
68
  queuedOrigin?: "operator" | "automatic" | null;
66
69
  /** Whether the live attempt's reviewer worker is answering. */
67
70
  reviewerAlive: boolean;
71
+ /** The build's one automatic review is still pending (build-review.ts). */
72
+ automaticPending?: boolean;
68
73
  };
69
74
  /** The review facts from the store's bounded retry projection — the same
70
75
  * reading `diagnoseTaskDispatch` makes, so every surface starts from one
71
76
  * record. `reviewerAlive` answers for the live attempt's runner. */
72
- export declare function reviewFactsOf(retry: ReviewRetryState | null, reviewerAlive: (runner: string) => boolean): ReviewFacts | null;
77
+ export declare function reviewFactsOf(retry: ReviewRetryState | null, reviewerAlive: (runner: string) => boolean, automaticPending?: boolean): ReviewFacts | null;
73
78
  /** The tokens a review in flight wears — the dispatch codes, unchanged. */
74
79
  export declare const REVIEW_TOKENS: ReadonlySet<string>;
75
80
  /**
@@ -30,7 +30,7 @@ export function parseWorkView(raw) {
30
30
  /** The review facts from the store's bounded retry projection — the same
31
31
  * reading `diagnoseTaskDispatch` makes, so every surface starts from one
32
32
  * record. `reviewerAlive` answers for the live attempt's runner. */
33
- export function reviewFactsOf(retry, reviewerAlive) {
33
+ export function reviewFactsOf(retry, reviewerAlive, automaticPending = false) {
34
34
  if (retry === null || retry.state === "unrequested")
35
35
  return null;
36
36
  const current = retry.live ?? (retry.state === "queued" ? null : retry.latest);
@@ -45,6 +45,7 @@ export function reviewFactsOf(retry, reviewerAlive) {
45
45
  queuedBy: retry.openRequest?.requestedBy ?? null,
46
46
  queuedOrigin: retry.openRequest?.origin ?? null,
47
47
  reviewerAlive: retry.live !== null && reviewerAlive(retry.live.runner),
48
+ automaticPending,
48
49
  };
49
50
  }
50
51
  /** The tokens a review in flight wears — the dispatch codes, unchanged. */
@@ -59,12 +60,12 @@ const retriesLeft = (count, explicit = true) => `${count}${explicit ? " explicit
59
60
  * the v50 dispatch contract; nothing here changes the lifecycle.
60
61
  */
61
62
  export function reviewStatusOf(review) {
62
- // Model review is retired (2026-09-21): nothing schedules, retries or
63
- // waits for a reviewer, so a recorded review request or attempt is
64
- // history and never the result's primary status. The stored verdict and
65
- // the assignment's Ready/Complete state speak instead.
66
- void review;
67
- return null;
63
+ // The one automatic review (build-review.ts) holds the result only while it
64
+ // is queued or running. A failed review never blocks: the result reads as
65
+ // it would unreviewed, marked "not reviewed" by the result itself.
66
+ if (review === null || review.automaticPending !== true || (review.state !== "queued" && review.state !== "running"))
67
+ return null;
68
+ return { token: "reviewing", label: "Reviewing", detail: "An automatic review is reading this result before it reaches you.", tone: "live", action: { label: "Open the result", kind: "open-result" } };
68
69
  }
69
70
  const FAILED_CHECK = /^the repository's approved verification command exited (-?[0-9]+)/;
70
71
  export function evidenceProblemOf(verdict, reasons) {
@@ -123,7 +124,7 @@ export function publicationStatusOf(publication) {
123
124
  * the detail).
124
125
  */
125
126
  export function resultStatusOf(result, publication = null) {
126
- return storedResultStatusOf(result, publication);
127
+ return (result?.role === "builder" ? reviewStatusOf(result.review ?? null) : null) ?? storedResultStatusOf(result, publication);
127
128
  }
128
129
  /** What the machine itself recorded about a result, in a clause. */
129
130
  function machineVerdictWords(result) {
@@ -327,9 +328,11 @@ export function workStatusOf(facts, resultDisplay) {
327
328
  const read = done ? RESULT_NEEDS_YOU.has(status.token) ? { stage: "needs-you", need: "other" } : stageOfCode(status.token, { needsPerson: false })
328
329
  : stageOfCode(status.token, { needsPerson: status.views.includes("needs-you"), planning: facts.dispatch?.code === "running" && facts.dispatch.role === "planner", operatorHold: facts.dispatch?.action === "unhold" });
329
330
  const stage = done && read.stage !== "needs-you" && read.stage !== "failed" ? "finished" : read.stage;
331
+ const level = facts.result?.checkLevel ?? null;
330
332
  const shared = taskStatusOf({ stage, ...(read.need === undefined ? {} : { need: read.need }), reason: plainReasonOf(stage, status.token, status.detail),
331
- report: facts.result?.role === "scout", checks: stage === "finished" && VERIFIED_RESULT.has(status.token) ? { status: "passed", exitCode: null, head: null } : null });
332
- return { ...status, label: shared.headline, tone: workToneOf(shared.headline), detail: stage === "finished" ? status.detail : shared.sentence };
333
+ report: facts.result?.role === "scout", checks: stage !== "finished" ? null : VERIFIED_RESULT.has(status.token) ? { status: "passed", exitCode: null, head: null, level }
334
+ : level === "off" ? { status: "not-run", exitCode: null, head: null, level } : null });
335
+ return { ...status, label: shared.headline, tone: workToneOf(shared.headline), detail: stage === "finished" && level !== "off" ? status.detail : shared.sentence };
333
336
  }
334
337
  function workStatusWordsOf(facts, resultDisplay) {
335
338
  const dispatch = facts.dispatch;
@@ -372,7 +375,7 @@ function workStatusWordsOf(facts, resultDisplay) {
372
375
  return { ...result, views, rank: needs ? 0 : 3 };
373
376
  }
374
377
  if (facts.state === "cancelled") {
375
- return { token: "cancelled", label: "Cancelled", detail: dispatch?.detail ?? "Nothing else will run for this task.", tone: "muted", action: null, views, rank: 4 };
378
+ return { token: "cancelled", label: dispatch?.summary.startsWith("Replaced by ") ? dispatch.summary : "Cancelled", detail: dispatch?.detail ?? "Nothing else will run for this task.", tone: "muted", action: null, views, rank: 4 };
376
379
  }
377
380
  if (question !== null && facts.state !== "failed" && dispatch !== null && QUESTION_FIRST.has(dispatch.code)) {
378
381
  return {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "toolroll",
3
- "version": "0.9.6",
3
+ "version": "0.9.8",
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"