toolroll 0.9.53 → 0.9.55

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 (254) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/README.md +5 -4
  3. package/dist/agent-onboard.js +4 -1
  4. package/dist/approval-rules-ui.d.ts +3 -2
  5. package/dist/approval-rules-ui.js +15 -20
  6. package/dist/assignment-ui.d.ts +3 -2
  7. package/dist/assignment-ui.js +4 -11
  8. package/dist/backup-ui.d.ts +2 -1
  9. package/dist/backup-ui.js +16 -27
  10. package/dist/brand-mark.d.ts +3 -2
  11. package/dist/brand-mark.js +4 -4
  12. package/dist/browser/workspace.css +1 -1
  13. package/dist/browser/workspace.js +25 -25
  14. package/dist/browser-shell.d.ts +2 -1
  15. package/dist/browser-shell.js +9 -9
  16. package/dist/browser-workspace.d.ts +2 -3
  17. package/dist/browser-workspace.js +0 -3
  18. package/dist/chat-ask.js +8 -8
  19. package/dist/chat-core.d.ts +171 -0
  20. package/dist/chat-core.js +288 -0
  21. package/dist/chat-decide.d.ts +10 -8
  22. package/dist/chat-decide.js +26 -21
  23. package/dist/chat-delivery-state.d.ts +51 -75
  24. package/dist/chat-delivery-state.js +140 -170
  25. package/dist/chat-delivery.d.ts +21 -2
  26. package/dist/chat-delivery.js +313 -194
  27. package/dist/chat-flow.d.ts +29 -1
  28. package/dist/chat-flow.js +24 -50
  29. package/dist/chat-messages.d.ts +319 -0
  30. package/dist/chat-messages.js +841 -0
  31. package/dist/chat-migration.d.ts +30 -0
  32. package/dist/chat-migration.js +802 -0
  33. package/dist/chat-polish.d.ts +5 -4
  34. package/dist/chat-polish.js +9 -10
  35. package/dist/chat-quiet.d.ts +3 -0
  36. package/dist/chat-quiet.js +5 -0
  37. package/dist/check-levels-ui.d.ts +2 -1
  38. package/dist/check-levels-ui.js +26 -53
  39. package/dist/cli.d.ts +3 -1
  40. package/dist/cli.js +9 -3
  41. package/dist/coding-shipping-ui.d.ts +2 -1
  42. package/dist/coding-shipping-ui.js +6 -6
  43. package/dist/coding-ui.d.ts +3 -1
  44. package/dist/coding-ui.js +30 -29
  45. package/dist/contracts/chat-content.d.ts +71 -2
  46. package/dist/contracts/chat-content.js +22 -3
  47. package/dist/contracts/chat-tables.d.ts +11 -4
  48. package/dist/contracts/chat-tables.js +165 -87
  49. package/dist/contracts/cli.d.ts +1 -3
  50. package/dist/contracts/console-api.d.ts +1 -1
  51. package/dist/contracts/console-api.js +6 -5
  52. package/dist/contracts/discord-callback.js +2 -1
  53. package/dist/contracts/health.d.ts +1 -3
  54. package/dist/contracts/slack-callback.js +3 -2
  55. package/dist/contracts/store-json.d.ts +1 -5
  56. package/dist/contracts/store-json.js +1 -4
  57. package/dist/contracts/teams-callback.js +2 -1
  58. package/dist/control-ui.d.ts +5 -4
  59. package/dist/control-ui.js +9 -34
  60. package/dist/credentials-ui.d.ts +5 -4
  61. package/dist/credentials-ui.js +23 -24
  62. package/dist/demo-chat.d.ts +3 -3
  63. package/dist/demo-chat.js +29 -76
  64. package/dist/discord-chat.js +19 -38
  65. package/dist/discord-settings.d.ts +3 -2
  66. package/dist/discord-settings.js +21 -55
  67. package/dist/discord.js +4 -14
  68. package/dist/envelope.js +10 -0
  69. package/dist/evidence-pack.d.ts +2 -1
  70. package/dist/evidence-pack.js +45 -49
  71. package/dist/export-ui.d.ts +7 -2
  72. package/dist/export-ui.js +4 -10
  73. package/dist/export.js +4 -4
  74. package/dist/flow-gallery-ui.d.ts +4 -3
  75. package/dist/flow-gallery-ui.js +28 -43
  76. package/dist/flow-starters-ui.d.ts +2 -1
  77. package/dist/flow-starters-ui.js +12 -15
  78. package/dist/flow-triggers.d.ts +1 -0
  79. package/dist/flow-triggers.js +16 -14
  80. package/dist/flows-ui.d.ts +4 -3
  81. package/dist/flows-ui.js +19 -30
  82. package/dist/flows.js +2 -1
  83. package/dist/guides.js +108 -3
  84. package/dist/html.d.ts +76 -0
  85. package/dist/html.js +173 -0
  86. package/dist/integrations-ui.d.ts +2 -1
  87. package/dist/integrations-ui.js +19 -23
  88. package/dist/kits-ui.d.ts +5 -4
  89. package/dist/kits-ui.js +18 -20
  90. package/dist/knowledge-ui.d.ts +6 -5
  91. package/dist/knowledge-ui.js +26 -25
  92. package/dist/lead-context.d.ts +11 -1
  93. package/dist/lead-context.js +6 -8
  94. package/dist/ledger-view.d.ts +2 -1
  95. package/dist/ledger-view.js +27 -29
  96. package/dist/limits-ui.d.ts +2 -1
  97. package/dist/limits-ui.js +7 -7
  98. package/dist/live-bus.d.ts +50 -8
  99. package/dist/live-bus.js +133 -50
  100. package/dist/mate-tools.js +3 -2
  101. package/dist/mcp-oauth.js +35 -36
  102. package/dist/models-ui.d.ts +2 -1
  103. package/dist/models-ui.js +25 -35
  104. package/dist/modes.d.ts +13 -1
  105. package/dist/modes.js +17 -1
  106. package/dist/monitoring-ui.d.ts +4 -3
  107. package/dist/monitoring-ui.js +13 -26
  108. package/dist/notification-rows.d.ts +30 -0
  109. package/dist/notification-rows.js +102 -0
  110. package/dist/openrouter-models.d.ts +2 -1
  111. package/dist/openrouter-models.js +5 -9
  112. package/dist/operate.js +16 -9
  113. package/dist/people-audit-ui.d.ts +2 -1
  114. package/dist/people-audit-ui.js +13 -13
  115. package/dist/plane-review.js +5 -11
  116. package/dist/policy-ui.d.ts +3 -2
  117. package/dist/policy-ui.js +17 -23
  118. package/dist/project-delete-ui.d.ts +4 -3
  119. package/dist/project-delete-ui.js +15 -27
  120. package/dist/project-delete.js +21 -26
  121. package/dist/pull-request-ui.d.ts +2 -1
  122. package/dist/pull-request-ui.js +17 -32
  123. package/dist/recipe-ui.d.ts +8 -7
  124. package/dist/recipe-ui.js +39 -32
  125. package/dist/release-adapters.d.ts +60 -0
  126. package/dist/release-adapters.js +435 -0
  127. package/dist/release-cli.d.ts +24 -0
  128. package/dist/release-cli.js +181 -0
  129. package/dist/release-gate.d.ts +80 -0
  130. package/dist/release-gate.js +150 -0
  131. package/dist/release-links.d.ts +29 -0
  132. package/dist/release-links.js +102 -0
  133. package/dist/release.d.ts +331 -0
  134. package/dist/release.js +550 -0
  135. package/dist/reply-shape.d.ts +2 -1
  136. package/dist/reply-shape.js +5 -5
  137. package/dist/repository-context-ui.d.ts +2 -1
  138. package/dist/repository-context-ui.js +2 -7
  139. package/dist/request-budget-ui.d.ts +2 -1
  140. package/dist/request-budget-ui.js +16 -16
  141. package/dist/result-review.d.ts +2 -3
  142. package/dist/result-review.js +3 -9
  143. package/dist/result-shots.js +2 -2
  144. package/dist/retention-ui.d.ts +7 -1
  145. package/dist/retention-ui.js +7 -11
  146. package/dist/retention.js +1 -1
  147. package/dist/serve.d.ts +11 -2
  148. package/dist/serve.js +69 -58
  149. package/dist/server/chat.d.ts +3 -6
  150. package/dist/server/chat.js +969 -1006
  151. package/dist/server/chrome.d.ts +291 -0
  152. package/dist/server/chrome.js +747 -0
  153. package/dist/server/console.css +2819 -0
  154. package/dist/server/flows.d.ts +2 -6
  155. package/dist/server/flows.js +840 -766
  156. package/dist/server/guards.d.ts +1 -1
  157. package/dist/server/guards.js +5 -2
  158. package/dist/server/handler-context.d.ts +1 -1
  159. package/dist/server/handler-context.js +1 -1
  160. package/dist/server/handler-registry.d.ts +8 -6
  161. package/dist/server/handler-registry.js +14 -2
  162. package/dist/server/http.d.ts +274 -0
  163. package/dist/server/http.js +239 -0
  164. package/dist/server/live.d.ts +34 -0
  165. package/dist/server/live.js +309 -0
  166. package/dist/server/pages.d.ts +2 -6
  167. package/dist/server/pages.js +808 -789
  168. package/dist/server/people-tokens.d.ts +1 -6
  169. package/dist/server/people-tokens.js +580 -572
  170. package/dist/server/remote.d.ts +4 -7
  171. package/dist/server/remote.js +37 -70
  172. package/dist/server/render-chat.d.ts +402 -0
  173. package/dist/server/render-chat.js +927 -0
  174. package/dist/server/render-pages.d.ts +535 -0
  175. package/dist/server/render-pages.js +1277 -0
  176. package/dist/server/render-people.d.ts +32 -0
  177. package/dist/server/render-people.js +121 -0
  178. package/dist/server/render-results.d.ts +744 -0
  179. package/dist/server/render-results.js +2237 -0
  180. package/dist/server/render-settings.d.ts +147 -0
  181. package/dist/server/render-settings.js +577 -0
  182. package/dist/server/render-tasks.d.ts +632 -0
  183. package/dist/server/render-tasks.js +2345 -0
  184. package/dist/server/request-context.d.ts +46 -0
  185. package/dist/server/request-context.js +17 -0
  186. package/dist/server/route-table.d.ts +25 -3
  187. package/dist/server/route-table.js +163 -75
  188. package/dist/server/runtime.d.ts +15 -7
  189. package/dist/server/runtime.js +7 -1
  190. package/dist/server/session.d.ts +138 -0
  191. package/dist/server/session.js +94 -0
  192. package/dist/server/settings.d.ts +1 -5
  193. package/dist/server/settings.js +2182 -2117
  194. package/dist/server/task-views.d.ts +11 -4
  195. package/dist/server/task-views.js +26 -22
  196. package/dist/server/tasks.d.ts +9 -9
  197. package/dist/server/tasks.js +1486 -1418
  198. package/dist/server-telemetry.d.ts +4 -3
  199. package/dist/server-telemetry.js +4 -8
  200. package/dist/skills-ui.d.ts +4 -3
  201. package/dist/skills-ui.js +14 -17
  202. package/dist/skills.d.ts +1 -1
  203. package/dist/skills.js +2 -1
  204. package/dist/slack-api.d.ts +5 -1
  205. package/dist/slack-api.js +2 -2
  206. package/dist/slack-chat.d.ts +9 -4
  207. package/dist/slack-chat.js +29 -52
  208. package/dist/slack-settings.d.ts +3 -2
  209. package/dist/slack-settings.js +23 -57
  210. package/dist/slack.js +6 -16
  211. package/dist/spend-ui.d.ts +2 -1
  212. package/dist/spend-ui.js +9 -32
  213. package/dist/sso-ui.d.ts +3 -2
  214. package/dist/sso-ui.js +26 -27
  215. package/dist/storage-ui.d.ts +2 -1
  216. package/dist/storage-ui.js +14 -33
  217. package/dist/store.d.ts +97 -364
  218. package/dist/store.js +207 -1531
  219. package/dist/surface.js +14 -3
  220. package/dist/task-composer.d.ts +2 -1
  221. package/dist/task-composer.js +7 -7
  222. package/dist/task-status.d.ts +4 -3
  223. package/dist/task-status.js +15 -16
  224. package/dist/team-http.d.ts +5 -9
  225. package/dist/team-http.js +5 -63
  226. package/dist/team-ui.d.ts +2 -1
  227. package/dist/team-ui.js +2 -5
  228. package/dist/teammate-question.js +12 -12
  229. package/dist/teammates-ui.d.ts +5 -4
  230. package/dist/teammates-ui.js +61 -90
  231. package/dist/teams-chat.js +12 -9
  232. package/dist/teams-settings.d.ts +3 -2
  233. package/dist/teams-settings.js +22 -33
  234. package/dist/teams.js +4 -5
  235. package/dist/telegram-flow.js +5 -5
  236. package/dist/telegram-settings.d.ts +3 -2
  237. package/dist/telegram-settings.js +14 -25
  238. package/dist/telegram.js +4 -4
  239. package/dist/toolroll-update-ui.d.ts +3 -2
  240. package/dist/toolroll-update-ui.js +35 -39
  241. package/dist/toolroll-update.d.ts +10 -0
  242. package/dist/toolroll-update.js +50 -3
  243. package/dist/tools-ui.d.ts +5 -2
  244. package/dist/tools-ui.js +31 -31
  245. package/dist/when-html.d.ts +11 -3
  246. package/dist/when-html.js +5 -6
  247. package/dist/workspace-revision.js +3 -1
  248. package/dist/workspace-ui.d.ts +4 -2
  249. package/dist/workspace-ui.js +10 -10
  250. package/package.json +1 -1
  251. package/dist/server/shared.d.ts +0 -3151
  252. package/dist/server/shared.js +0 -12001
  253. package/dist/slack-state.d.ts +0 -13
  254. package/dist/slack-state.js +0 -10
@@ -0,0 +1,632 @@
1
+ /** Task pages: approval, agents, plans, controls, decisions and the task body. */
2
+ import { type Html } from "../html.js";
3
+ import { type RunActivity } from "../activity-line.js";
4
+ import { type AgentChoice } from "../agentconfig.js";
5
+ import { type AssignmentSnapshot } from "../assignment.js";
6
+ import { type BrowserTaskView } from "../browser-workspace.js";
7
+ import { type FormView } from "../contracts/console-api.js";
8
+ import { type DispatchDiagnosis } from "../dispatch.js";
9
+ import { type ReportView } from "../evidence.js";
10
+ import { type Gap } from "../gaps.js";
11
+ import { type FailureExplanation } from "../needs-you.js";
12
+ import { type RouteOverride, type RouteProjection } from "../phase-routing.js";
13
+ import { type MilestoneState } from "../plan.js";
14
+ import { type ContractChange } from "../planner-source.js";
15
+ import { type CriterionMatrixRow, type ProofVerdict } from "../proof.js";
16
+ import { type Phase } from "../provider.js";
17
+ import { type QualityMode } from "../quality.js";
18
+ import { type AcceptanceCriterion, type Scope, type UnattendedPermissionMode } from "../scope.js";
19
+ import { type Artifact, type CheckProgress, type CoordinatorProposal, type Decision, type ExternalMirror, type Hold, type Incident, type PlanRevisionKind, type PlanRevisionStatus, type Publication, type PublicationGrant, type RepairChainRow, type ReviewRetryState, type RevisionLineage, type Run, type SteerNote, type Store, type Task } from "../store.js";
20
+ import { type TaskControlView } from "../task-control.js";
21
+ import { type DisplayStatus, type PublicationFacts, type ReviewFacts, type WorkStatus } from "../workspace-ui.js";
22
+ import { type Chrome, type Screen } from "./chrome.js";
23
+ import { type CompletionReceiptView, type EvidenceLinkMap, type TaskPullRequest } from "./render-results.js";
24
+ import { type Who } from "./session.js";
25
+ /** What the task and approval views show about a drafted plan's contract
26
+ * (contract handoff, task 1). A problem is a named problem, never a blank. */
27
+ export type PlanContractView = {
28
+ run: number;
29
+ problem: string;
30
+ } | {
31
+ run: number;
32
+ sourceDigest: string;
33
+ /** Whether a scope was filed before planning (false: legacy road). */
34
+ filed: boolean;
35
+ amendment: string | null;
36
+ changes: ContractChange[];
37
+ changeWords: string[];
38
+ /** The proposed terms are still exactly the scope row. */
39
+ current: boolean;
40
+ /** A revision: the terms before planning were copied from the previous version, not filed by a person. */
41
+ revision?: boolean;
42
+ };
43
+ export declare function contractChangeHtml(change: ContractChange): Html;
44
+ /**
45
+ * The contract panel (contract handoff, task 1): whether the drafted plan
46
+ * reproduced the filed goal, exclusions, touches, and rubric exactly, or
47
+ * proposes an amendment — every addition, change, and removal listed, the
48
+ * planner's stated reason beside them, and the plain consequence that
49
+ * approving binds the AMENDED terms. "full" is the task page's card;
50
+ * "ceremony" is the restatement inside the approval form and /next.
51
+ */
52
+ export declare function planContractHtml(view: PlanContractView | null, mode: "full" | "ceremony"): Html;
53
+ /** The exact path limits, one per line (UI polish 2026-09-13): a long
54
+ * comma run was the least readable term on a phone. Every path, verbatim. */
55
+ export declare function approvalPathsHtml(touches: readonly string[]): Html;
56
+ /** The rubric, restated above the seal (v39) — the same claim the digest
57
+ * line already makes ("approval binds to this exact wording") extended to
58
+ * the acceptance terms: an id in Geist Mono (a machine fact the proof must
59
+ * answer by), a statement in Geist, the signed evidence kinds after
60
+ * it. `how` never renders here — it is advisory, never signed. Empty
61
+ * renders nothing: a grandfathered scope's ceremony is unchanged. */
62
+ export declare function acceptanceCeremonyHtml(criteria: readonly AcceptanceCriterion[]): Html;
63
+ /** "claude" + "opus" → "Claude Opus"; "claude-opus-5-5" → "Claude Opus 5.5"; anything else keeps its exact id. */
64
+ export declare function agentNameWords(provider: string, model: string | null): string;
65
+ /** The permission a sealed profile grants, in two or three words. */
66
+ export declare function permissionWordsOf(profile: Scope["profile"] | null | undefined): string | null;
67
+ /** One plain sentence for a revision (approval critique, Oct 2):
68
+ * "Fixes what build #9 missed: <criterion>." The notes, paths and lineage
69
+ * stay in the Details fold. */
70
+ export declare function revisionSentence(revision: Extract<RevisionView, {
71
+ sourceRun: number;
72
+ }>, acceptance: readonly AcceptanceCriterion[]): string;
73
+ /** A planner's amendment, said plainly and kept in view: approving binds
74
+ * the amended terms, so this is never folded away. */
75
+ export declare function approvalAmendmentHtml(view: PlanContractView | null | undefined): Html;
76
+ /**
77
+ * The approval sheet (approval critique, Oct 2): the plan open, in plain
78
+ * rows — Goal, Changes, Won't touch, Done when — one line of who builds,
79
+ * one Approve & start beside the password, and every remaining signed
80
+ * term (lineage, routing, runtime limits, the seal) in one Details fold.
81
+ * Presentation only: the same hidden fields, nonce, digest and password
82
+ * post to the same route, and the task page and chat card share it.
83
+ */
84
+ export declare function approvalSheetHtml(input: {
85
+ surface: "task" | "chat";
86
+ action: string;
87
+ csrf: string;
88
+ nonce: string;
89
+ digest: string;
90
+ returnTo: string | null;
91
+ scope: Scope;
92
+ planDocument: string | null;
93
+ planContract: PlanContractView | null | undefined;
94
+ revision: Extract<RevisionView, {
95
+ sourceRun: number;
96
+ }> | null;
97
+ revisionSourceHref: string;
98
+ /** A machine-drafted repair: the build it repairs. */
99
+ repairChain: RepairChainRow | null;
100
+ route: RouteView | null | undefined;
101
+ coordinator: {
102
+ label: string;
103
+ filedAgo: string | null;
104
+ } | null;
105
+ deliverable: "branch" | "report";
106
+ editHref: string;
107
+ notNowHref: string;
108
+ sticky: boolean;
109
+ /** Earlier versions of this task still queued or running, and how many of them are running. */
110
+ earlier: {
111
+ active: number;
112
+ running: number;
113
+ };
114
+ /** The in-place editor (task page): the scope route, a draft the server
115
+ * refused (with why), whether it opens on arrival, and the plan's steps editor. */
116
+ edit: {
117
+ action: string;
118
+ draft: URLSearchParams | null;
119
+ problem: string | null;
120
+ open: boolean;
121
+ stepsHref: string | null;
122
+ } | null;
123
+ }): Html;
124
+ /** Earlier versions of a task still in flight, in plain words: queued
125
+ * while they only wait, running once one has started; null when none. */
126
+ export declare function earlierVersionsWords(active: number, running: number): string | null;
127
+ /** An in-place plan edit that would change the agent's permissions: thrown to roll the save back. */
128
+ export declare class PermissionsWouldChange extends Error {
129
+ }
130
+ /** Evidence kinds in plain words, for the signed criteria in Details. */
131
+ export declare const EVIDENCE_PLAIN: Record<string, string>;
132
+ /** The permission choice a sealed profile carries, as the scope form names it. */
133
+ export declare function permissionModeOfProfile(profile: Scope["profile"] | null | undefined): UnattendedPermissionMode | null;
134
+ /** Done when, from the in-place editor: each line keeps its requirement's
135
+ * id by position, and its evidence and guidance while its words stand; a
136
+ * rewritten one is yours to check, like an added one; an emptied one is
137
+ * dropped. */
138
+ export declare function requirementsFromEditor(body: FormView<"requirement" | "requirement-new">, current: readonly AcceptanceCriterion[]): unknown[];
139
+ /**
140
+ * THE CONSENT DOOR (v48): whether a yes can be given on this scope right
141
+ * now — one answer for the task page, the focused chat, and /next, so no
142
+ * surface mints a nonce or shows a password the others would refuse.
143
+ * Closed when the scope cannot say exactly what would run: an unresolved
144
+ * profile, a routed row whose route cannot be read, a route with a stated
145
+ * problem, or a pre-routing row whose old approval no longer stands (its
146
+ * profile alone can no longer be agreed to — re-filing routes it). An
147
+ * approved legacy row never reaches here: its old yes is grandfathered.
148
+ * Every closed answer carries the words and the one road that opens it.
149
+ */
150
+ export type ConsentDoor = {
151
+ open: true;
152
+ } | {
153
+ open: false;
154
+ title: string;
155
+ why: string;
156
+ road: "scope" | "agents";
157
+ };
158
+ export declare function consentDoorOf(scope: Scope | null, route: RouteView | null | undefined): ConsentDoor;
159
+ /** The closed door, rendered: no nonce, no password, no approve button —
160
+ * the reason and the one act that opens it. */
161
+ export declare function consentClosedHtml(taskId: string, door: ConsentDoor & {
162
+ open: false;
163
+ }, surface: "task" | "chat" | "next"): Html;
164
+ export declare function profileWords(scope: Pick<Scope, "profile" | "profileState" | "unresolvedReason" | "digestVersion">): Html;
165
+ /** The Agents view every console surface renders (v47): the SAME
166
+ * projection the CLI prints — who plans, builds, and revises,
167
+ * whether each was recommended, overridden, or pinned, its reasons, and
168
+ * the readiness the task's runners have reported (ready / unavailable /
169
+ * unknown — an unknown is said, never upgraded). Readiness is volatile and
170
+ * never part of what an approval signs, so the ceremony shows the agents
171
+ * and their reasons only. */
172
+ export type RouteView = {
173
+ kind: "route" | "legacy" | "unreadable";
174
+ source: "approved" | "proposed" | "live" | null;
175
+ projection: RouteProjection | null;
176
+ /** A proven pre-routing row: its approved agent profile, nothing more. */
177
+ legacy: {
178
+ provider: string;
179
+ model: string;
180
+ repairModel: string;
181
+ approved: boolean;
182
+ } | null;
183
+ /** A routed row whose agents cannot be read — fail closed, in words. */
184
+ problem: string | null;
185
+ overrides: RouteOverride[];
186
+ /** An approver may edit: a live claim or a viewer session refuses. */
187
+ editable: boolean;
188
+ editableWhy: string | null;
189
+ /** A planner change after a draft landed asks for a real re-plan. */
190
+ replanOnPlanChange: boolean;
191
+ /** The scope digest the change forms CAS against; null = no scope yet. */
192
+ digest: string | null;
193
+ /** v48: the configured, role-valid agents an approver may choose from —
194
+ * every option an exact pair the operator named once in configuration.
195
+ * The form offers these and nothing else. */
196
+ choices: Record<Phase, AgentChoice[]>;
197
+ };
198
+ export declare const ROLE_NOUN: Record<RouteProjection["legs"][number]["phase"], string>;
199
+ export declare function agentsStandingWords(view: RouteView): string;
200
+ /** The size line an approval leads its agents with — "Small change: fast
201
+ * model, no plan" — and, quietly, why it was sized so. */
202
+ export declare function sizeLineHtml(projection: RouteProjection): Html;
203
+ /** What a size does, for a proposal card. */
204
+ export declare function sizeConsequence(size: string, risky: boolean): string;
205
+ /** The one plain-English line: who does what. */
206
+ export declare function agentsSummaryWords(view: RouteView): string;
207
+ /** A risk badge only when there is something to say: a risky change, or an
208
+ * older route sealed at elevated or high risk. */
209
+ export declare function riskBadgeHtml(projection: RouteProjection): Html;
210
+ /** Neutral metadata badges: risk (when not routine), posture, and standing. */
211
+ export declare function agentsBadgesHtml(view: RouteView): Html;
212
+ /** Volatile availability, per provider on the route — shown beside the
213
+ * agents, never inside the approval's terms. */
214
+ export declare function agentsAvailabilityHtml(projection: RouteProjection): Html;
215
+ /** The closed details: one row per role, with the reasons. */
216
+ export declare function agentsWhyHtml(projection: RouteProjection, summaryLabel?: string): Html;
217
+ /** The ceremony's agents block: what the yes agrees to — the agents and
218
+ * their reasons. Availability is volatile and deliberately absent here. */
219
+ export declare function agentsCeremonyHtml(view: RouteView | null | undefined): Html;
220
+ /** The runtime limits the sealed profile binds — permissions, turn and
221
+ * time bounds, repairs — restated on the ceremony as
222
+ * a CLOSED disclosure (v48): a term the yes covers, one tap away, never a
223
+ * wall of switches between the reader and the password. An unresolved
224
+ * profile still speaks in the open: that is a refusal, not a detail. */
225
+ export declare function runtimeDetailsHtml(scope: Pick<Scope, "profile" | "profileState" | "unresolvedReason" | "digestVersion">): Html;
226
+ /** The task page's Agents card: the summary, availability, closed reasons,
227
+ * and — for an approver — closed change controls. Every change re-files
228
+ * the scope; an approval given under the earlier agents needs renewing. */
229
+ export declare function agentsCardHtml(taskId: string, view: RouteView | null | undefined, canEdit: boolean): Html;
230
+ /** The chat's always-visible strip: the summary and a way to the details. */
231
+ export declare function agentsStripHtml(view: RouteView | null, taskId: string): Html;
232
+ /** A ceremony nonce as stored: the sha256 hex of the value the form carried. */
233
+ export declare function nonceHashOf(value: string): string;
234
+ /** The approve POST's refusal, in words a person can act on. */
235
+ export declare function approveRefusalWords(reason: string): string;
236
+ /** The browser's one-click approval binds not only the signed scope but the
237
+ * exact advisory plan revision shown beside it. The scope digest remains the
238
+ * durable authority; this composite makes a stale open tab fail when somebody
239
+ * edits the plan before approval. The empty middle slot keeps the bytes of
240
+ * forms already open (it once held other terms, always empty here). */
241
+ export declare function approvalFormDigest(scopeDigest: string, planSha: string | null): string;
242
+ /** The one task-level road from a truthful dispatch diagnosis to its nearest
243
+ * existing repair. This is navigation, never authority: every destination
244
+ * still owns its original confirmation, password, CSRF, and transactional
245
+ * checks. Keeping the map here also means the focused chat and task overview
246
+ * cannot send a person to different fixes for the same gate. */
247
+ export declare function taskRecoveryHref(taskId: string, diagnosis: DispatchDiagnosis | null): string | null;
248
+ /** The resume ceremony's digest (v52): the exact run, its settlement, and
249
+ * the scope approval as it stands — a nonce minted over one set of facts
250
+ * cannot confirm a resume under another. */
251
+ export declare function resumeDigestOf(taskId: string, runId: number, settledAt: string, scope: Scope | null): string;
252
+ export declare const stopWhen: (iso: string) => string;
253
+ /**
254
+ * The exact-run control (v52): ONE component on the task page, the
255
+ * focused chat, and the status fragment, so every surface names the same
256
+ * run and shows the same state. Stop is one guarded post naming the run;
257
+ * Stopping… is a disabled control with who asked and when; Resume opens
258
+ * the password ceremony; a stopped review points at Review again. Forms
259
+ * carry the CSRF token and the exact run id, nothing else.
260
+ */
261
+ /** Presentation only: the same projected words and action on all task
262
+ * surfaces. Approval keeps its action on the exact-terms disclosure. */
263
+ export declare function taskStatusCard(status: DisplayStatus & {
264
+ diagnostics?: WorkStatus["diagnostics"];
265
+ }, taskId: string, dispatch: DispatchDiagnosis | null, runId: number | null, approvalAction?: boolean): Html;
266
+ export declare function checkProgressHtml(progress: CheckProgress | null, id?: string): Html;
267
+ export declare function taskControlDetailsHtml(control: TaskControlView, taskId: string, csrf: string, surface: "task" | "chat", inert?: boolean, stopElsewhere?: boolean): Html;
268
+ /** `stopElsewhere`: the Building card already carries this exact run's Stop, so the control card keeps only its details.
269
+ * `csrf` is only a guard now: an empty one (a read-only surface) renders no forms; postForm writes the field. */
270
+ export declare function taskControlHtml(control: TaskControlView, taskId: string, csrf: string, surface: "task" | "chat", inert?: boolean, stopElsewhere?: boolean): Html;
271
+ /** The resume confirmation (v52): the exact run restated, what resuming
272
+ * does and does not do, the gate that would still keep work from
273
+ * starting, and the password typed again. */
274
+ export declare function resumeCeremonyPage(chrome: Chrome, data: {
275
+ taskId: string;
276
+ taskTitle: string;
277
+ control: TaskControlView & {
278
+ kind: "paused";
279
+ };
280
+ nonceValue: string;
281
+ /** Unused: postForm writes the CSRF field (kept for the caller). */
282
+ csrf: string;
283
+ returnTo: "task" | "chat";
284
+ gate: DispatchDiagnosis | null;
285
+ approved: boolean;
286
+ }): Screen;
287
+ export declare function taskViewSwitch(taskId: string, active: "overview" | "ask"): Html;
288
+ export declare function publicationFactsOf(publication: Publication | null): PublicationFacts;
289
+ /** Where a status's next act lives, for a row that links out. */
290
+ export declare function statusActionHref(status: DisplayStatus, taskId: string, runId: number | null, prUrl: string | null, repo?: string | null): string | null;
291
+ /** The one status line every surface renders: a dot in the tone, the
292
+ * label, and the `data-work-status` token tests and CSS key off. */
293
+ /** A not-yet-finished task's shared headline from its dispatch diagnosis (task-status.ts). */
294
+ export declare function dispatchHeadline(d: DispatchDiagnosis): string;
295
+ export declare function statusLineHtml(status: DisplayStatus, extra?: Html | ""): Html;
296
+ export declare function workDiagnosticsHtml(diagnostics: WorkStatus["diagnostics"]): Html;
297
+ /**
298
+ * The decision card everywhere a person may ANSWER (portfolio, the
299
+ * selected-project inbox; the task page joins in slice 3): a reversible
300
+ * option answers with one tap on the card, labeled with its own words —
301
+ * never a letter; an irreversible option is a LINK to the decision page,
302
+ * where the server-side confirm=yes guard lives. The roll-up inbox keeps
303
+ * its links-only cards and never renders this partial. The recommended
304
+ * option wears a neutral badge — recommendation is not urgency, and magenta
305
+ * stays on the card's outline.
306
+ */
307
+ export declare function decisionAnswerCard(decision: Decision & {
308
+ taskId: string;
309
+ repo?: string | null;
310
+ }, csrf: string, now: Date, chip: boolean, returnTo?: string | null): Html;
311
+ /**
312
+ * The inline-answer enhancement (portfolio arc §2): submits a reversible
313
+ * option's form as the urlencoded POST the forms-only gate expects, follows
314
+ * the redirect, and — because an answered decision leaves the open list —
315
+ * replaces ONLY that card with the answered receipt parsed from the
316
+ * decision page's own rendering, or removes the card. Anything unexpected
317
+ * (auth, a page that is not the decision's) navigates instead of inserting.
318
+ * Nothing else on the page is touched: typed input elsewhere survives.
319
+ */
320
+ export declare function decisionAnswerScript(): string;
321
+ /** A plan is stored as inert Markdown for portability into the builder
322
+ * brief, but the console renders its known structure as a useful control
323
+ * surface. Historical free-form plans keep their safe plain-text fallback. */
324
+ export declare const MILESTONE_STATE_WORDS: Record<MilestoneState, string>;
325
+ export declare function milestoneStateWord(state: MilestoneState): string;
326
+ /** Adaptive execution plans (v44): the live milestone projection a running
327
+ * (or finished) build has reported. A shared render used by BOTH the task
328
+ * page and the focused chat's live region (c2) — labeled clearly as an
329
+ * agent's own report, since a milestone claim is never completion proof
330
+ * (Priority 2's proof contract is the only thing that adjudicates "done"). */
331
+ export declare function milestoneProgressHtml(milestones: MilestoneProgressView[] | null | undefined): Html;
332
+ /** Adaptive execution plans (v44): the current plan revision's own reason
333
+ * and evidence, any revision still awaiting an operator's accept/reject,
334
+ * and the immutable history. A shared render used by BOTH the task page
335
+ * and the focused chat's live region (c2), reading a document already
336
+ * verified before a byte reached this function (c5). `csrf` is only a
337
+ * guard now: an empty one renders no forms; postForm writes the field. */
338
+ export declare function planRevisionLedgerHtml(ledger: PlanRevisionLedgerView | null | undefined, taskId: string, csrf: string): Html;
339
+ export declare function executionPlanHtml(document: string, compact?: boolean): Html;
340
+ /** One plan revision, its document verified before a byte renders — the
341
+ * same verify-then-read discipline as `planViewOf`, just carrying the
342
+ * ledger row's own facts alongside the text. `id: null` marks the
343
+ * read-only revision-1 projection for a task with no `plan_revision` rows
344
+ * yet (c1). */
345
+ export type RevisionDocView = {
346
+ id: number | null;
347
+ revision: number;
348
+ status: PlanRevisionStatus;
349
+ reason: string;
350
+ evidenceLink: string | null;
351
+ author: string;
352
+ kind: PlanRevisionKind;
353
+ authorityKind: "plan-only" | "authority-change";
354
+ changedFields: string[];
355
+ document: string;
356
+ sha256: string;
357
+ createdAt: string;
358
+ resolvedAt: string | null;
359
+ resolvedBy: string | null;
360
+ };
361
+ export type PlanRevisionLedgerView = {
362
+ current: RevisionDocView | null;
363
+ pending: RevisionDocView | null;
364
+ history: RevisionDocView[];
365
+ };
366
+ export type MilestoneProgressView = {
367
+ id: string;
368
+ description: string;
369
+ state: MilestoneState;
370
+ note: string | null;
371
+ };
372
+ /** The revision batch a task's approval screen restates, or the named reason it cannot. */
373
+ export type RevisionView = {
374
+ sourceTask: string;
375
+ sourceRun: number;
376
+ /** What kind of brief this is — annotations, a CI repair, a criterion repair. */
377
+ kind: "annotations" | "ci-repair" | "criterion-repair";
378
+ comments: {
379
+ path: string | null;
380
+ line: number | null;
381
+ note: string;
382
+ author: string;
383
+ }[];
384
+ /** The lineage and ACTUAL terms (contract handoff task 2), read from
385
+ * the child's own rows — the same projection chat and the approval
386
+ * card restate. */
387
+ lineage: RevisionLineage | null;
388
+ } | {
389
+ problem: string;
390
+ };
391
+ /**
392
+ * A revision's lineage and ACTUAL terms, in the same words on the task
393
+ * page, the approval card, and chat (contract handoff task 2): which
394
+ * source and build it revises, the ancestry to its root, the terms the
395
+ * child really carries (read from its own scope — never restated from the
396
+ * brief), what is re-resolved for THIS approval, what never inherits, and
397
+ * — when the task continues a repair chain — the attempts used against
398
+ * the signed cap.
399
+ */
400
+ export declare function revisionLineageWords(lineage: RevisionLineage): string[];
401
+ export declare function revisionLineageHtml(lineage: RevisionLineage | null): Html;
402
+ export declare function taskBodyParts(data: {
403
+ /** Until the first Ready result: show the task's way there (onboarding). */
404
+ guide?: boolean;
405
+ /** What the last attempt missed and what to change, shown when the task failed. */
406
+ failure?: FailureExplanation | null;
407
+ /** Run checks in place, for a status row that offers it. */
408
+ runChecks?: {
409
+ action: string;
410
+ level: "quick" | "full";
411
+ returnTo: string;
412
+ } | null;
413
+ /** The demo database: no check runs here, and the Checks row says so. */
414
+ demo?: boolean;
415
+ assignment?: AssignmentSnapshot | null;
416
+ checkProgress?: CheckProgress | null;
417
+ rootId?: string;
418
+ rootTitle?: string;
419
+ /** Markup the caller rendered (the version history). */
420
+ history?: Html;
421
+ versionLabel?: string | null;
422
+ status?: DisplayStatus;
423
+ task: Task;
424
+ /** Shared read-side lifecycle answer; the atomic claim still re-proves it. */
425
+ dispatch?: DispatchDiagnosis | null;
426
+ /** v52: the exact-run Stop / Stopping / Resume control. */
427
+ control?: TaskControlView;
428
+ strikes: number;
429
+ /** v102: who filed it, and the project's approval rules as they bear on this task (null: none apply). */
430
+ filer?: {
431
+ name: string | null;
432
+ kind: string;
433
+ } | null;
434
+ budgetHold?: string | null;
435
+ policyHold?: string | null;
436
+ approvalRules?: {
437
+ words: string;
438
+ votes: string[];
439
+ needsTwo: boolean;
440
+ } | null;
441
+ plan: "requested" | "drafted" | null;
442
+ planDocument: string | null;
443
+ planAuto?: boolean;
444
+ /** Hash of the verified plan artifact currently shown. */
445
+ planSha?: string | null;
446
+ /** The drafted plan's contract record (contract handoff, task 1). */
447
+ planContract?: PlanContractView | null;
448
+ /** Adaptive execution plans (v44): the revision ledger and live milestone
449
+ * projection — null for a task with no plan at all. */
450
+ planRevisions?: PlanRevisionLedgerView | null;
451
+ milestoneProgress?: MilestoneProgressView[] | null;
452
+ /** v34: what this task delivers, and the scout's report when one exists. */
453
+ deliverable?: "branch" | "report";
454
+ report?: ReportView | null;
455
+ revision?: RevisionView | null;
456
+ /** v40: this task's own place in a bounded repair chain — computed
457
+ * independent of `completion` (a freshly drafted, unapproved repair has
458
+ * no run yet, so it must not wait for one to say so). `completion`'s own
459
+ * branches render it too, once a run exists; this is the fallback for
460
+ * the moment before that, so "awaiting approval" is never invisible. */
461
+ repairChain?: RepairChainRow | null;
462
+ publication?: Publication | null;
463
+ repo: string | null;
464
+ /** Immutable filing provenance (v12) — the approver sees which door
465
+ * filed this (console, cli, intake, template:<name>) at the yes. */
466
+ filedVia?: string | null;
467
+ /** Coordinator provenance when an agent filed this; null otherwise. */
468
+ coordinator?: {
469
+ label: string;
470
+ filedAgo: string | null;
471
+ } | null;
472
+ holds: Hold[];
473
+ claimed: boolean;
474
+ /** What this task waits for — blockers outside this console's ceiling
475
+ * are named but carry no state and no link. */
476
+ waitsFor?: {
477
+ id: string;
478
+ title: string | null;
479
+ state: string | null;
480
+ admitted: boolean;
481
+ }[];
482
+ /** Open tasks a "wait for" select may offer (this console's view only). */
483
+ waitCandidates?: {
484
+ id: string;
485
+ title: string;
486
+ }[];
487
+ /** The run whose lease is the CURRENT live claim — computed by the data
488
+ * layer; the renderer never guesses liveness from a null outcome. */
489
+ liveRunId?: number | null;
490
+ /** What the agent did last on that live run, and when (task-activity.ts). */
491
+ activity?: RunActivity | null;
492
+ /** Workers that are both alive and authorized for this task's project. */
493
+ worker?: {
494
+ answering: number;
495
+ registered: number;
496
+ totalRegistered: number;
497
+ lastHeard: string | null;
498
+ };
499
+ /** Unmet capabilities that keep this exact task out of dispatch. */
500
+ gaps?: Gap[];
501
+ /** Whether this serve asserted its runner — the live file view exists. */
502
+ peekable?: boolean;
503
+ /** Where the task stands in its own column, from the data layer. */
504
+ position?: {
505
+ position: number;
506
+ total: number;
507
+ column: string | null;
508
+ } | null;
509
+ /** The tracker item this task stands for, when it is external work. */
510
+ mirror?: ExternalMirror | null;
511
+ scope: Scope | null;
512
+ /** What the approval nonce/digest bind: scope digest, or the joint fingerprint. */
513
+ approvalDigest?: string | null;
514
+ spendDefaults?: {
515
+ buildPerRunMicrousd: number | null;
516
+ } | null;
517
+ /** Installation starting value for a task that has no profile yet. */
518
+ permissionDefault?: UnattendedPermissionMode;
519
+ /** Durable choice for this task, when one was explicitly made. */
520
+ permissionMode?: UnattendedPermissionMode | null;
521
+ /** Installation starting value and this task's explicit evidence depth. */
522
+ qualityDefault?: QualityMode;
523
+ qualityMode?: QualityMode | null;
524
+ /** The phase route (v47) and whether this session may edit it. */
525
+ route?: RouteView | null;
526
+ canEditRoute?: boolean;
527
+ runs: Run[];
528
+ /** Proof produced by the newest finished attempt. The two booleans are
529
+ * machine facts about immutable, hash-addressed artifacts — never inferred
530
+ * from the agent's prose. `proofVerdict` is the closed machine-authored
531
+ * verdict (Priority 2), computed once at completion and never re-derived
532
+ * here — null only for a run that predates the proof system. */
533
+ completion?: {
534
+ runId: number;
535
+ outcome: string | null;
536
+ hasTerminalDiff: boolean;
537
+ hasHandoff: boolean;
538
+ proofVerdict: ProofVerdict | null;
539
+ /** v40: the verdict BEFORE an independent reviewer's judgements were
540
+ * folded in — null when no review has folded (every run before this
541
+ * migration, and every run no review has touched). */
542
+ machineVerdict: ProofVerdict | null;
543
+ proofReasons: string[];
544
+ proofMatrix: CriterionMatrixRow[];
545
+ proofMatrixLinks: EvidenceLinkMap;
546
+ proofAccepted: boolean;
547
+ /** v51: the run's signed quality mode — the policy semantic coverage is
548
+ * read under (default: review optional; strict: review required). */
549
+ qualityMode?: "default" | "strict";
550
+ /** v40: this run's own place in a bounded repair chain, if any. */
551
+ repairChain: RepairChainRow | null;
552
+ /** v50: every root review attempt of this result and what the
553
+ * allowance still admits; null when no review was ever asked for. */
554
+ reviewRetry?: ReviewRetryState | null;
555
+ /** The same review, as the shared projection reads it (review fixes). */
556
+ review?: ReviewFacts | null;
557
+ /** Priority 2's concise, shared result package. */
558
+ receipt: CompletionReceiptView | null;
559
+ } | null;
560
+ /** v50: whether this session may ask for a review retry (an approver's
561
+ * browser session — the same standing `task review` demands). */
562
+ canRetryReview?: boolean;
563
+ decisions: Decision[];
564
+ incidents: Incident[];
565
+ /** Pending coordinator proposals on this task (mate arc v3), with the decisions their answer cards name. */
566
+ coordinatorProposals?: {
567
+ rows: CoordinatorProposal[];
568
+ decisions: Map<number, Decision>;
569
+ now: Date;
570
+ } | null;
571
+ /** Operator steering notes (arc 1), delivery state included. */
572
+ steering?: SteerNote[];
573
+ /** The publication grant the publisher would act under — from
574
+ * publicationGrantFor(repo) only; null when none, or no project. */
575
+ grant?: PublicationGrant | null;
576
+ /** The pull request opened through Complete (its state, link, CI and merge), or the offer to open one for a
577
+ * result already marked complete; null when neither applies. */
578
+ pullRequest?: TaskPullRequest | null;
579
+ /** The task's whole family (the original and its revisions) and every attempt across it, for the thread. */
580
+ family?: {
581
+ root: {
582
+ id: string;
583
+ title: string;
584
+ createdAt: string;
585
+ goal?: string | null;
586
+ };
587
+ versions: {
588
+ id: string;
589
+ title: string;
590
+ state: string;
591
+ }[];
592
+ runs: (Run & {
593
+ taskId: string;
594
+ })[];
595
+ } | null;
596
+ /** Degraded composition (slice 1c). "sensitive": the page carries a
597
+ * password ceremony, so no live poller runs, the attempt panel is a
598
+ * static line, and open decisions render link-only — decided by the page
599
+ * wrapper from the rendered body itself. "pane": the body is embedded in
600
+ * the workbench's selected-task pane, which carries no run pollers, so
601
+ * only the attempt panel degrades. */
602
+ degraded?: "sensitive" | "pane";
603
+ csrf: string;
604
+ nonce: string;
605
+ scopeDraft?: URLSearchParams;
606
+ /** Arrived to edit the plan (?edit=plan): the approval sheet opens its editor. */
607
+ editPlan?: boolean;
608
+ cancelDraft?: string;
609
+ problem: string | null;
610
+ now: Date;
611
+ }): {
612
+ html: Html;
613
+ view: BrowserTaskView;
614
+ };
615
+ export declare function taskBody(data: Parameters<typeof taskBodyParts>[0]): Html;
616
+ export declare function taskPage(chrome: Chrome, data: Parameters<typeof taskBody>[0]): Screen;
617
+ /** One accessible two-choice control everywhere permissions are selected.
618
+ * The words describe behavior; the raw flag stays secondary detail. */
619
+ export declare function permissionModeChoices(name: string, selected: UnattendedPermissionMode): Html;
620
+ /** Quality selects the configured agent route; permissions remain separate. */
621
+ export declare function qualityModeChoices(name: string, selected: QualityMode): Html;
622
+ /**
623
+ * A decision's answer forms — one source of truth for the decision screen
624
+ * and the triage flow. The consequence reads BEFORE the button that buys
625
+ * it; irreversible options arm behind one deliberate tap AND the server
626
+ * independently requires the confirm field. `returnTo` is allow-listed by
627
+ * the answer handler, never an arbitrary URL. `csrf` is unused (postForm
628
+ * writes the field); kept for callers.
629
+ */
630
+ export declare function decisionOptionForms(decision: Decision, returnTo: string | null): Html;
631
+ export declare function decisionPage(chrome: Chrome, decision: Decision, taskId: string, artifacts: Artifact[], who: Who, now: Date, returnTo?: string | null): Screen;
632
+ export declare function taskOf(store: Store, decision: Decision): string;