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
@@ -4,10 +4,12 @@ export const WORKSPACE_REVISION_KEY = 'workspace-content:v1';
4
4
  const KEY = WORKSPACE_REVISION_KEY;
5
5
  const MAX_AGE_MS = 60_000;
6
6
  const OMIT = new Set(['schema_version', 'service_cursor', 'wake', 'notification_delivery', 'sqlite_sequence',
7
- 'team_read', 'team_request', 'push_delivery', 'telegram_update', 'telegram_outbound_message', 'telegram_retry', 'bridge_lease']);
7
+ 'team_read', 'team_request', 'push_delivery', 'chat_message_ref']);
8
8
  const QUIET = {
9
9
  runner: ['heartbeat_at'], claim: ['heartbeat_at', 'expires_at'], watch_lease: ['heartbeat_at', 'expires_at'],
10
10
  watch_episode: ['ticks'], provider_readiness: ['observed_at'],
11
+ // A chat worker's lease, poll cursor and rate-limit wait are its own bookkeeping; its connection and problem are news.
12
+ chat_runtime: ['owner', 'lease_until', 'generation', 'cursor', 'heartbeat', 'retry_at'],
11
13
  };
12
14
  /** A quiet beat that revives what a view already rendered as gone: the rows a beat may move, read before and after.
13
15
  * A runner beat after its liveness window (or backwards) is a revival; a lease renewed at or past its expiry is one. */
@@ -22,6 +22,7 @@ export { ACCEPT_NEEDS_REASON, cantAcceptYetOf, evidenceProblemOf, type EvidenceP
22
22
  import { type ProofVerdict } from "./proof.js";
23
23
  import type { ReviewRetryState, TaskState } from "./store.js";
24
24
  import type { TaskControlView } from "./task-control.js";
25
+ import { type Html } from "./html.js";
25
26
  /** The Work destination's views — shortcuts over the same rows, never a
26
27
  * persisted state. All is the default. */
27
28
  export type WorkView = "all" | "needs-you" | "running" | "completed";
@@ -273,8 +274,9 @@ export declare function compareWorkRows(a: {
273
274
  * lives under. */
274
275
  export type PrimaryDestination = "chat" | "work" | "projects" | "flows" | "settings" | null;
275
276
  export declare function primaryDestinationOf(active: string): PrimaryDestination;
276
- /** Learning stays in Settings and a useful, closed result disclosure. */
277
- export declare function learningHtml(view: import('./project-learning.js').LearningView, csrf: string, canManage: boolean, source?: number): string;
277
+ /** Learning stays in Settings and a useful, closed result disclosure. `csrf` gates the management forms (a cookie
278
+ * session has one); postForm adds the request's own CSRF field. */
279
+ export declare function learningHtml(view: import('./project-learning.js').LearningView, csrf: string, canManage: boolean, source?: number): Html;
278
280
  /** The first signed requirement a finished attempt missed (failed or unanswered; a person's own check is not a miss),
279
281
  * with the evidence line behind it in plain words. Null when every requirement held. */
280
282
  export declare function missedRequirementOf(matrix: readonly {
@@ -21,6 +21,7 @@ export { ACCEPT_NEEDS_REASON, cantAcceptYetOf, evidenceProblemOf };
21
21
  import { GOAL_ASSESSMENT_PENDING, manualReviewOnly, plainReasonWords } from "./proof.js";
22
22
  import { OPEN_RESULT, plainReasonOf, stageOfCode, taskStatusOf, workToneOf } from "./task-status.js";
23
23
  import { whenUtc } from "./when-html.js";
24
+ import { html, postForm } from "./html.js";
24
25
  export const WORK_VIEWS = [
25
26
  { key: "all", label: "All", hint: "Every task in view, most urgent first.", empty: "Nothing is in progress. Describe work in chat or add a task, and it appears here." },
26
27
  { key: "needs-you", label: "Needs you", hint: "Tasks waiting on an answer, approval, or your inspection.", empty: "Nothing needs you right now. Queued and running work continues on its own." },
@@ -521,19 +522,18 @@ export function primaryDestinationOf(active) {
521
522
  return "settings";
522
523
  return null;
523
524
  }
524
- /** Learning stays in Settings and a useful, closed result disclosure. */
525
+ /** Learning stays in Settings and a useful, closed result disclosure. `csrf` gates the management forms (a cookie
526
+ * session has one); postForm adds the request's own CSRF field. */
525
527
  export function learningHtml(view, csrf, canManage, source) {
526
- const e = (x) => String(x).replace(/[&<>"']/g, c => ({ '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#39;' })[c]);
527
- const fields = (values) => Object.entries(values).map(([k, v]) => `<input type="hidden" name="${e(k)}" value="${e(v)}">`).join('');
528
- const base = { csrf, repo: view.repo, identity: view.identity, revision: view.revision };
529
- const act = (action, label, lesson) => canManage && csrf ? `<form method="post" action="/settings/learning/change">${fields({ ...base, action, ...(lesson ? { lesson: lesson.id, version: lesson.version, sha: lesson.sha } : {}) })}<button type="submit">${label}</button></form>` : '';
530
- const evidence = (list, run) => list.map(one => `<li><a href="/r/${one.runId ?? run}/evidence/${one.artifactId}">Source #${one.artifactId}</a><blockquote>${e(one.excerpt)}</blockquote><code>${e(one.sha256)}</code></li>`).join('');
528
+ const base = { repo: view.repo, identity: view.identity, revision: view.revision };
529
+ const act = (action, label, lesson) => canManage && csrf ? postForm('/settings/learning/change', html `<button type="submit">${label}</button>`, { hidden: { ...base, action, ...(lesson ? { lesson: lesson.id, version: lesson.version, sha: lesson.sha } : {}) } }) : '';
530
+ const evidence = (list, run) => list.map(one => html `<li><a href="/r/${String(one.runId ?? run)}/evidence/${one.artifactId}">Source #${one.artifactId}</a><blockquote>${one.excerpt}</blockquote><code>${one.sha256}</code></li>`);
531
531
  const lessons = view.lessons.filter(l => source === undefined || l.source === source);
532
- const cards = lessons.map(l => `<article class="card" data-lesson="${l.id}"><p><strong>${e(l.payload.observation)}</strong></p><p>${e(l.payload.action)}</p><p class="meta">${l.payload.kind === 'system' ? 'System suggestion · No change applied' : e(l.status === 'adopted' ? 'Adopted advice' : l.status === 'disabled' ? 'Disabled' : 'Proposed lesson')}</p><details><summary>Source and use</summary><p><a href="/r/${l.source}">Result #${l.source}</a> · <a href="/r/${l.reviewer}">Review #${l.reviewer}</a></p><p>${e(l.payload.paths.join(', '))} · ${e(l.payload.phases.join(', '))} · ${e({ darwin: "macOS", win32: "Windows", linux: "Linux" }[l.payload.platform] ?? l.payload.platform)}</p><ul>${evidence(l.payload.evidence, l.source)}</ul>${l.payload.kind !== 'project' ? '' : `<p class="meta">${l.status === 'proposed' ? 'Save permits advisory reuse when enabled and applicable. It does not prove a remedy works.' : 'Disabling affects future runs. Active snapshots, code and approvals stay unchanged.'}</p>${l.status === 'proposed' ? act('adopt', 'Save lesson', l) : ''}`}</details>${l.payload.kind === 'project' && l.status === 'adopted' ? act('disable', 'Disable lesson', l) : ''}</article>`).join('');
532
+ const cards = lessons.map(l => html `<article class="card" data-lesson="${l.id}"><p><strong>${l.payload.observation}</strong></p><p>${l.payload.action}</p><p class="meta">${l.payload.kind === 'system' ? 'System suggestion · No change applied' : l.status === 'adopted' ? 'Adopted advice' : l.status === 'disabled' ? 'Disabled' : 'Proposed lesson'}</p><details><summary>Source and use</summary><p><a href="/r/${l.source}">Result #${l.source}</a> · <a href="/r/${l.reviewer}">Review #${l.reviewer}</a></p><p>${l.payload.paths.join(', ')} · ${l.payload.phases.join(', ')} · ${{ darwin: "macOS", win32: "Windows", linux: "Linux" }[l.payload.platform] ?? l.payload.platform}</p><ul>${evidence(l.payload.evidence, l.source)}</ul>${l.payload.kind !== 'project' ? '' : html `<p class="meta">${l.status === 'proposed' ? 'Save permits advisory reuse when enabled and applicable. It does not prove a remedy works.' : 'Disabling affects future runs. Active snapshots, code and approvals stay unchanged.'}</p>${l.status === 'proposed' ? act('adopt', 'Save lesson', l) : ''}`}</details>${l.payload.kind === 'project' && l.status === 'adopted' ? act('disable', 'Disable lesson', l) : ''}</article>`);
533
533
  if (source !== undefined)
534
- return lessons.length ? `<details class="learning result-learning"><summary>Learned from this task</summary>${cards}<a href="/settings/learning?repo=${encodeURIComponent(view.repo)}">Learning settings</a></details>` : '';
535
- const history = view.events.map(ev => `<article class="card" data-learning-event="${e(ev.action)}"><p><strong>${e({ assessment: { propose: 'Learning suggested', none: 'No lesson needed', unassessed: 'Learning not assessed', invalid: 'Learning assessment invalid' }[ev.after] ?? 'Learning not assessed', proposal: 'Suggestion recorded', adopt: 'Lesson adopted', disable: 'Lesson disabled', reset: 'Learning reset', enable: 'Reuse enabled', pause: 'Reuse paused', reuse: 'Run context saved', failure: 'Learning issue', capture: 'Capture finished' }[ev.action] ?? ev.action)}</strong>${ev.action === "reuse" ? ` · ${e(ev.after)}` : ""}</p><p class="meta">${whenUtc(ev.at)} · ${e(ev.actor)}${ev.run === null ? '' : ` · <a href="/r/${ev.run}">Run #${ev.run}</a>${ev.outcome === null ? "" : ` · ${e(ev.outcome)}`}`}</p><details><summary>Details</summary><p>${e(ev.before)} → ${e(ev.after)}</p><p>${e(ev.reason)}</p>${ev.lesson === null ? '' : `<p>Lesson #${ev.lesson}</p>`}<ul>${evidence(ev.evidence, ev.run)}</ul>${ev.snapshot === null ? "" : `<details><summary>Exact context</summary><pre>${e(ev.snapshot)}</pre></details>`}</details></article>`).join('');
536
- return `<section class="learning">${view.damaged ? '<p class="problem" role="alert">Some lessons no longer verify and are excluded from reuse.</p>' : ''}<p>${view.enabled ? 'Use adopted lessons: on' : 'Use adopted lessons: off'}</p>${act(view.enabled ? 'pause' : 'enable', view.enabled ? 'Pause reuse' : 'Enable reuse')}${cards || '<p>No lessons yet. Reviews may suggest useful advice here.</p>'}<details><summary>Reset learning</summary><p>Disable all adopted lessons and future reuse. Keep history, code, approvals and active run snapshots.</p>${act('reset', 'Reset learning')}</details><h2>Changes</h2>${history || '<p>No learning changes yet.</p>'}${view.next === null ? '' : `<a class="button-link" href="/settings/learning?repo=${encodeURIComponent(view.repo)}&before=${view.next}">Older changes</a>`}</section>`;
534
+ return lessons.length ? html `<details class="learning result-learning"><summary>Learned from this task</summary>${cards}<a href="/settings/learning?repo=${encodeURIComponent(view.repo)}">Learning settings</a></details>` : html ``;
535
+ const history = view.events.map(ev => html `<article class="card" data-learning-event="${ev.action}"><p><strong>${{ assessment: { propose: 'Learning suggested', none: 'No lesson needed', unassessed: 'Learning not assessed', invalid: 'Learning assessment invalid' }[ev.after] ?? 'Learning not assessed', proposal: 'Suggestion recorded', adopt: 'Lesson adopted', disable: 'Lesson disabled', reset: 'Learning reset', enable: 'Reuse enabled', pause: 'Reuse paused', reuse: 'Run context saved', failure: 'Learning issue', capture: 'Capture finished' }[ev.action] ?? ev.action}</strong>${ev.action === "reuse" ? ` · ${ev.after}` : ""}</p><p class="meta">${whenUtc(ev.at)} · ${ev.actor}${ev.run === null ? '' : html ` · <a href="/r/${ev.run}">Run #${ev.run}</a>${ev.outcome === null ? "" : ` · ${ev.outcome}`}`}</p><details><summary>Details</summary><p>${ev.before} → ${ev.after}</p><p>${ev.reason}</p>${ev.lesson === null ? '' : html `<p>Lesson #${ev.lesson}</p>`}<ul>${evidence(ev.evidence, ev.run)}</ul>${ev.snapshot === null ? "" : html `<details><summary>Exact context</summary><pre>${ev.snapshot}</pre></details>`}</details></article>`);
536
+ return html `<section class="learning">${view.damaged ? html `<p class="problem" role="alert">Some lessons no longer verify and are excluded from reuse.</p>` : ''}<p>${view.enabled ? 'Use adopted lessons: on' : 'Use adopted lessons: off'}</p>${act(view.enabled ? 'pause' : 'enable', view.enabled ? 'Pause reuse' : 'Enable reuse')}${cards.length ? cards : html `<p>No lessons yet. Reviews may suggest useful advice here.</p>`}<details><summary>Reset learning</summary><p>Disable all adopted lessons and future reuse. Keep history, code, approvals and active run snapshots.</p>${act('reset', 'Reset learning')}</details><h2>Changes</h2>${history.length ? history : html `<p>No learning changes yet.</p>`}${view.next === null ? '' : html `<a class="button-link" href="/settings/learning?repo=${encodeURIComponent(view.repo)}&before=${view.next}">Older changes</a>`}</section>`;
537
537
  }
538
538
  /** The first signed requirement a finished attempt missed (failed or unanswered; a person's own check is not a miss),
539
539
  * with the evidence line behind it in plain words. Null when every requirement held. */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "toolroll",
3
- "version": "0.9.53",
3
+ "version": "0.9.55",
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"