toolroll 0.9.54 → 0.9.56

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 (350) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/README.md +29 -12
  3. package/dist/action-ledger.d.ts +2 -4
  4. package/dist/action-ledger.js +2 -10
  5. package/dist/agent-onboard.js +4 -1
  6. package/dist/approval-policy.d.ts +5 -5
  7. package/dist/approval-policy.js +4 -4
  8. package/dist/approval-rules-ui.d.ts +3 -2
  9. package/dist/approval-rules-ui.js +17 -22
  10. package/dist/assignment-ui.d.ts +3 -2
  11. package/dist/assignment-ui.js +4 -11
  12. package/dist/backup-ui.d.ts +2 -1
  13. package/dist/backup-ui.js +16 -27
  14. package/dist/brand-mark.d.ts +3 -2
  15. package/dist/brand-mark.js +4 -4
  16. package/dist/browser/workspace.css +1 -1
  17. package/dist/browser/workspace.js +25 -25
  18. package/dist/browser-shell.d.ts +2 -1
  19. package/dist/browser-shell.js +9 -9
  20. package/dist/browser-workspace.d.ts +14 -15
  21. package/dist/browser-workspace.js +0 -3
  22. package/dist/budget-alerts.js +3 -3
  23. package/dist/chat-actions.d.ts +23 -18
  24. package/dist/chat-actions.js +110 -88
  25. package/dist/chat-ask.d.ts +2 -2
  26. package/dist/chat-ask.js +5 -5
  27. package/dist/chat-channel.d.ts +15 -15
  28. package/dist/chat-channel.js +20 -20
  29. package/dist/chat-controls.d.ts +0 -4
  30. package/dist/chat-controls.js +0 -1
  31. package/dist/chat-core.js +1 -1
  32. package/dist/chat-delivery-state.js +2 -2
  33. package/dist/chat-delivery.d.ts +2 -2
  34. package/dist/chat-delivery.js +27 -34
  35. package/dist/chat-flow.js +3 -3
  36. package/dist/chat-messages.d.ts +1 -1
  37. package/dist/chat-messages.js +4 -4
  38. package/dist/chat-migration.d.ts +1 -1
  39. package/dist/chat-migration.js +11 -11
  40. package/dist/chat-polish.d.ts +5 -4
  41. package/dist/chat-polish.js +9 -10
  42. package/dist/chat-rooms.js +3 -3
  43. package/dist/chat-warmth.d.ts +2 -2
  44. package/dist/check-levels-ui.d.ts +2 -1
  45. package/dist/check-levels-ui.js +26 -53
  46. package/dist/cli.d.ts +3 -1
  47. package/dist/cli.js +15 -10
  48. package/dist/coding-shipping-ui.d.ts +2 -1
  49. package/dist/coding-shipping-ui.js +6 -6
  50. package/dist/coding-ui.d.ts +3 -1
  51. package/dist/coding-ui.js +30 -29
  52. package/dist/contracts/chat-actions.d.ts +32 -27
  53. package/dist/contracts/chat-actions.js +29 -11
  54. package/dist/contracts/chat-content.d.ts +1 -1
  55. package/dist/contracts/chat-content.js +1 -1
  56. package/dist/contracts/chat-tables.js +4 -4
  57. package/dist/contracts/cli.d.ts +1 -3
  58. package/dist/contracts/console-api.d.ts +7 -7
  59. package/dist/contracts/console-api.js +13 -12
  60. package/dist/contracts/flow-propose.d.ts +3 -3
  61. package/dist/contracts/flow.d.ts +132 -125
  62. package/dist/contracts/flow.js +27 -12
  63. package/dist/contracts/health.d.ts +1 -3
  64. package/dist/contracts/lead-context.d.ts +1 -1
  65. package/dist/contracts/lead-context.js +2 -2
  66. package/dist/contracts/lead-tools.d.ts +20 -18
  67. package/dist/contracts/lead-tools.js +15 -15
  68. package/dist/contracts/stage-output.d.ts +1 -1
  69. package/dist/contracts/stage-output.js +1 -1
  70. package/dist/contracts/store-json.d.ts +23 -22
  71. package/dist/contracts/store-json.js +17 -17
  72. package/dist/contracts/{teammate-turn.d.ts → subagent-turn.d.ts} +5 -5
  73. package/dist/contracts/{teammate-turn.js → subagent-turn.js} +7 -7
  74. package/dist/control-ui.d.ts +5 -4
  75. package/dist/control-ui.js +9 -34
  76. package/dist/converse.d.ts +23 -23
  77. package/dist/converse.js +28 -28
  78. package/dist/coordinator-proposals.d.ts +2 -2
  79. package/dist/coordinator-proposals.js +1 -1
  80. package/dist/coordinator.js +1 -1
  81. package/dist/credentials-ui.d.ts +5 -4
  82. package/dist/credentials-ui.js +23 -24
  83. package/dist/demo-chat.d.ts +3 -3
  84. package/dist/demo-chat.js +29 -76
  85. package/dist/deprecations.d.ts +12 -0
  86. package/dist/deprecations.js +20 -0
  87. package/dist/desktop-update-gate.js +8 -4
  88. package/dist/desktop-update.js +6 -1
  89. package/dist/discord-chat.js +6 -6
  90. package/dist/discord-settings.d.ts +3 -2
  91. package/dist/discord-settings.js +17 -42
  92. package/dist/dispatch.d.ts +1 -1
  93. package/dist/dispatch.js +1 -1
  94. package/dist/envelope.js +10 -1
  95. package/dist/evidence-pack.d.ts +2 -1
  96. package/dist/evidence-pack.js +45 -49
  97. package/dist/export-ui.d.ts +7 -2
  98. package/dist/export-ui.js +4 -10
  99. package/dist/export.js +7 -7
  100. package/dist/flow-engine.d.ts +2 -2
  101. package/dist/flow-engine.js +21 -21
  102. package/dist/flow-gallery-ui.d.ts +4 -3
  103. package/dist/flow-gallery-ui.js +28 -43
  104. package/dist/flow-insights.d.ts +1 -1
  105. package/dist/flow-share.js +13 -8
  106. package/dist/flow-starters-ui.d.ts +2 -1
  107. package/dist/flow-starters-ui.js +12 -15
  108. package/dist/flow-steps.d.ts +5 -5
  109. package/dist/flow-steps.js +19 -19
  110. package/dist/flow-triggers.d.ts +2 -1
  111. package/dist/flow-triggers.js +17 -15
  112. package/dist/flows-cli.js +1 -1
  113. package/dist/flows-ui.d.ts +4 -3
  114. package/dist/flows-ui.js +38 -49
  115. package/dist/flows.js +21 -20
  116. package/dist/guides.js +112 -6
  117. package/dist/html.d.ts +76 -0
  118. package/dist/html.js +173 -0
  119. package/dist/integrations-ui.d.ts +2 -1
  120. package/dist/integrations-ui.js +19 -23
  121. package/dist/invoke.js +1 -1
  122. package/dist/kits-ui.d.ts +5 -4
  123. package/dist/kits-ui.js +22 -24
  124. package/dist/kits.d.ts +12 -12
  125. package/dist/kits.js +31 -31
  126. package/dist/knowledge-ui.d.ts +6 -5
  127. package/dist/knowledge-ui.js +26 -25
  128. package/dist/{mate-cli.d.ts → lead-cli.d.ts} +11 -11
  129. package/dist/{mate-cli.js → lead-cli.js} +38 -38
  130. package/dist/lead-commitments.js +4 -4
  131. package/dist/lead-context.d.ts +12 -2
  132. package/dist/lead-context.js +15 -17
  133. package/dist/{mate-contract.d.ts → lead-contract.d.ts} +3 -3
  134. package/dist/{mate-contract.js → lead-contract.js} +7 -6
  135. package/dist/{mate-doors.d.ts → lead-doors.d.ts} +6 -6
  136. package/dist/{mate-doors.js → lead-doors.js} +24 -24
  137. package/dist/lead-follow.d.ts +5 -5
  138. package/dist/lead-follow.js +9 -9
  139. package/dist/lead-people.d.ts +5 -5
  140. package/dist/lead-people.js +14 -14
  141. package/dist/{mate-progress.d.ts → lead-progress.d.ts} +9 -9
  142. package/dist/{mate-progress.js → lead-progress.js} +3 -3
  143. package/dist/{mate-tools.d.ts → lead-tools.d.ts} +19 -19
  144. package/dist/{mate-tools.js → lead-tools.js} +109 -101
  145. package/dist/{mate.d.ts → lead.d.ts} +27 -27
  146. package/dist/{mate.js → lead.js} +102 -102
  147. package/dist/ledger-view.d.ts +2 -1
  148. package/dist/ledger-view.js +27 -29
  149. package/dist/limits-ui.d.ts +3 -2
  150. package/dist/limits-ui.js +8 -8
  151. package/dist/live-bus.d.ts +50 -8
  152. package/dist/live-bus.js +133 -50
  153. package/dist/mcp-connect.d.ts +1 -1
  154. package/dist/mcp-connect.js +3 -3
  155. package/dist/mcp-core.js +1 -1
  156. package/dist/mcp-oauth.js +35 -36
  157. package/dist/memory-pass.d.ts +2 -2
  158. package/dist/memory-pass.js +7 -7
  159. package/dist/models-ui.d.ts +2 -1
  160. package/dist/models-ui.js +25 -35
  161. package/dist/monitoring-ui.d.ts +4 -3
  162. package/dist/monitoring-ui.js +13 -26
  163. package/dist/notification-rows.d.ts +2 -2
  164. package/dist/openrouter-models.d.ts +2 -1
  165. package/dist/openrouter-models.js +5 -9
  166. package/dist/operate.d.ts +3 -3
  167. package/dist/operate.js +46 -41
  168. package/dist/people-audit-ui.d.ts +2 -1
  169. package/dist/people-audit-ui.js +13 -13
  170. package/dist/policy-ui.d.ts +3 -2
  171. package/dist/policy-ui.js +17 -23
  172. package/dist/policy.d.ts +1 -1
  173. package/dist/principal.d.ts +1 -1
  174. package/dist/principal.js +2 -2
  175. package/dist/project-delete-ui.d.ts +4 -3
  176. package/dist/project-delete-ui.js +16 -28
  177. package/dist/project-delete.d.ts +1 -1
  178. package/dist/project-delete.js +26 -26
  179. package/dist/project-memory.js +1 -1
  180. package/dist/project-tools.d.ts +1 -1
  181. package/dist/project-tools.js +1 -1
  182. package/dist/pull-request-ui.d.ts +2 -1
  183. package/dist/pull-request-ui.js +17 -32
  184. package/dist/recipe-ui.d.ts +8 -7
  185. package/dist/recipe-ui.js +39 -32
  186. package/dist/release-adapters.d.ts +60 -0
  187. package/dist/release-adapters.js +435 -0
  188. package/dist/release-cli.d.ts +24 -0
  189. package/dist/release-cli.js +181 -0
  190. package/dist/release-gate.d.ts +80 -0
  191. package/dist/release-gate.js +150 -0
  192. package/dist/release-links.d.ts +29 -0
  193. package/dist/release-links.js +102 -0
  194. package/dist/release.d.ts +331 -0
  195. package/dist/release.js +550 -0
  196. package/dist/reply-shape.d.ts +2 -1
  197. package/dist/reply-shape.js +5 -5
  198. package/dist/repository-context-ui.d.ts +2 -1
  199. package/dist/repository-context-ui.js +2 -7
  200. package/dist/request-budget-ui.d.ts +2 -1
  201. package/dist/request-budget-ui.js +16 -16
  202. package/dist/result-review.d.ts +2 -3
  203. package/dist/result-review.js +3 -9
  204. package/dist/retention-ui.d.ts +7 -1
  205. package/dist/retention-ui.js +7 -11
  206. package/dist/retention.js +4 -4
  207. package/dist/scope.d.ts +2 -2
  208. package/dist/scout-report.d.ts +1 -1
  209. package/dist/scout-report.js +1 -1
  210. package/dist/serve.d.ts +11 -2
  211. package/dist/serve.js +105 -99
  212. package/dist/server/chat.d.ts +7 -10
  213. package/dist/server/chat.js +984 -1021
  214. package/dist/server/chrome.d.ts +291 -0
  215. package/dist/server/chrome.js +747 -0
  216. package/dist/server/console.css +2819 -0
  217. package/dist/server/flows.d.ts +2 -6
  218. package/dist/server/flows.js +854 -773
  219. package/dist/server/guards.d.ts +1 -1
  220. package/dist/server/guards.js +8 -5
  221. package/dist/server/handler-context.d.ts +1 -1
  222. package/dist/server/handler-context.js +1 -1
  223. package/dist/server/handler-registry.d.ts +8 -6
  224. package/dist/server/handler-registry.js +14 -2
  225. package/dist/server/http.d.ts +274 -0
  226. package/dist/server/http.js +239 -0
  227. package/dist/server/live.d.ts +34 -0
  228. package/dist/server/live.js +309 -0
  229. package/dist/server/pages.d.ts +2 -6
  230. package/dist/server/pages.js +808 -789
  231. package/dist/server/people-tokens.d.ts +1 -6
  232. package/dist/server/people-tokens.js +581 -573
  233. package/dist/server/remote.d.ts +4 -7
  234. package/dist/server/remote.js +39 -70
  235. package/dist/server/render-chat.d.ts +402 -0
  236. package/dist/server/render-chat.js +927 -0
  237. package/dist/server/render-pages.d.ts +535 -0
  238. package/dist/server/render-pages.js +1277 -0
  239. package/dist/server/render-people.d.ts +32 -0
  240. package/dist/server/render-people.js +121 -0
  241. package/dist/server/render-results.d.ts +744 -0
  242. package/dist/server/render-results.js +2237 -0
  243. package/dist/server/render-settings.d.ts +154 -0
  244. package/dist/server/render-settings.js +580 -0
  245. package/dist/server/render-tasks.d.ts +632 -0
  246. package/dist/server/render-tasks.js +2345 -0
  247. package/dist/server/request-context.d.ts +46 -0
  248. package/dist/server/request-context.js +17 -0
  249. package/dist/server/route-table.d.ts +25 -3
  250. package/dist/server/route-table.js +167 -77
  251. package/dist/server/runtime.d.ts +28 -20
  252. package/dist/server/runtime.js +7 -1
  253. package/dist/server/session.d.ts +138 -0
  254. package/dist/server/session.js +94 -0
  255. package/dist/server/settings.d.ts +1 -5
  256. package/dist/server/settings.js +2186 -2121
  257. package/dist/server/task-views.d.ts +11 -4
  258. package/dist/server/task-views.js +26 -22
  259. package/dist/server/tasks.d.ts +9 -9
  260. package/dist/server/tasks.js +1489 -1420
  261. package/dist/server-telemetry.d.ts +4 -3
  262. package/dist/server-telemetry.js +4 -8
  263. package/dist/setup-guide.d.ts +2 -2
  264. package/dist/skills-ui.d.ts +4 -3
  265. package/dist/skills-ui.js +14 -17
  266. package/dist/skills.d.ts +1 -1
  267. package/dist/skills.js +2 -1
  268. package/dist/slack-chat.d.ts +2 -2
  269. package/dist/slack-chat.js +6 -6
  270. package/dist/slack-settings.d.ts +3 -2
  271. package/dist/slack-settings.js +17 -42
  272. package/dist/spend-ui.d.ts +5 -4
  273. package/dist/spend-ui.js +17 -40
  274. package/dist/spend.d.ts +14 -14
  275. package/dist/spend.js +31 -31
  276. package/dist/sso-ui.d.ts +3 -2
  277. package/dist/sso-ui.js +26 -27
  278. package/dist/storage-ui.d.ts +2 -1
  279. package/dist/storage-ui.js +14 -33
  280. package/dist/store-baseline.d.ts +19 -0
  281. package/dist/store-baseline.js +2873 -0
  282. package/dist/store.d.ts +197 -249
  283. package/dist/store.js +747 -3084
  284. package/dist/subagent-admin.d.ts +53 -0
  285. package/dist/{teammate-admin.js → subagent-admin.js} +37 -37
  286. package/dist/{teammate-desk.d.ts → subagent-desk.d.ts} +22 -23
  287. package/dist/{teammate-desk.js → subagent-desk.js} +26 -35
  288. package/dist/{teammate-memory.d.ts → subagent-memory.d.ts} +17 -17
  289. package/dist/{teammate-memory.js → subagent-memory.js} +41 -41
  290. package/dist/{teammate-question.d.ts → subagent-question.d.ts} +6 -6
  291. package/dist/{teammate-question.js → subagent-question.js} +17 -17
  292. package/dist/{teammate-tools.d.ts → subagent-tools.d.ts} +18 -18
  293. package/dist/{teammate-tools.js → subagent-tools.js} +36 -36
  294. package/dist/{teammate-week.d.ts → subagent-week.d.ts} +10 -10
  295. package/dist/{teammate-week.js → subagent-week.js} +23 -23
  296. package/dist/{teammate-work.d.ts → subagent-work.d.ts} +21 -21
  297. package/dist/{teammate-work.js → subagent-work.js} +50 -50
  298. package/dist/subagents-ui.d.ts +22 -0
  299. package/dist/subagents-ui.js +137 -0
  300. package/dist/{teammates.d.ts → subagents.d.ts} +11 -11
  301. package/dist/{teammates.js → subagents.js} +21 -21
  302. package/dist/subscription-chat.d.ts +13 -13
  303. package/dist/subscription-chat.js +19 -19
  304. package/dist/surface.d.ts +19 -2
  305. package/dist/surface.js +20 -33
  306. package/dist/task-composer.d.ts +2 -1
  307. package/dist/task-composer.js +7 -7
  308. package/dist/task-status.d.ts +4 -3
  309. package/dist/task-status.js +15 -16
  310. package/dist/team-cli.d.ts +1 -0
  311. package/dist/team-cli.js +14 -2
  312. package/dist/team-http.d.ts +5 -9
  313. package/dist/team-http.js +5 -63
  314. package/dist/team-leads.js +13 -13
  315. package/dist/team-runtime.d.ts +2 -2
  316. package/dist/team-runtime.js +8 -8
  317. package/dist/team-ui.d.ts +2 -1
  318. package/dist/team-ui.js +2 -5
  319. package/dist/teams-chat.js +6 -6
  320. package/dist/teams-settings.d.ts +3 -2
  321. package/dist/teams-settings.js +20 -31
  322. package/dist/telegram-flow.d.ts +3 -3
  323. package/dist/telegram-flow.js +3 -3
  324. package/dist/{telegram-mate.d.ts → telegram-lead.d.ts} +5 -5
  325. package/dist/{telegram-mate.js → telegram-lead.js} +27 -27
  326. package/dist/telegram-settings.d.ts +3 -2
  327. package/dist/telegram-settings.js +14 -25
  328. package/dist/telegram-status.js +1 -1
  329. package/dist/telegram-team.d.ts +1 -1
  330. package/dist/telegram-team.js +5 -5
  331. package/dist/telegram.d.ts +1 -1
  332. package/dist/telegram.js +9 -30
  333. package/dist/text-limits.d.ts +18 -18
  334. package/dist/text-limits.js +18 -18
  335. package/dist/toolroll-update-ui.d.ts +3 -2
  336. package/dist/toolroll-update-ui.js +35 -39
  337. package/dist/toolroll-update.d.ts +8 -0
  338. package/dist/toolroll-update.js +45 -8
  339. package/dist/tools-ui.d.ts +5 -2
  340. package/dist/tools-ui.js +31 -31
  341. package/dist/when-html.d.ts +11 -3
  342. package/dist/when-html.js +5 -6
  343. package/dist/workspace-ui.d.ts +4 -2
  344. package/dist/workspace-ui.js +10 -10
  345. package/package.json +1 -2
  346. package/dist/server/shared.d.ts +0 -3151
  347. package/dist/server/shared.js +0 -12001
  348. package/dist/teammate-admin.d.ts +0 -53
  349. package/dist/teammates-ui.d.ts +0 -20
  350. package/dist/teammates-ui.js +0 -166
@@ -1,14 +1,13 @@
1
- import type { Registration } from './handler-registry.js';
2
1
  /** tasks handlers, moved without changing their route bodies. */
3
- import { type IncomingMessage, type ServerResponse } from "node:http";
2
+ import { type IncomingMessage } from "node:http";
4
3
  import { CodingWorkspace } from '../coding-workspace.js';
5
4
  import { type Principal } from "../operate-remote.js";
6
5
  import { RequestBudget, SourceAdmission, type Admission } from "../request-budget.js";
7
6
  import { type Store } from "../store.js";
8
7
  import type { TeamResponse } from '../team-contract.js';
9
- import type { EdgeContext } from './handler-context.js';
10
8
  import { type RemoteHookContext } from "./remote-hooks.js";
11
- import { type ServeOptions, type Who } from "./shared.js";
9
+ import { type ServeOptions } from "./http.js";
10
+ import { type Who } from "./session.js";
12
11
  export interface RemoteRuntime {
13
12
  identify: (request: IncomingMessage, touch?: boolean, limited?: boolean, refusedToken?: {
14
13
  principal?: Principal;
@@ -32,7 +31,6 @@ export interface RemoteRuntime {
32
31
  name: string;
33
32
  generation: number;
34
33
  }, csrf: string) => TeamResponse;
35
- teamStreams: Set<ServerResponse<IncomingMessage>>;
36
34
  requestBudget: RequestBudget;
37
35
  options: ServeOptions;
38
36
  coding: CodingWorkspace | null;
@@ -54,6 +52,5 @@ export interface RemoteRuntime {
54
52
  teamsTenantBudget: SourceAdmission;
55
53
  }
56
54
  export declare function createRemoteHandlers(runtime: RemoteRuntime): {
57
- registrations: Registration[];
58
- edge: (ctx: EdgeContext) => Promise<void>;
55
+ registrations: import("./handler-registry.js").Registration[];
59
56
  };
@@ -1,3 +1,4 @@
1
+ import { handlersOf } from './handler-registry.js';
1
2
  /** tasks handlers, moved without changing their route bodies. */
2
3
  import {} from "node:http";
3
4
  import { handleCliHttp } from '../cli-http.js';
@@ -13,9 +14,10 @@ import {} from "../store.js";
13
14
  import { handleTeamHttp, TEAM_PASSWORD_REVERIFY_MS } from '../team-http.js';
14
15
  import { handleTeamsHttp } from "../teams.js";
15
16
  import { flowHook, telegramHook } from "./remote-hooks.js";
16
- import { respond } from "./shared.js";
17
+ import { respond } from "./http.js";
18
+ import {} from "./session.js";
17
19
  export function createRemoteHandlers(runtime) {
18
- const { identify, store, admitPasswordSource, admitBearer, allowedHost, team, teamBrowserReply, teamStreams, requestBudget, options, coding, codingProjects, liveCeiling, clock, evidenceRoot, consoleOrigin, managedRepos, joinSourceOf, ssoSettings, SSO_FRESH_MS, oauthTokenBudget, hookContext, teamsSourceBudget, teamsTenantBudget } = runtime;
20
+ const { identify, store, admitPasswordSource, admitBearer, allowedHost, team, teamBrowserReply, requestBudget, options, coding, codingProjects, liveCeiling, clock, evidenceRoot, consoleOrigin, managedRepos, joinSourceOf, ssoSettings, SSO_FRESH_MS, oauthTokenBudget, hookContext, teamsSourceBudget, teamsTenantBudget } = runtime;
19
21
  /**
20
22
  * The full principal a live `so_` API token stands for: its person and their generation, the token's own read/act
21
23
  * scope, its project limit narrowed by the person's current access, and its id. Every route that accepts an API token
@@ -93,7 +95,7 @@ export function createRemoteHandlers(runtime) {
93
95
  return reply;
94
96
  const who = identify(request, false);
95
97
  return who?.via === 'cookie' ? teamBrowserReply(reply, actor, who.session.csrf) : reply;
96
- }, cursor: team.cursor, streams: teamStreams,
98
+ },
97
99
  });
98
100
  // Remote CLI: one live API token names the person; the shared command boundary decides everything else.
99
101
  const cliEndpoint = (request, response) => handleCliHttp(request, response, {
@@ -130,71 +132,38 @@ export function createRemoteHandlers(runtime) {
130
132
  projectsFor: account => store.knownRepos().filter(repo => store.accountCanAccess(account, repo)).sort(),
131
133
  admitToken: request => oauthTokenBudget.admit(joinSourceOf(request)),
132
134
  });
133
- async function edge(ctx) {
134
- const { request, response, url, route } = ctx;
135
- switch (route.id) {
136
- case 'edge.telegram-hook': return telegramHook(hookContext, request, response);
137
- case 'edge.flow-hook':
138
- case 'edge.flow-form':
139
- case 'edge.flow-form-send': return flowHook(hookContext, request, response, url);
140
- case 'edge.mcp': return mcpHttp(request, response);
141
- case 'edge.oauth-discovery':
142
- case 'edge.oauth-register':
143
- case 'edge.oauth-token':
144
- case 'edge.oauth-authorize':
145
- case 'edge.oauth-consent':
146
- await oauthHttp(request, response, url);
147
- return;
148
- case 'edge.sessions-list':
149
- case 'edge.sessions-show':
150
- case 'edge.sessions-changes':
151
- case 'edge.sessions-start':
152
- case 'edge.sessions-send':
153
- case 'edge.sessions-stop':
154
- case 'edge.sessions-resume':
155
- case 'edge.sessions-recover':
156
- await sessionEndpoint(request, response);
157
- return;
158
- case 'edge.team-read':
159
- case 'edge.team-send':
160
- case 'edge.team-events':
161
- await teamEndpoint(request, response);
162
- return;
163
- case 'edge.cli':
164
- await cliEndpoint(request, response);
165
- return;
166
- case 'edge.teams':
167
- if (options.configDir !== undefined && await handleTeamsHttp(request, response, { store, dir: options.configDir, ...(options.teamsFetcher ? { fetcher: options.teamsFetcher } : {}), clock,
168
- admitSource: request => teamsSourceBudget.admit(joinSourceOf(request)), admitTenant: tenant => teamsTenantBudget.admit(tenant) }))
169
- return;
170
- return respond(response, 404, 'text/plain; charset=utf-8', 'No such address.');
171
- }
172
- throw new Error('Unregistered remote route');
173
- }
174
- const registrations = [
175
- { id: "edge.telegram-hook", domain: "remote", stage: "edge", method: "POST", handle: edge },
176
- { id: "edge.flow-form", domain: "remote", stage: "edge", method: "GET,HEAD", handle: edge },
177
- { id: "edge.flow-form-send", domain: "remote", stage: "edge", method: "POST", handle: edge },
178
- { id: "edge.flow-hook", domain: "remote", stage: "edge", method: "POST", handle: edge },
179
- { id: "edge.mcp", domain: "remote", stage: "edge", method: "POST", handle: edge },
180
- { id: "edge.oauth-discovery", domain: "remote", stage: "edge", method: "GET,HEAD", handle: edge },
181
- { id: "edge.oauth-register", domain: "remote", stage: "edge", method: "POST", handle: edge },
182
- { id: "edge.oauth-token", domain: "remote", stage: "edge", method: "POST", handle: edge },
183
- { id: "edge.oauth-authorize", domain: "remote", stage: "edge", method: "GET,HEAD", handle: edge },
184
- { id: "edge.oauth-consent", domain: "remote", stage: "edge", method: "POST", handle: edge },
185
- { id: "edge.sessions-list", domain: "remote", stage: "edge", method: "POST", handle: edge },
186
- { id: "edge.sessions-show", domain: "remote", stage: "edge", method: "POST", handle: edge },
187
- { id: "edge.sessions-changes", domain: "remote", stage: "edge", method: "POST", handle: edge },
188
- { id: "edge.sessions-start", domain: "remote", stage: "edge", method: "POST", handle: edge },
189
- { id: "edge.sessions-send", domain: "remote", stage: "edge", method: "POST", handle: edge },
190
- { id: "edge.sessions-stop", domain: "remote", stage: "edge", method: "POST", handle: edge },
191
- { id: "edge.sessions-resume", domain: "remote", stage: "edge", method: "POST", handle: edge },
192
- { id: "edge.sessions-recover", domain: "remote", stage: "edge", method: "POST", handle: edge },
193
- { id: "edge.team-read", domain: "remote", stage: "edge", method: "GET", handle: edge },
194
- { id: "edge.team-send", domain: "remote", stage: "edge", method: "POST", handle: edge },
195
- { id: "edge.team-events", domain: "remote", stage: "edge", method: "GET", handle: edge },
196
- { id: "edge.cli", domain: "remote", stage: "edge", method: "POST", handle: edge },
197
- { id: "edge.teams", domain: "remote", stage: "edge", method: "POST", handle: edge },
198
- ];
199
- return { registrations, edge };
135
+ const teams = async ({ request, response }) => {
136
+ if (options.configDir !== undefined && await handleTeamsHttp(request, response, { store, dir: options.configDir, ...(options.teamsFetcher ? { fetcher: options.teamsFetcher } : {}), clock,
137
+ admitSource: request => teamsSourceBudget.admit(joinSourceOf(request)), admitTenant: tenant => teamsTenantBudget.admit(tenant) }))
138
+ return;
139
+ return respond(response, 404, 'text/plain; charset=utf-8', 'No such address.');
140
+ };
141
+ // D5: native coding sessions and the central team service are deprecated (still served this release); each
142
+ // answer says so in a Deprecation header (RFC 9745).
143
+ // Each protocol adapter keeps its own operation boundary; every row still names its own entry.
144
+ const registrations = handlersOf("remote", {}, {
145
+ "edge.telegram-hook": async ({ request, response }) => { await telegramHook(hookContext, request, response); },
146
+ "edge.flow-form": async ({ request, response, url }) => { await flowHook(hookContext, request, response, url); },
147
+ "edge.flow-form-send": async ({ request, response, url }) => { await flowHook(hookContext, request, response, url); },
148
+ "edge.flow-hook": async ({ request, response, url }) => { await flowHook(hookContext, request, response, url); },
149
+ "edge.mcp": async ({ request, response }) => { await mcpHttp(request, response); },
150
+ "edge.oauth-discovery": async ({ request, response, url }) => { await oauthHttp(request, response, url); },
151
+ "edge.oauth-register": async ({ request, response, url }) => { await oauthHttp(request, response, url); },
152
+ "edge.oauth-token": async ({ request, response, url }) => { await oauthHttp(request, response, url); },
153
+ "edge.oauth-authorize": async ({ request, response, url }) => { await oauthHttp(request, response, url); },
154
+ "edge.oauth-consent": async ({ request, response, url }) => { await oauthHttp(request, response, url); },
155
+ "edge.sessions-list": async ({ request, response }) => { response.setHeader('Deprecation', 'true'); await sessionEndpoint(request, response); },
156
+ "edge.sessions-show": async ({ request, response }) => { response.setHeader('Deprecation', 'true'); await sessionEndpoint(request, response); },
157
+ "edge.sessions-changes": async ({ request, response }) => { response.setHeader('Deprecation', 'true'); await sessionEndpoint(request, response); },
158
+ "edge.sessions-start": async ({ request, response }) => { response.setHeader('Deprecation', 'true'); await sessionEndpoint(request, response); },
159
+ "edge.sessions-send": async ({ request, response }) => { response.setHeader('Deprecation', 'true'); await sessionEndpoint(request, response); },
160
+ "edge.sessions-stop": async ({ request, response }) => { response.setHeader('Deprecation', 'true'); await sessionEndpoint(request, response); },
161
+ "edge.sessions-resume": async ({ request, response }) => { response.setHeader('Deprecation', 'true'); await sessionEndpoint(request, response); },
162
+ "edge.sessions-recover": async ({ request, response }) => { response.setHeader('Deprecation', 'true'); await sessionEndpoint(request, response); },
163
+ "edge.team-read": async ({ request, response }) => { response.setHeader('Deprecation', 'true'); await teamEndpoint(request, response); },
164
+ "edge.team-send": async ({ request, response }) => { response.setHeader('Deprecation', 'true'); await teamEndpoint(request, response); },
165
+ "edge.cli": async ({ request, response }) => { await cliEndpoint(request, response); },
166
+ "edge.teams": teams,
167
+ });
168
+ return { registrations };
200
169
  }
@@ -0,0 +1,402 @@
1
+ import { type AssignmentSnapshot } from "../assignment.js";
2
+ import { type BrowserActionCard } from "../browser-workspace.js";
3
+ import { type ChatDraft } from "../converse.js";
4
+ import { type DispatchDiagnosis } from "../dispatch.js";
5
+ import { type LeadLiveStep } from "../lead-progress.js";
6
+ import { type FailureExplanation } from "../needs-you.js";
7
+ import { type Scope } from "../scope.js";
8
+ import { type ChatConfig, type ChatProviderId, type ChatSnapshot, type ChatTurn, type CheckProgress, type CoordinatorProposal, type Decision, type DirectChatProviderId, type LeadAsk, type LeadMessage, type LeadProposal, type LeadSession, type LeadTurn, type Publication, type RepairChainRow, type Store, type SubscriptionChatProviderId, type TaskFamily, type TaskState } from "../store.js";
9
+ import { type TaskControlView } from "../task-control.js";
10
+ import { type TeamChatProviderResolver } from "../team-chat-authorization.js";
11
+ import { type TeamSnapshot } from "../team-contract.js";
12
+ import { type DisplayStatus } from "../workspace-ui.js";
13
+ import { type Html } from "../html.js";
14
+ import { type Chrome, type Screen } from "./chrome.js";
15
+ import { type ProjectPeek } from "./render-pages.js";
16
+ import { type CompletionReceiptView } from "./render-results.js";
17
+ import { type MilestoneProgressView, type PlanContractView, type PlanRevisionLedgerView, type RevisionView, type RouteView } from "./render-tasks.js";
18
+ /** The installation fact that the lead was turned on by default, once (its value: the provider). */
19
+ export declare const LEAD_BY_DEFAULT_FACT = "lead-on-by-default";
20
+ /** The installation fact that the phone card was put away. */
21
+ export declare const PHONE_CARD_FACT = "phone-card-dismissed";
22
+ export type ChatProjectPulse = {
23
+ id: string;
24
+ label: string;
25
+ path: string;
26
+ peek: ProjectPeek | null;
27
+ };
28
+ /** A task attached by the server to one chat turn. The thread remains the
29
+ * unified conversation; this is a focused lens, not a second chat silo. */
30
+ export type TaskChatFocus = {
31
+ executionId: string;
32
+ /** A failed task: what its latest attempt missed and what to change (the task page's own words). */
33
+ failure?: FailureExplanation | null;
34
+ /** Until this installation's first Ready result, the task shows where it stands on Plan → You approve → Build → Checks → Ready. */
35
+ guide?: boolean;
36
+ family: TaskFamily;
37
+ history: Html;
38
+ status: DisplayStatus;
39
+ assignment: AssignmentSnapshot | null;
40
+ id: string;
41
+ title: string;
42
+ state: TaskState;
43
+ project: string | null;
44
+ now: Date;
45
+ dispatch: DispatchDiagnosis | null;
46
+ scope: "none" | "needs approval" | "approved";
47
+ plan: "requested" | "drafted" | null;
48
+ /** Adaptive execution plans (v44): the identical ledger/progress
49
+ * projection the task page renders (c2). */
50
+ planRevisions: PlanRevisionLedgerView | null;
51
+ milestoneProgress: MilestoneProgressView[] | null;
52
+ claimed: boolean;
53
+ liveRun: {
54
+ id: number;
55
+ runner: string;
56
+ startedAt: string;
57
+ phase: string | null;
58
+ } | null;
59
+ checkProgress: CheckProgress | null;
60
+ /** v52: the exact-run control — the task page's own projection. */
61
+ control: TaskControlView;
62
+ /** The phase route (v47): the task page's exact projection, so chat and
63
+ * page can never disagree about which agent runs which phase. */
64
+ route: RouteView | null;
65
+ /** Approval uses the task page's exact nonce and joint digest. */
66
+ approval: {
67
+ scope: Scope;
68
+ nonce: string;
69
+ digest: string;
70
+ planDocument: string | null;
71
+ /** The drafted plan's contract record (contract handoff, task 1): the
72
+ * same panel the task page and /next show inside the ceremony. */
73
+ planContract: PlanContractView | null;
74
+ deliverable: "branch" | "report";
75
+ revision: RevisionView | null;
76
+ coordinator: {
77
+ label: string;
78
+ filedAgo: string | null;
79
+ } | null;
80
+ /** The repair chain row when this task is a machine-drafted repair. */
81
+ repairChain: RepairChainRow | null;
82
+ } | null;
83
+ decisions: (Decision & {
84
+ taskId: string;
85
+ repo: string | null;
86
+ })[];
87
+ publication: Publication | null;
88
+ /** The same compact, evidence-backed receipt shown on the task page.
89
+ * Chat is a lens over durable workflow state, never a second copy. */
90
+ result: CompletionReceiptView | null;
91
+ };
92
+ /** The task composer's modes (console v2), as the words the lead reads for that one turn. */
93
+ export type TaskComposerMode = "build" | "plan" | "answer";
94
+ export declare const TASK_COMPOSER_MODES: Record<TaskComposerMode, string>;
95
+ export declare function taskChatContext(focus: TaskChatFocus): Html;
96
+ export declare function taskChatApproval(focus: TaskChatFocus, csrf: string): Html;
97
+ /** The chat's status sentence, worded as the task page words it: what a failed attempt missed, or which step a live
98
+ * build is on (and the step it is stuck on). Undefined keeps the shared status sentence. */
99
+ export declare function chatStatusSentence(focus: TaskChatFocus): string | undefined;
100
+ /** One live, server-derived journey from request to proof. The fragment is
101
+ * safe to refresh independently, so an in-progress message is never lost. */
102
+ export declare function taskChatLiveRegion(focus: TaskChatFocus, csrf: string, fragment?: boolean, inert?: boolean, approvalHref?: string): Html;
103
+ /** The first task's way to Ready, filled in as it moves (onboarding): the same stage every surface reads. */
104
+ export declare function firstTaskJourneyHtml(focus: TaskChatFocus): Html;
105
+ export declare function taskChatHeading(focus: TaskChatFocus): Html;
106
+ export declare function chatWorkspace(content: Html, projects: readonly ChatProjectPulse[], inert: boolean, focus: TaskChatFocus | null, resultPanel?: Html | null): Html;
107
+ /** The folded overview's one-line summary (UI polish 2026-09-13): the
108
+ * two counts a phone reader scans before deciding to open it. */
109
+ export declare function chatOverviewSummaryHtml(projects: readonly ChatProjectPulse[], attention?: {
110
+ count: number;
111
+ saturated: boolean;
112
+ }): Html;
113
+ /** A live, server-derived portfolio card. It is deliberately independent
114
+ * of the model's prose: the numbers and links always reflect the current
115
+ * control plane, while chat remains the place to ask what they mean. */
116
+ export type AssignmentChatSnapshot = ChatSnapshot & {
117
+ assignmentStates?: Record<string, {
118
+ state: AssignmentSnapshot['state'];
119
+ label: string;
120
+ detail: string;
121
+ }>;
122
+ attentionCount?: {
123
+ count: number;
124
+ saturated: boolean;
125
+ };
126
+ };
127
+ export declare function chatFleetOverview(snapshot: AssignmentChatSnapshot | null, projects: readonly ChatProjectPulse[], interactive: boolean): Html;
128
+ /**
129
+ * The lead's project rail: one bounded pulse per admitted project, plus
130
+ * two roads that preserve the plane's contracts. "ask" sends the stable
131
+ * rN alias the model already sees; "board" uses the existing POST switch
132
+ * instead of smuggling a project change through a GET parameter.
133
+ */
134
+ export declare function chatProjectRail(projects: readonly ChatProjectPulse[], inert: boolean): Html;
135
+ /** Spend-authorized one-click questions: ordinary /chat posts, not a new door. */
136
+ export declare function leadPromptStarters(focus?: TaskChatFocus | null): Html;
137
+ export declare function chatHeading(copy: string, projectCount: number, showProjectToggle?: boolean): Html;
138
+ /** A deliberately small rich-text grammar for model copy. The reply is shaped first (the lead's voice, enforced:
139
+ * no headers, at most three bold anchors, labelled links, no internal ids unless `asked` wanted them); input is
140
+ * escaped before tags are introduced: bullets, numbered steps, bold, inline code and labelled http(s) links are
141
+ * presentation only—never executable HTML. */
142
+ export declare function renderChatText(raw: string, asked?: string): Html;
143
+ export declare function chatActivity(activity: string | null): Html;
144
+ export declare const CHAT_UI_SCRIPT: string;
145
+ /** Provider, model, and limits under ONE disclosure (UI polish
146
+ * 2026-09-13): the facts stay one tap away on every chat surface, and a
147
+ * membership never shows a dollar figure as if it were a charge. */
148
+ export declare function chatLimitsHtml(facts: {
149
+ provider: string;
150
+ model: string;
151
+ turnsToday: number;
152
+ dailyTurns: number;
153
+ subscription: boolean;
154
+ weekly: {
155
+ spent: number;
156
+ ceiling: number;
157
+ } | null;
158
+ }): Html;
159
+ export declare function chatPage(chrome: Chrome, data: {
160
+ enabled: ({
161
+ ok: true;
162
+ } & Record<string, unknown>) | {
163
+ ok: false;
164
+ why: string;
165
+ };
166
+ pending: ChatTurn | null;
167
+ latched: ChatTurn[];
168
+ chat: {
169
+ candidates: Map<string, {
170
+ key: string;
171
+ draft: ChatDraft;
172
+ repoPath: string;
173
+ }>;
174
+ lastTurn: {
175
+ id: number;
176
+ reply: string | null;
177
+ staticError: string | null;
178
+ proposalsDiscarded: boolean;
179
+ } | null;
180
+ } | null;
181
+ recent: ChatTurn[];
182
+ turnsToday: number;
183
+ weeklySpent: number;
184
+ projects: ChatProjectPulse[];
185
+ fleetSnapshot: AssignmentChatSnapshot | null;
186
+ catchUp?: Html;
187
+ /** Optional task lens into the same unified conversation. */
188
+ focusTask: TaskChatFocus | null;
189
+ canManage: boolean;
190
+ config: import("../store.js").ChatConfig | null;
191
+ /** Where each provider's key comes from — never the key itself. */
192
+ keyFacts: {
193
+ provider: string;
194
+ state: "environment" | "stored" | "none";
195
+ tail: string | null;
196
+ }[];
197
+ /** OpenRouter's live catalog when the key is present and reachable. */
198
+ openrouterModels: string[] | null;
199
+ /** Claude and Codex models from the saved live catalog, labelled with prices. */
200
+ liveModels?: {
201
+ value: string;
202
+ label: string;
203
+ }[];
204
+ csrf: string;
205
+ problem: string | null;
206
+ /** The card that mints a mate session (mate arc §5), approvers only. */
207
+ leadMint?: Html;
208
+ /** Pending coordinator proposals as cards (mate arc v3), approvers only. */
209
+ coordinatorProposals?: Html;
210
+ /** The task's result detail (package 3), when the URL opened one. */
211
+ resultPanel?: Html | null;
212
+ /** Opened from "Chat settings": show them expanded. */
213
+ settingsOpen?: boolean;
214
+ /** Chat's first run is on the page: it already says what to do while there is no lead. */
215
+ firstRunShown?: boolean;
216
+ }): Screen;
217
+ export declare function chatAckPage(chrome: Chrome, turn: ChatTurn, nonce: string): Screen;
218
+ /** The card that starts a conversation: the one password ceremony (mate arc §1). */
219
+ export declare function leadMintCard(enabled: {
220
+ billing: "metered" | "subscription";
221
+ config: {
222
+ provider: ChatProviderId;
223
+ weeklyCeilingMicrousd: number;
224
+ };
225
+ }, returnTo?: string): Html;
226
+ /** The decisions the cards on a page name, for the answer card's consequences and the builder's recommendation. */
227
+ export declare function decisionsFor(store: Store, proposals: readonly {
228
+ kind: string;
229
+ payload: Record<string, unknown>;
230
+ }[]): Map<number, Decision>;
231
+ export type ProposalCardView = {
232
+ id: number;
233
+ kind: LeadProposal["kind"];
234
+ payload: Record<string, unknown>;
235
+ state: string;
236
+ outcome: Record<string, unknown> | null;
237
+ /** Who proposed: the mate, or a coordinator by name. */
238
+ by: {
239
+ mate: true;
240
+ } | {
241
+ mate: false;
242
+ name: string;
243
+ ago: string;
244
+ };
245
+ /** Where confirm/dismiss post: `/chat/proposal` for the lead's, `/proposals` for a coordinator's. */
246
+ actionBase: string;
247
+ };
248
+ /**
249
+ * A proposal card: what, then confirm/dismiss, or the door's answer. An
250
+ * `answer` card shows the question, every option WITH its consequence,
251
+ * the builder's recommendation beside the proposer's pick, and — for an
252
+ * irreversible option — the explicit confirmation field the decision
253
+ * page itself uses (ruling 12).
254
+ */
255
+ export declare function proposalCard(view: ProposalCardView, inert: boolean, decision: Decision | null, returnTo?: string | null): Html;
256
+ /** The card's HTML and, for the chat's confirm-in-place cards, the same
257
+ * card as data: the body is the HTML's own, the act is the same door. */
258
+ export declare function proposalCardParts(view: ProposalCardView, inert: boolean, decision: Decision | null, returnTo?: string | null): {
259
+ html: Html;
260
+ card: BrowserActionCard;
261
+ };
262
+ export declare function leadProposalCard(proposal: LeadProposal, inert: boolean, decision: Decision | null, returnTo?: string | null): Html;
263
+ export declare function leadProposalCardParts(proposal: LeadProposal, inert: boolean, decision: Decision | null, returnTo?: string | null): {
264
+ html: Html;
265
+ card: BrowserActionCard;
266
+ };
267
+ /** Review and inline team cards share the same server-decided controls and reasons. The team API renders these
268
+ * outside a console request, so the session's own `csrf` is given to the forms here. */
269
+ export declare function teamProposalCardParts(store: Store, actor: {
270
+ name: string;
271
+ generation: number;
272
+ }, proposal: LeadProposal, snapshot: TeamSnapshot, csrf: string, decision: Decision | null, now: Date, provider: TeamChatProviderResolver): {
273
+ html: Html;
274
+ card: BrowserActionCard;
275
+ };
276
+ export declare function coordinatorProposalCard(proposal: CoordinatorProposal, now: Date, decision: Decision | null, returnTo?: string | null): Html;
277
+ /** The section shared by /chat (both modes) and the task page: pending coordinator proposals as cards. */
278
+ export declare function coordinatorProposalsSection(proposals: readonly CoordinatorProposal[], decisions: Map<number, Decision>, now: Date, heading?: boolean, returnTo?: string | null): Html;
279
+ /** The lead thread a change in reachable projects closed (mate arc ruling 9): its saved words and card outcomes, never continued. */
280
+ export type ReplacedThread = {
281
+ messages: LeadMessage[];
282
+ proposals: LeadProposal[];
283
+ decisions: Map<number, Decision>;
284
+ };
285
+ export declare const REPLACED_THREAD_DIVIDER = "New conversation \u2014 the projects I can reach changed";
286
+ /** The replaced thread as the React conversation renders it: words and card outcomes, no buttons. */
287
+ export declare function replacedBrowserMessages(previous: ReplacedThread): import("../browser-workspace.js").BrowserMessage[];
288
+ /** The replaced thread for the server-rendered page: read only, then the divider. */
289
+ export declare function replacedThreadHtml(previous: ReplacedThread | null | undefined): Html;
290
+ export type LeadThreadRows = {
291
+ /** The lead thread a change in reachable projects replaced; shown only. */
292
+ previous?: ReplacedThread | null;
293
+ messages: LeadMessage[];
294
+ proposals: LeadProposal[];
295
+ /** The decisions the answer cards name. */
296
+ decisions: Map<number, Decision>;
297
+ coordinatorProposals: CoordinatorProposal[];
298
+ pending: LeadTurn | null;
299
+ recent: LeadTurn[];
300
+ /** Optional task lens into the same unified thread. */
301
+ focusTask: TaskChatFocus | null;
302
+ /** The lead's open question to this reader, drawn as buttons under its reply. */
303
+ ask?: LeadAsk | null;
304
+ /** Every question the lead asked in these messages, by turn: answered ones show their words without buttons. */
305
+ asks?: Map<number, LeadAsk>;
306
+ };
307
+ /** The lead's question as buttons: each option sends itself as the next message (the same POST as a typed one);
308
+ * "Something else" moves to the composer. Nothing shows while a reply is running. */
309
+ export declare function leadAskHtml(ask: LeadAsk, target: {
310
+ task: string | null;
311
+ project: string | null;
312
+ }, composer: string, open?: boolean): Html;
313
+ /** The thread's messages as the React conversation renders them, each
314
+ * with the proposal cards its turn produced; `back` is where a card's
315
+ * confirm or dismiss returns. */
316
+ export declare function leadBrowserMessages(rows: Pick<LeadThreadRows, "messages" | "proposals" | "decisions" | "pending" | "ask" | "asks">, back: string | null, target?: {
317
+ task: string | null;
318
+ project: string | null;
319
+ }): import("../browser-workspace.js").BrowserMessage[];
320
+ /** The version of the DISPLAYED conversation (package 2): every fact a
321
+ * thread or task fragment renders — message identities, card states and
322
+ * outcomes, the live turn and its step count, the last turn's state, the
323
+ * decisions the cards name, and the task lens's own facts — and nothing
324
+ * that merely ticks: no relative age, no freshly minted nonce, no csrf.
325
+ * Equal versions mean equal fragments; the poll fetches nothing else. */
326
+ export declare function leadChatVersion(rows: LeadThreadRows): string;
327
+ /** The thread region — the one safe region the live refresh reconciles
328
+ * (package 2): coordinator cards, the operator/assistant messages with
329
+ * their cards, the reply-in-progress card, and the starters that follow a
330
+ * populated thread. Every child carries a stable `data-key` so the page
331
+ * keeps an unchanged node (its open disclosures, its focus) and replaces
332
+ * only what the server rendered differently. The composer is never here. */
333
+ export declare function leadThreadHtml(data: LeadThreadRows & {
334
+ csrf: string;
335
+ now: Date;
336
+ problem: string | null;
337
+ chatProject?: string | null;
338
+ }): Html;
339
+ /** What follows the composer (package 2): the starters of an EMPTY thread
340
+ * sit under the box; once the first message lands they move above it. */
341
+ export declare function leadAfterComposerHtml(data: {
342
+ messages: LeadMessage[];
343
+ pending: LeadTurn | null;
344
+ focusTask: TaskChatFocus | null;
345
+ }): Html;
346
+ export declare function leadPage(chrome: Chrome, data: LeadThreadRows & {
347
+ session: LeadSession;
348
+ /** A project's own thread (v77); null for the lead conversation or a task. */
349
+ chatProject?: string | null;
350
+ follow?: {
351
+ enabled: boolean;
352
+ detail: string;
353
+ };
354
+ resultRunId?: number | null;
355
+ latched: ChatTurn[];
356
+ config: import("../store.js").ChatConfig;
357
+ turnsToday: number;
358
+ weeklySpent: number;
359
+ projects: ChatProjectPulse[];
360
+ fleetSnapshot: AssignmentChatSnapshot | null;
361
+ catchUp?: Html;
362
+ csrf: string;
363
+ problem: string | null;
364
+ now: Date;
365
+ /** The task's result detail (package 3), when the URL opened one. */
366
+ resultPanel?: Html | null;
367
+ }): Screen;
368
+ /** Live replies (chat streaming): per thread, the turn being answered —
369
+ * each step's tools in plain words and its text as it is written. Memory
370
+ * only and display only; the saved turn stays the record. */
371
+ export type LiveTurn = {
372
+ steps: LeadLiveStep[];
373
+ done: boolean;
374
+ ok: boolean;
375
+ listeners: Set<() => void>;
376
+ expiry?: NodeJS.Timeout;
377
+ };
378
+ export type ChatEnablement = {
379
+ ok: true;
380
+ billing: "metered";
381
+ config: ChatConfig & {
382
+ provider: DirectChatProviderId;
383
+ };
384
+ key: string;
385
+ keySource: "environment" | "stored";
386
+ price: import("../converse.js").ModelPrice;
387
+ credentialKey: string;
388
+ } | {
389
+ ok: true;
390
+ billing: "subscription";
391
+ config: ChatConfig & {
392
+ provider: SubscriptionChatProviderId;
393
+ };
394
+ key: null;
395
+ keySource: null;
396
+ price: null;
397
+ credentialKey: string;
398
+ } | {
399
+ ok: false;
400
+ code: "demo" | "unscoped" | "roots" | "unresolved" | "empty" | "unconfigured" | "unpriced" | "no-key";
401
+ why: string;
402
+ };