toolroll 0.9.54 → 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 (199) hide show
  1. package/CHANGELOG.md +9 -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-polish.d.ts +5 -4
  19. package/dist/chat-polish.js +9 -10
  20. package/dist/check-levels-ui.d.ts +2 -1
  21. package/dist/check-levels-ui.js +26 -53
  22. package/dist/cli.d.ts +3 -1
  23. package/dist/cli.js +9 -3
  24. package/dist/coding-shipping-ui.d.ts +2 -1
  25. package/dist/coding-shipping-ui.js +6 -6
  26. package/dist/coding-ui.d.ts +3 -1
  27. package/dist/coding-ui.js +30 -29
  28. package/dist/contracts/cli.d.ts +1 -3
  29. package/dist/contracts/console-api.d.ts +1 -1
  30. package/dist/contracts/console-api.js +6 -5
  31. package/dist/contracts/health.d.ts +1 -3
  32. package/dist/control-ui.d.ts +5 -4
  33. package/dist/control-ui.js +9 -34
  34. package/dist/credentials-ui.d.ts +5 -4
  35. package/dist/credentials-ui.js +23 -24
  36. package/dist/demo-chat.d.ts +3 -3
  37. package/dist/demo-chat.js +29 -76
  38. package/dist/discord-settings.d.ts +3 -2
  39. package/dist/discord-settings.js +17 -42
  40. package/dist/envelope.js +10 -0
  41. package/dist/evidence-pack.d.ts +2 -1
  42. package/dist/evidence-pack.js +45 -49
  43. package/dist/export-ui.d.ts +7 -2
  44. package/dist/export-ui.js +4 -10
  45. package/dist/flow-gallery-ui.d.ts +4 -3
  46. package/dist/flow-gallery-ui.js +28 -43
  47. package/dist/flow-starters-ui.d.ts +2 -1
  48. package/dist/flow-starters-ui.js +12 -15
  49. package/dist/flow-triggers.d.ts +1 -0
  50. package/dist/flow-triggers.js +16 -14
  51. package/dist/flows-ui.d.ts +4 -3
  52. package/dist/flows-ui.js +19 -30
  53. package/dist/flows.js +2 -1
  54. package/dist/guides.js +108 -3
  55. package/dist/html.d.ts +76 -0
  56. package/dist/html.js +173 -0
  57. package/dist/integrations-ui.d.ts +2 -1
  58. package/dist/integrations-ui.js +19 -23
  59. package/dist/kits-ui.d.ts +5 -4
  60. package/dist/kits-ui.js +18 -20
  61. package/dist/knowledge-ui.d.ts +6 -5
  62. package/dist/knowledge-ui.js +26 -25
  63. package/dist/lead-context.d.ts +11 -1
  64. package/dist/lead-context.js +6 -8
  65. package/dist/ledger-view.d.ts +2 -1
  66. package/dist/ledger-view.js +27 -29
  67. package/dist/limits-ui.d.ts +2 -1
  68. package/dist/limits-ui.js +7 -7
  69. package/dist/live-bus.d.ts +50 -8
  70. package/dist/live-bus.js +133 -50
  71. package/dist/mcp-oauth.js +35 -36
  72. package/dist/models-ui.d.ts +2 -1
  73. package/dist/models-ui.js +25 -35
  74. package/dist/monitoring-ui.d.ts +4 -3
  75. package/dist/monitoring-ui.js +13 -26
  76. package/dist/openrouter-models.d.ts +2 -1
  77. package/dist/openrouter-models.js +5 -9
  78. package/dist/operate.js +11 -7
  79. package/dist/people-audit-ui.d.ts +2 -1
  80. package/dist/people-audit-ui.js +13 -13
  81. package/dist/policy-ui.d.ts +3 -2
  82. package/dist/policy-ui.js +17 -23
  83. package/dist/project-delete-ui.d.ts +4 -3
  84. package/dist/project-delete-ui.js +15 -27
  85. package/dist/pull-request-ui.d.ts +2 -1
  86. package/dist/pull-request-ui.js +17 -32
  87. package/dist/recipe-ui.d.ts +8 -7
  88. package/dist/recipe-ui.js +39 -32
  89. package/dist/release-adapters.d.ts +60 -0
  90. package/dist/release-adapters.js +435 -0
  91. package/dist/release-cli.d.ts +24 -0
  92. package/dist/release-cli.js +181 -0
  93. package/dist/release-gate.d.ts +80 -0
  94. package/dist/release-gate.js +150 -0
  95. package/dist/release-links.d.ts +29 -0
  96. package/dist/release-links.js +102 -0
  97. package/dist/release.d.ts +331 -0
  98. package/dist/release.js +550 -0
  99. package/dist/reply-shape.d.ts +2 -1
  100. package/dist/reply-shape.js +5 -5
  101. package/dist/repository-context-ui.d.ts +2 -1
  102. package/dist/repository-context-ui.js +2 -7
  103. package/dist/request-budget-ui.d.ts +2 -1
  104. package/dist/request-budget-ui.js +16 -16
  105. package/dist/result-review.d.ts +2 -3
  106. package/dist/result-review.js +3 -9
  107. package/dist/retention-ui.d.ts +7 -1
  108. package/dist/retention-ui.js +7 -11
  109. package/dist/serve.d.ts +11 -2
  110. package/dist/serve.js +69 -58
  111. package/dist/server/chat.d.ts +3 -6
  112. package/dist/server/chat.js +969 -1006
  113. package/dist/server/chrome.d.ts +291 -0
  114. package/dist/server/chrome.js +747 -0
  115. package/dist/server/console.css +2819 -0
  116. package/dist/server/flows.d.ts +2 -6
  117. package/dist/server/flows.js +840 -766
  118. package/dist/server/guards.d.ts +1 -1
  119. package/dist/server/guards.js +5 -2
  120. package/dist/server/handler-context.d.ts +1 -1
  121. package/dist/server/handler-context.js +1 -1
  122. package/dist/server/handler-registry.d.ts +8 -6
  123. package/dist/server/handler-registry.js +14 -2
  124. package/dist/server/http.d.ts +274 -0
  125. package/dist/server/http.js +239 -0
  126. package/dist/server/live.d.ts +34 -0
  127. package/dist/server/live.js +309 -0
  128. package/dist/server/pages.d.ts +2 -6
  129. package/dist/server/pages.js +808 -789
  130. package/dist/server/people-tokens.d.ts +1 -6
  131. package/dist/server/people-tokens.js +580 -572
  132. package/dist/server/remote.d.ts +4 -7
  133. package/dist/server/remote.js +37 -70
  134. package/dist/server/render-chat.d.ts +402 -0
  135. package/dist/server/render-chat.js +927 -0
  136. package/dist/server/render-pages.d.ts +535 -0
  137. package/dist/server/render-pages.js +1277 -0
  138. package/dist/server/render-people.d.ts +32 -0
  139. package/dist/server/render-people.js +121 -0
  140. package/dist/server/render-results.d.ts +744 -0
  141. package/dist/server/render-results.js +2237 -0
  142. package/dist/server/render-settings.d.ts +147 -0
  143. package/dist/server/render-settings.js +577 -0
  144. package/dist/server/render-tasks.d.ts +632 -0
  145. package/dist/server/render-tasks.js +2345 -0
  146. package/dist/server/request-context.d.ts +46 -0
  147. package/dist/server/request-context.js +17 -0
  148. package/dist/server/route-table.d.ts +25 -3
  149. package/dist/server/route-table.js +163 -75
  150. package/dist/server/runtime.d.ts +15 -7
  151. package/dist/server/runtime.js +7 -1
  152. package/dist/server/session.d.ts +138 -0
  153. package/dist/server/session.js +94 -0
  154. package/dist/server/settings.d.ts +1 -5
  155. package/dist/server/settings.js +2181 -2117
  156. package/dist/server/task-views.d.ts +11 -4
  157. package/dist/server/task-views.js +26 -22
  158. package/dist/server/tasks.d.ts +9 -9
  159. package/dist/server/tasks.js +1486 -1418
  160. package/dist/server-telemetry.d.ts +4 -3
  161. package/dist/server-telemetry.js +4 -8
  162. package/dist/skills-ui.d.ts +4 -3
  163. package/dist/skills-ui.js +14 -17
  164. package/dist/skills.d.ts +1 -1
  165. package/dist/skills.js +2 -1
  166. package/dist/slack-settings.d.ts +3 -2
  167. package/dist/slack-settings.js +17 -42
  168. package/dist/spend-ui.d.ts +2 -1
  169. package/dist/spend-ui.js +9 -32
  170. package/dist/sso-ui.d.ts +3 -2
  171. package/dist/sso-ui.js +26 -27
  172. package/dist/storage-ui.d.ts +2 -1
  173. package/dist/storage-ui.js +14 -33
  174. package/dist/surface.js +14 -3
  175. package/dist/task-composer.d.ts +2 -1
  176. package/dist/task-composer.js +7 -7
  177. package/dist/task-status.d.ts +4 -3
  178. package/dist/task-status.js +15 -16
  179. package/dist/team-http.d.ts +5 -9
  180. package/dist/team-http.js +5 -63
  181. package/dist/team-ui.d.ts +2 -1
  182. package/dist/team-ui.js +2 -5
  183. package/dist/teammates-ui.d.ts +5 -4
  184. package/dist/teammates-ui.js +61 -90
  185. package/dist/teams-settings.d.ts +3 -2
  186. package/dist/teams-settings.js +20 -31
  187. package/dist/telegram-settings.d.ts +3 -2
  188. package/dist/telegram-settings.js +14 -25
  189. package/dist/toolroll-update-ui.d.ts +3 -2
  190. package/dist/toolroll-update-ui.js +35 -39
  191. package/dist/tools-ui.d.ts +5 -2
  192. package/dist/tools-ui.js +31 -31
  193. package/dist/when-html.d.ts +11 -3
  194. package/dist/when-html.js +5 -6
  195. package/dist/workspace-ui.d.ts +4 -2
  196. package/dist/workspace-ui.js +10 -10
  197. package/package.json +1 -1
  198. package/dist/server/shared.d.ts +0 -3151
  199. package/dist/server/shared.js +0 -12001
@@ -1,9 +1,16 @@
1
+ import { type Html } from "../html.js";
1
2
  import { type AssignmentSnapshot } from '../assignment.js';
2
3
  import { type FailureExplanation } from '../needs-you.js';
3
4
  import type { TaskFamily } from "../store.js";
4
5
  import { type ServerResponse } from "node:http";
5
6
  import { type Scope } from "../scope.js";
6
- import { taskBody, type Chrome, type CompletionReceiptView, type MilestoneProgressView, type PlanContractView, type PlanRevisionLedgerView, type ProjectPeek, type ResultDetail, type RevisionDocView, type RevisionView, type RouteView, type Screen, type ServeOptions, type TaskChatFocus, type TaskPullRequest, type Who, type WorkRow } from "./shared.js";
7
+ import { type Chrome, type Screen } from "./chrome.js";
8
+ import { type ServeOptions } from "./http.js";
9
+ import { type TaskChatFocus } from "./render-chat.js";
10
+ import { type ProjectPeek, type WorkRow } from "./render-pages.js";
11
+ import { type CompletionReceiptView, type ResultDetail, type TaskPullRequest } from "./render-results.js";
12
+ import { taskBody, type MilestoneProgressView, type PlanContractView, type PlanRevisionLedgerView, type RevisionDocView, type RevisionView, type RouteView } from "./render-tasks.js";
13
+ import { type Who } from "./session.js";
7
14
  import type { PlanRevision, TaskRef } from "../store.js";
8
15
  import { type Run, type Store, type Task, type TaskState } from "../store.js";
9
16
  import { type ReviewFacts } from "../workspace-ui.js";
@@ -27,7 +34,7 @@ export interface TaskViewsRuntime {
27
34
  restricted: () => boolean;
28
35
  options: ServeOptions;
29
36
  sendScreen: (response: ServerResponse, status: number, s: Screen) => void;
30
- chromeFor: (project: string | null, active: Chrome["active"], listPane?: string, scope?: Chrome["scope"]) => Chrome;
37
+ chromeFor: (project: string | null, active: Chrome["active"], listPane?: Html, scope?: Chrome["scope"]) => Chrome;
31
38
  unscopedMode: boolean;
32
39
  dockedConversation: (who: Who, focusTask: TaskChatFocus | null, chatProject: string | null, now: Date, back: string, resultRunId?: number | null) => import("../browser-workspace.js").BrowserConversation | null;
33
40
  liveRefreshSeconds: () => number;
@@ -41,13 +48,13 @@ export declare function createTaskViews(runtime: TaskViewsRuntime): {
41
48
  })[];
42
49
  revisionDestination: (child: string, back: string) => string;
43
50
  earlierLiveVersions: (family: TaskFamily, now: Date) => string[];
44
- familyHistory: (family: TaskFamily) => string;
51
+ familyHistory: (family: TaskFamily) => Html;
45
52
  freshAssignment: (assignment: AssignmentSnapshot | null, receipt: CompletionReceiptView | null) => AssignmentSnapshot | null;
46
53
  workRowOf: (task: Task & {
47
54
  repo: string | null;
48
55
  family?: TaskFamily;
49
56
  }, now: Date, receipt?: CompletionReceiptView | null) => WorkRow;
50
- taskListPane: (project: string | null, currentId: string | null) => string;
57
+ taskListPane: (project: string | null, currentId: string | null) => Html;
51
58
  runIsLive: (run: Pick<Run, "outcome" | "leaseId" | "taskRef">) => boolean;
52
59
  runIsTaskResult: (run: Pick<Run, "role" | "finishedAt">) => boolean;
53
60
  revisionViewOf: (ref: ReturnType<Store["lookupRef"]>) => RevisionView | null;
@@ -1,4 +1,5 @@
1
1
  import { assignmentPresentationOf, historicalAssessmentReason } from '../assignment-presentation.js';
2
+ import { html, joinHtml } from "../html.js";
2
3
  import { assignmentStatusOf, assignmentWithEvidence } from '../assignment-ui.js';
3
4
  import { assignmentOf } from '../assignment.js';
4
5
  import { knowledgeContextHtml } from "../knowledge-ui.js";
@@ -32,7 +33,13 @@ import { isRevisionFeedback } from "../result-review.js";
32
33
  import { buildReviewOf } from "../review-switch.js";
33
34
  import { isAlive as runnerAlive } from "../runner.js";
34
35
  import { approvalOf } from "../scope.js";
35
- import { approvalFormDigest, nonceHashOf, chatResultHref, completionReceiptView, consentDoorOf, decisionsFor, diffFileAnchor, escape, evidenceLinksFor, followUpsFor, oneLineOf, orderChangedFiles, parseReviewDiff, proofBundleView, publicationFactsOf, receiptStatusOf, refuse, resumeCeremonyPage, resumeDigestOf, reviewHref, screen, taskBody, taskChatHref, taskHref, taskPage, withinSignedTouches } from "./shared.js";
36
+ import { oneLineOf, refuse, screen } from "./chrome.js";
37
+ import { chatResultHref, reviewHref, taskChatHref, taskHref } from "./http.js";
38
+ import { decisionsFor } from "./render-chat.js";
39
+ import {} from "./render-pages.js";
40
+ import { completionReceiptView, diffFileAnchor, evidenceLinksFor, followUpsFor, orderChangedFiles, parseReviewDiff, proofBundleView, receiptStatusOf, withinSignedTouches } from "./render-results.js";
41
+ import { approvalFormDigest, consentDoorOf, nonceHashOf, publicationFactsOf, resumeCeremonyPage, resumeDigestOf, taskBody, taskPage } from "./render-tasks.js";
42
+ import {} from "./session.js";
36
43
  import { budgetHoldWords, budgetLabel, monthOf } from "../spend.js";
37
44
  import {} from "../store.js";
38
45
  import { taskControlOf } from "../task-control.js";
@@ -74,20 +81,19 @@ export function createTaskViews(runtime) {
74
81
  .filter(task => workRowOf(task, now).status.views.includes("running")).map(task => task.id);
75
82
  }
76
83
  function familyHistory(family) {
77
- const warning = family.problem === null ? "" : `<p class="problem" data-history-problem>${escape(family.problem)}</p>`;
84
+ const warning = family.problem === null ? "" : html `<p class="problem" data-history-problem>${family.problem}</p>`;
78
85
  const otherActive = new Set([...family.otherActive.map(one => one.id), ...earlierLiveVersions(family, runtime.clock())]).size;
79
- const active = otherActive === 0 ? "" : `<p class="problem" data-other-active>${otherActive} earlier version${otherActive === 1 ? " is" : "s are"} still waiting or running. Review History.</p>`;
86
+ const active = otherActive === 0 ? "" : html `<p class="problem" data-other-active>${otherActive} earlier version${otherActive === 1 ? " is" : "s are"} still waiting or running. Review History.</p>`;
80
87
  if (family.versions.length < 2)
81
- return warning;
88
+ return html `${warning}`;
82
89
  const versions = family.versions.map((version, index) => {
83
90
  const label = index === 0 ? "Original" : `Revision ${index}`;
84
91
  const status = workRowOf(version, runtime.clock()).status;
85
92
  const runs = runtime.store.runsFor(version.refId).filter(runIsTaskResult);
86
93
  const href = `${taskHref(family.root.id)}?version=${encodeURIComponent(version.id)}`;
87
- return `<li data-history-version="${escape(version.id)}"><a href="${href}">${label}</a>${version.id === family.current.id ? " · Current" : ""} · ${escape(status.label)}` +
88
- runs.map(run => `<a href="${escape(run.outcome === "built" || run.outcome === "no-change" ? chatResultHref(family.root.id, run.id) : `/r/${run.id}`)}">Build #${run.id}${run.outcome === "built" ? "" : ` · ${escape(run.outcome === "no-change" ? "No changes" : run.outcome === "failed" ? "Failed" : run.outcome ?? "Unfinished")}`}</a>`).join("") + `</li>`;
94
+ return html `<li data-history-version="${version.id}"><a href="${href}">${label}</a>${version.id === family.current.id ? " · Current" : ""} · ${status.label}${runs.map(run => html `<a href="${run.outcome === "built" || run.outcome === "no-change" ? chatResultHref(family.root.id, run.id) : `/r/${run.id}`}">Build #${run.id}${run.outcome === "built" ? "" : ` · ${run.outcome === "no-change" ? "No changes" : run.outcome === "failed" ? "Failed" : run.outcome ?? "Unfinished"}`}</a>`)}</li>`;
89
95
  });
90
- return warning + active + `<details class="task-history" data-root-task="${escape(family.root.id)}"><summary>History</summary><ol>${versions.join("")}</ol></details>`;
96
+ return html `${warning}${active}<details class="task-history" data-root-task="${family.root.id}"><summary>History</summary><ol>${versions}</ol></details>`;
91
97
  }
92
98
  /** Keep detailed receipt diagnostics; shared assignment reads own readiness. */
93
99
  function freshAssignment(assignment, receipt) {
@@ -166,11 +172,9 @@ export function createTaskViews(runtime) {
166
172
  if (family !== null && (project === null || family.root.repo === null || family.root.repo === project))
167
173
  rows.push({ ...family.current, id: family.root.id, title: family.root.title });
168
174
  }
169
- const items = rows
170
- .map(task => `<a class="item${task.id === currentId ? " current" : ""}" href="${taskHref(task.id)}">` +
171
- `<span class="t">${escape(task.title)}</span></a>`)
172
- .join("\n");
173
- return `<h2>Tasks</h2>\n${items === "" ? `<p class="meta">None yet</p>` : items}`;
175
+ const items = joinHtml(rows
176
+ .map(task => html `<a class="item${task.id === currentId ? " current" : ""}" href="${taskHref(task.id)}"><span class="t">${task.title}</span></a>`), "\n");
177
+ return html `<h2>Tasks</h2>\n${rows.length === 0 ? html `<p class="meta">None yet</p>` : items}`;
174
178
  }
175
179
  /**
176
180
  * The one liveness fact (round-4 findings 14/15): a run is being built
@@ -677,13 +681,13 @@ export function createTaskViews(runtime) {
677
681
  function taskScreen(response, who, taskId, problem, status, scopeDraft, cancelDraft, editPlan = false) {
678
682
  const admittedFamily = runtime.familyOf(taskId);
679
683
  if (admittedFamily?.problem != null)
680
- return runtime.sendScreen(response, status, screen(admittedFamily.root.title, `<h1>${escape(admittedFamily.root.title)}</h1><p>${escape(admittedFamily.current.state)}</p><p class="problem" data-history-problem>${escape(admittedFamily.problem)}</p>`, { chrome: runtime.chromeFor(admittedFamily.root.repo, "tasks") }));
684
+ return runtime.sendScreen(response, status, screen(admittedFamily.root.title, html `<h1>${admittedFamily.root.title}</h1><p>${admittedFamily.current.state}</p><p class="problem" data-history-problem>${admittedFamily.problem}</p>`, { chrome: runtime.chromeFor(admittedFamily.root.repo, "tasks") }));
681
685
  const data = taskViewData(taskId, who, problem);
682
686
  if (data === null)
683
687
  return refuse(response, who, 404, "no such task", "/tasks");
684
688
  const family = runtime.familyOf(taskId);
685
689
  const presentedData = { ...data, rootId: family?.root.id ?? taskId, rootTitle: family?.root.title ?? data.task.title,
686
- history: family === null || data.assignment != null ? "" : familyHistory(family),
690
+ ...(family === null || data.assignment != null ? {} : { history: familyHistory(family) }),
687
691
  versionLabel: family !== null && family.current.id !== taskId ? `Viewing ${family.versions.findIndex(one => one.id === taskId) === 0 ? "Original" : `Revision ${family.versions.findIndex(one => one.id === taskId)}`} · ${family.current.state === "running" ? "A newer revision is running" : "A newer revision is current"}` : null };
688
692
  if (scopeDraft !== undefined)
689
693
  presentedData.scopeDraft = scopeDraft;
@@ -716,7 +720,7 @@ export function createTaskViews(runtime) {
716
720
  // only an approver is offered a road to message the agent.
717
721
  const taskView = page.workspace?.view?.kind === "task" ? { ...page.workspace.view, ...(docked === null ? {} : { tabs: [] }), ...(who.role === "approver" ? {} : { chatHref: null }),
718
722
  // A signed-in page hears the moment the task changes, and who else has it open.
719
- ...(who.via === "cookie" ? { live: { href: `${taskHref(family?.root.id ?? taskId)}/live`, at: (() => { try {
723
+ ...(who.via === "cookie" ? { live: { room: `task:${encodeURIComponent(family?.root.id ?? taskId)}`, at: (() => { try {
720
724
  return taskFingerprint(runtime.store, family?.root.id ?? taskId, runtime.clock());
721
725
  }
722
726
  catch {
@@ -755,7 +759,7 @@ export function createTaskViews(runtime) {
755
759
  if (run.role === "reviewer")
756
760
  return taskScreen(response, who, taskId, `run #${runId} is a historical review run — nothing reruns it; open the saved result instead`, 409);
757
761
  if (stop.resumedAt !== null)
758
- return taskScreen(response, who, taskId, `run #${runId} was already resumed by ${escape(stop.resumedBy ?? "?")}`, 409);
762
+ return taskScreen(response, who, taskId, `run #${runId} was already resumed by ${stop.resumedBy ?? "?"}`, 409);
759
763
  const control = taskControlOf(runtime.store, ref.id, now);
760
764
  if (control.kind !== "paused" || control.run !== runId) {
761
765
  return taskScreen(response, who, taskId, control.kind === "stopping" ? `run #${runId} is still stopping — its processes are not yet established gone` : `run #${runId} is no longer the attempt a resume can name — reload and decide against the current state`, 409);
@@ -957,7 +961,7 @@ export function createTaskViews(runtime) {
957
961
  cited: cited.has(file.path),
958
962
  })), cited.size > 0);
959
963
  const publication = runtime.store.publicationForRun(run.id);
960
- let learning = "", skillTest = false;
964
+ let learning = html ``, skillTest = false;
961
965
  const learningRepo = runtime.store.refForId(run.taskRef)?.repo;
962
966
  if (learningRepo && runtime.visible(learningRepo)) {
963
967
  try {
@@ -968,17 +972,17 @@ export function createTaskViews(runtime) {
968
972
  const test = skillTestResult(runtime.store, run.id, who.name);
969
973
  if (test) {
970
974
  skillTest = true;
971
- learning = skillTestFeedbackHtml(test, who.via === 'cookie' ? who.session.csrf : '', who.role === 'approver') + learning;
975
+ learning = html `${skillTestFeedbackHtml(test, who.via === 'cookie' ? who.session.csrf : '', who.role === 'approver')}${learning}`;
972
976
  }
973
977
  }
974
978
  catch {
975
- learning = '<p role="alert">The saved skill test could not be verified.</p>' + learning;
979
+ learning = html `<p role="alert">The saved skill test could not be verified.</p>${learning}`;
976
980
  }
977
981
  try {
978
- learning = skillsSnapshotHtml(readSkillsSnapshot(runtime.store, run.id)) + knowledgeContextHtml(readKnowledgeSnapshot(runtime.store, run.id)) + learning;
982
+ learning = html `${skillsSnapshotHtml(readSkillsSnapshot(runtime.store, run.id))}${knowledgeContextHtml(readKnowledgeSnapshot(runtime.store, run.id))}${learning}`;
979
983
  }
980
984
  catch {
981
- learning = '<p class="problem" role="alert">The context saved for this run could not be verified.</p>' + learning;
985
+ learning = html `<p class="problem" role="alert">The context saved for this run could not be verified.</p>${learning}`;
982
986
  }
983
987
  }
984
988
  return {
@@ -986,7 +990,7 @@ export function createTaskViews(runtime) {
986
990
  skillTest,
987
991
  taskId,
988
992
  rootId: runtime.familyOf(taskId)?.root.id ?? taskId,
989
- history: (() => { const family = runtime.familyOf(taskId); return family === null ? "" : familyHistory(family); })(),
993
+ ...(() => { const family = runtime.familyOf(taskId); return family === null ? {} : { history: familyHistory(family) }; })(),
990
994
  run,
991
995
  receipt,
992
996
  assignment: (() => {
@@ -1,21 +1,21 @@
1
- import type { Registration } from './handler-registry.js';
1
+ /** tasks handlers, moved without changing their route bodies. */
2
+ import { type Html } from "../html.js";
2
3
  import { type ServerResponse } from "node:http";
3
4
  import { type Artifact, type Run, type Store } from "../store.js";
4
- import type { HandlerContext } from './handler-context.js';
5
5
  import type { ServerRuntime } from './runtime.js';
6
- import { type CompletedWorkRow, type PeekAdmission, type RankedReviewRow, type ReviewCockpitView, type Who } from "./shared.js";
6
+ import { type PeekAdmission } from "./render-pages.js";
7
+ import { type CompletedWorkRow, type RankedReviewRow, type ReviewCockpitView } from "./render-results.js";
8
+ import { type Who } from "./session.js";
7
9
  export declare function createTasksHandlers(runtime: ServerRuntime): {
8
- registrations: Registration[];
9
- get: (ctx: HandlerContext) => Promise<void>;
10
- post: (ctx: HandlerContext) => Promise<void>;
11
- runListPane: (project: string | null, currentId: number | null) => string;
10
+ registrations: import("./handler-registry.js").Registration[];
11
+ runListPane: (project: string | null, currentId: number | null) => Html;
12
12
  peekFragment: (runId: number, sessionKey: string, editorMode?: boolean) => Promise<{
13
13
  status: number;
14
- body: string;
14
+ body: Html;
15
15
  retryAfter?: number;
16
16
  }>;
17
17
  taskMutation: (response: ServerResponse, who: Who, taskId: string, verb: string, posted: URLSearchParams, now: Date) => void;
18
- queueRegionFor: (project: string | null, csrf: string, revision: number, now: Date) => string;
18
+ queueRegionFor: (project: string | null, csrf: string, revision: number, now: Date) => Html;
19
19
  ciFailingFor: (runId: number | null, prNumber: number | null) => boolean;
20
20
  completedRowFor: (taskId: string, project: string | null) => CompletedWorkRow | null;
21
21
  attemptRowFor: (taskId: string, runId: number | null, project: string | null) => CompletedWorkRow | null;