@tangle-network/agent-app 0.45.53 → 0.45.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 (480) hide show
  1. package/README.md +1 -1
  2. package/dist/alerting/index.d.ts +5 -175
  3. package/dist/alerting/slack.d.ts +176 -0
  4. package/dist/app-auth/index.d.ts +14 -17
  5. package/dist/assets/index.d.ts +2 -504
  6. package/dist/assets/schema.d.ts +264 -0
  7. package/dist/assets/types.d.ts +237 -0
  8. package/dist/assistant/AssistantDock.d.ts +56 -0
  9. package/dist/assistant/AssistantHistory.d.ts +41 -0
  10. package/dist/assistant/AssistantPanel.d.ts +84 -0
  11. package/dist/assistant/ProposalCard.d.ts +41 -0
  12. package/dist/assistant/ResizeHandle.d.ts +19 -0
  13. package/dist/assistant/client-context.d.ts +20 -0
  14. package/dist/assistant/client.d.ts +117 -0
  15. package/dist/assistant/index.d.ts +19 -848
  16. package/dist/assistant/launcher.d.ts +23 -0
  17. package/dist/assistant/persistence.d.ts +26 -0
  18. package/dist/assistant/presentation.d.ts +99 -0
  19. package/dist/assistant/provider-label.d.ts +7 -0
  20. package/dist/assistant/reducer.d.ts +130 -0
  21. package/dist/assistant/sse.d.ts +24 -0
  22. package/dist/assistant/time-ago.d.ts +6 -0
  23. package/dist/assistant/transcript.d.ts +97 -0
  24. package/dist/assistant/types.d.ts +291 -0
  25. package/dist/assistant/use-stick-to-bottom.d.ts +28 -0
  26. package/dist/assistant/useAssistantChat.d.ts +63 -0
  27. package/dist/assistant/useAssistantModels.d.ts +22 -0
  28. package/dist/assistant/useAssistantThreads.d.ts +47 -0
  29. package/dist/assistant/usePanelPrefs.d.ts +55 -0
  30. package/dist/billing/index.d.ts +19 -21
  31. package/dist/brand/index.d.ts +16 -10
  32. package/dist/brand-extraction/extract.d.ts +34 -0
  33. package/dist/brand-extraction/index.d.ts +12 -214
  34. package/dist/brand-extraction/map.d.ts +58 -0
  35. package/dist/brand-extraction/types.d.ts +119 -0
  36. package/dist/catalog/index.d.ts +11 -101
  37. package/dist/chat-react/composer-mode-controls.d.ts +14 -0
  38. package/dist/chat-react/entry-composer.d.ts +92 -0
  39. package/dist/chat-react/index.d.ts +22 -118
  40. package/dist/chat-react/types.d.ts +11 -0
  41. package/dist/chat-routes/attachment-store.d.ts +84 -0
  42. package/dist/chat-routes/attachment-upload.d.ts +84 -0
  43. package/dist/chat-routes/attachment-validation.d.ts +95 -0
  44. package/dist/chat-routes/binary-sniff.d.ts +45 -0
  45. package/dist/chat-routes/completed-sandbox-turn.d.ts +25 -0
  46. package/dist/chat-routes/detached-turn.d.ts +197 -0
  47. package/dist/chat-routes/dispatch-parts.d.ts +101 -0
  48. package/dist/chat-routes/draft-persistence.d.ts +189 -0
  49. package/dist/chat-routes/durable-projection.d.ts +18 -0
  50. package/dist/chat-routes/file-index.d.ts +115 -0
  51. package/dist/chat-routes/index.d.ts +25 -1840
  52. package/dist/chat-routes/model-failover-stream.d.ts +206 -0
  53. package/dist/chat-routes/promote-file-part.d.ts +84 -0
  54. package/dist/chat-routes/resolve-attachments.d.ts +72 -0
  55. package/dist/chat-routes/sandbox-producer.d.ts +146 -0
  56. package/dist/chat-routes/sandbox-turn-usage.d.ts +4 -0
  57. package/dist/{stale-turn-lock-DucQzvXu.d.ts → chat-routes/stale-turn-lock.d.ts} +7 -9
  58. package/dist/chat-routes/turn-routes.d.ts +540 -0
  59. package/dist/chat-routes/upload.d.ts +84 -0
  60. package/dist/{wire-DOZ-O6hD.d.ts → chat-routes/wire.d.ts} +41 -44
  61. package/dist/chat-store/core.d.ts +19 -0
  62. package/dist/chat-store/index.d.ts +22 -322
  63. package/dist/{parts-BqIHMdyu.d.ts → chat-store/parts.d.ts} +49 -47
  64. package/dist/chat-store/schema.d.ts +157 -0
  65. package/dist/chat-store/store.d.ts +177 -0
  66. package/dist/config/index.d.ts +13 -18
  67. package/dist/crypto/index.d.ts +10 -12
  68. package/dist/crypto/web-token.d.ts +22 -0
  69. package/dist/design-canvas/apply.d.ts +70 -0
  70. package/dist/design-canvas/drizzle-store.d.ts +29 -0
  71. package/dist/design-canvas/drizzle.d.ts +7 -575
  72. package/dist/{export-presets-mgVulRaV.d.ts → design-canvas/export-presets.d.ts} +18 -22
  73. package/dist/design-canvas/index.d.ts +22 -268
  74. package/dist/design-canvas/mcp-entry.d.ts +15 -0
  75. package/dist/design-canvas/mcp-handler.d.ts +34 -0
  76. package/dist/design-canvas/mcp-tools.d.ts +30 -0
  77. package/dist/{model-DnfO_PdJ.d.ts → design-canvas/model.d.ts} +33 -35
  78. package/dist/{operations-ByJ6yXOW.d.ts → design-canvas/operations.d.ts} +21 -25
  79. package/dist/design-canvas/schema.d.ts +558 -0
  80. package/dist/{store-CqfDtnPQ.d.ts → design-canvas/store.d.ts} +8 -12
  81. package/dist/design-canvas/templates.d.ts +72 -0
  82. package/dist/design-canvas/validate.d.ts +32 -0
  83. package/dist/design-canvas-react/components/BleedTrimOverlay.d.ts +22 -0
  84. package/dist/design-canvas-react/components/BrandKnot.d.ts +11 -0
  85. package/dist/design-canvas-react/components/CanvasEmptyState.d.ts +32 -0
  86. package/dist/design-canvas-react/components/CanvasInsertPanel.d.ts +53 -0
  87. package/dist/{lazy-DrkVyDpe.d.ts → design-canvas-react/components/DesignCanvas.d.ts} +27 -20
  88. package/dist/design-canvas-react/components/DesignCanvasEditor.d.ts +23 -0
  89. package/dist/design-canvas-react/components/ElementNode.d.ts +51 -0
  90. package/dist/design-canvas-react/components/ExportControl.d.ts +21 -0
  91. package/dist/design-canvas-react/components/GridLayer.d.ts +47 -0
  92. package/dist/design-canvas-react/components/InlineTextEditor.d.ts +25 -0
  93. package/dist/design-canvas-react/components/LayersPanel.d.ts +20 -0
  94. package/dist/design-canvas-react/components/PagesStrip.d.ts +34 -0
  95. package/dist/design-canvas-react/components/Rulers.d.ts +31 -0
  96. package/dist/design-canvas-react/components/SelectionLayer.d.ts +51 -0
  97. package/dist/design-canvas-react/components/SnapGuidesOverlay.d.ts +25 -0
  98. package/dist/design-canvas-react/components/Toolbar.d.ts +64 -0
  99. package/dist/design-canvas-react/components/Workspace.d.ts +92 -0
  100. package/dist/design-canvas-react/components/ZoomControls.d.ts +14 -0
  101. package/dist/design-canvas-react/components/glyphs.d.ts +46 -0
  102. package/dist/design-canvas-react/components/icon-button.d.ts +22 -0
  103. package/dist/design-canvas-react/components/index.d.ts +27 -0
  104. package/dist/design-canvas-react/components/layer-tree.d.ts +34 -0
  105. package/dist/design-canvas-react/components/ruler-math.d.ts +78 -0
  106. package/dist/design-canvas-react/components/transform-math.d.ts +168 -0
  107. package/dist/{command-stack-TNPWJCzW.d.ts → design-canvas-react/contracts.d.ts} +16 -63
  108. package/dist/design-canvas-react/engine/command-stack.d.ts +43 -0
  109. package/dist/design-canvas-react/engine/commands.d.ts +154 -0
  110. package/dist/design-canvas-react/engine/selection.d.ts +48 -0
  111. package/dist/design-canvas-react/engine/snap.d.ts +24 -0
  112. package/dist/design-canvas-react/engine/zoom-pan.d.ts +18 -0
  113. package/dist/design-canvas-react/engine.d.ts +21 -399
  114. package/dist/design-canvas-react/export-math.d.ts +104 -0
  115. package/dist/design-canvas-react/export.d.ts +89 -0
  116. package/dist/design-canvas-react/index.d.ts +16 -586
  117. package/dist/design-canvas-react/insert-builders.d.ts +61 -0
  118. package/dist/design-canvas-react/lazy.d.ts +21 -6
  119. package/dist/documents/docx.d.ts +50 -0
  120. package/dist/documents/extract.d.ts +87 -0
  121. package/dist/documents/index.d.ts +26 -232
  122. package/dist/documents/media-type.d.ts +33 -0
  123. package/dist/documents/pdf-inspector.d.ts +5 -9
  124. package/dist/{types-DrBidf3O.d.ts → documents/types.d.ts} +13 -15
  125. package/dist/documents/zip.d.ts +56 -0
  126. package/dist/eval/calibration.d.ts +106 -0
  127. package/dist/eval/index.d.ts +8 -116
  128. package/dist/eval-campaign/index.d.ts +11 -12
  129. package/dist/{trust-gate-Dcm5xSva.d.ts → eval-campaign/trust-gate.d.ts} +5 -9
  130. package/dist/forms/blank.d.ts +48 -0
  131. package/dist/forms/fill.d.ts +105 -0
  132. package/dist/forms/index.d.ts +58 -332
  133. package/dist/forms/registry.d.ts +115 -0
  134. package/dist/forms/verify.d.ts +58 -0
  135. package/dist/harness/index.d.ts +21 -19
  136. package/dist/intakes/api.d.ts +5 -11
  137. package/dist/{completion-CvcNUz07.d.ts → intakes/completion.d.ts} +7 -11
  138. package/dist/intakes/context-sufficiency.d.ts +113 -0
  139. package/dist/intakes/drizzle/schema.d.ts +338 -0
  140. package/dist/intakes/drizzle/store.d.ts +75 -0
  141. package/dist/intakes/drizzle.d.ts +12 -391
  142. package/dist/intakes/index.d.ts +23 -113
  143. package/dist/{model-C8U0HZxL.d.ts → intakes/model.d.ts} +15 -17
  144. package/dist/intakes-react/components/BrandMark.d.ts +10 -0
  145. package/dist/intakes-react/components/IntakeInterview.d.ts +15 -0
  146. package/dist/intakes-react/components/index.d.ts +1 -0
  147. package/dist/intakes-react/contracts.d.ts +42 -0
  148. package/dist/intakes-react/index.d.ts +12 -47
  149. package/dist/intakes-react/lazy.d.ts +9 -8
  150. package/dist/integrations/index.d.ts +10 -12
  151. package/dist/{contract-OxG_jVMx.d.ts → interactions/contract.d.ts} +40 -42
  152. package/dist/interactions/index.d.ts +16 -256
  153. package/dist/interactions/route.d.ts +151 -0
  154. package/dist/interactions/sidecar.d.ts +100 -0
  155. package/dist/knowledge/index.d.ts +7 -11
  156. package/dist/knowledge-loop/index.d.ts +13 -20
  157. package/dist/legibility/checks/empty-state.d.ts +59 -0
  158. package/dist/legibility/checks/reachability.d.ts +103 -0
  159. package/dist/legibility/checks/silent-failure.d.ts +57 -0
  160. package/dist/legibility/checks/success.d.ts +38 -0
  161. package/dist/legibility/checks/vocabulary.d.ts +65 -0
  162. package/dist/legibility/cli-args.d.ts +30 -0
  163. package/dist/legibility/cli.d.ts +25 -0
  164. package/dist/legibility/index.d.ts +10 -530
  165. package/dist/legibility/report.d.ts +22 -0
  166. package/dist/legibility/scan.d.ts +29 -0
  167. package/dist/legibility/source.d.ts +132 -0
  168. package/dist/legibility/suppress.d.ts +36 -0
  169. package/dist/legibility/types.d.ts +168 -0
  170. package/dist/legibility/walk-sources.d.ts +21 -0
  171. package/dist/{agent-activity-C8ZG0F0M.d.ts → missions/agent-activity.d.ts} +3 -5
  172. package/dist/missions/engine.d.ts +251 -0
  173. package/dist/missions/events.d.ts +195 -0
  174. package/dist/missions/index.d.ts +12 -765
  175. package/dist/missions/plan-parse.d.ts +50 -0
  176. package/dist/missions/service.d.ts +265 -0
  177. package/dist/{failover-D-3UXXTb.d.ts → model-resolution/failover.d.ts} +10 -12
  178. package/dist/model-resolution/index.d.ts +15 -18
  179. package/dist/object-store/index.d.ts +15 -17
  180. package/dist/openui/action.d.ts +54 -0
  181. package/dist/openui/authoring.d.ts +25 -0
  182. package/dist/openui/index.d.ts +24 -206
  183. package/dist/openui/route.d.ts +124 -0
  184. package/dist/openui/segments.d.ts +71 -0
  185. package/dist/openui/values.d.ts +82 -0
  186. package/dist/openui-react/index.d.ts +9 -13
  187. package/dist/peer-floors/check.d.ts +9 -190
  188. package/dist/peer-floors/cli.d.ts +2 -3
  189. package/dist/peer-floors/dependency-source.d.ts +178 -0
  190. package/dist/plans/index.d.ts +13 -14
  191. package/dist/{billing-BuNlaKlE.d.ts → platform/billing.d.ts} +28 -32
  192. package/dist/platform/guards.d.ts +79 -0
  193. package/dist/platform/hub.d.ts +107 -0
  194. package/dist/platform/index.d.ts +7 -112
  195. package/dist/{sso-Cm00S61u.d.ts → platform/sso.d.ts} +15 -97
  196. package/dist/preflight/cli.d.ts +3 -6
  197. package/dist/preflight/index.d.ts +16 -18
  198. package/dist/preset-cloudflare/headers.d.ts +12 -0
  199. package/dist/preset-cloudflare/index.d.ts +22 -74
  200. package/dist/preset-cloudflare/workflow-instance.d.ts +35 -0
  201. package/dist/profile/budget.d.ts +72 -0
  202. package/dist/profile/fingerprint.d.ts +65 -0
  203. package/dist/profile/index.d.ts +27 -19
  204. package/dist/prompt/index.d.ts +3 -5
  205. package/dist/record/drizzle/schema.d.ts +488 -0
  206. package/dist/record/drizzle/store.d.ts +224 -0
  207. package/dist/record/drizzle.d.ts +10 -679
  208. package/dist/record/fold.d.ts +99 -0
  209. package/dist/record/index.d.ts +13 -13
  210. package/dist/{fold-DACU7gtf.d.ts → record/model.d.ts} +22 -124
  211. package/dist/record/ulid.d.ts +12 -0
  212. package/dist/redact/index.d.ts +14 -16
  213. package/dist/run/index.d.ts +11 -16
  214. package/dist/runtime/agent.d.ts +23 -0
  215. package/dist/runtime/certified-delivery.d.ts +57 -0
  216. package/dist/runtime/index.d.ts +17 -367
  217. package/dist/runtime/loop.d.ts +58 -0
  218. package/dist/runtime/model-catalog.d.ts +103 -0
  219. package/dist/{model-CdCDfBA9.d.ts → runtime/model.d.ts} +25 -27
  220. package/dist/runtime/openai-stream.d.ts +126 -0
  221. package/dist/runtime/surface-profile.d.ts +115 -0
  222. package/dist/sandbox/binary-read.d.ts +63 -0
  223. package/dist/sandbox/diagnostics.d.ts +69 -0
  224. package/dist/sandbox/index.d.ts +103 -1085
  225. package/dist/sandbox/model.d.ts +179 -0
  226. package/dist/sandbox/outcome.d.ts +10 -0
  227. package/dist/sandbox/prewarm-claim-d1.d.ts +80 -0
  228. package/dist/sandbox/prewarm.d.ts +193 -0
  229. package/dist/sandbox/recovery.d.ts +216 -0
  230. package/dist/sandbox/terminal-connection.d.ts +145 -0
  231. package/dist/sandbox/workspace-sandbox-manager.d.ts +44 -0
  232. package/dist/sequences/apply.d.ts +54 -0
  233. package/dist/sequences/captions.d.ts +91 -0
  234. package/dist/sequences/drizzle-store.d.ts +36 -0
  235. package/dist/sequences/drizzle.d.ts +7 -1252
  236. package/dist/sequences/exports.d.ts +138 -0
  237. package/dist/sequences/index.d.ts +19 -340
  238. package/dist/sequences/mcp-entry.d.ts +15 -0
  239. package/dist/sequences/mcp-handler.d.ts +39 -0
  240. package/dist/sequences/mcp-tools.d.ts +47 -0
  241. package/dist/{store-B7LLlk9p.d.ts → sequences/model.d.ts} +26 -110
  242. package/dist/sequences/operations.d.ts +126 -0
  243. package/dist/sequences/schema.d.ts +1231 -0
  244. package/dist/sequences/store.d.ts +81 -0
  245. package/dist/sequences/validate.d.ts +98 -0
  246. package/dist/sequences-react/components/BrandMark.d.ts +10 -0
  247. package/dist/sequences-react/components/PreviewCanvas.d.ts +26 -0
  248. package/dist/sequences-react/components/SnapIndicatorLine.d.ts +11 -0
  249. package/dist/sequences-react/components/TimelineClipChip.d.ts +80 -0
  250. package/dist/sequences-react/components/TimelineEditor.d.ts +44 -0
  251. package/dist/sequences-react/components/TimelineEmptyState.d.ts +21 -0
  252. package/dist/sequences-react/components/TimelineGhostLanes.d.ts +14 -0
  253. package/dist/sequences-react/components/TimelinePlayhead.d.ts +11 -0
  254. package/dist/sequences-react/components/TimelineRuler.d.ts +16 -0
  255. package/dist/sequences-react/components/TimelineSmallScreenGate.d.ts +12 -0
  256. package/dist/sequences-react/components/TimelineTrackRow.d.ts +51 -0
  257. package/dist/sequences-react/components/ZoomControl.d.ts +15 -0
  258. package/dist/sequences-react/components/composite-command.d.ts +8 -0
  259. package/dist/sequences-react/components/glyphs.d.ts +26 -0
  260. package/dist/sequences-react/components/index.d.ts +31 -0
  261. package/dist/sequences-react/components/interaction-math.d.ts +103 -0
  262. package/dist/sequences-react/contracts.d.ts +187 -0
  263. package/dist/sequences-react/engine/command-stack.d.ts +18 -0
  264. package/dist/sequences-react/engine/commands.d.ts +146 -0
  265. package/dist/sequences-react/engine/playback.d.ts +18 -0
  266. package/dist/sequences-react/engine/snap.d.ts +29 -0
  267. package/dist/sequences-react/engine/zoom.d.ts +29 -0
  268. package/dist/sequences-react/index.d.ts +20 -880
  269. package/dist/sequences-react/lazy.d.ts +8 -0
  270. package/dist/sequences-react/media/frame-provider.d.ts +70 -0
  271. package/dist/sequences-react/media/transcription.d.ts +33 -0
  272. package/dist/sequences-react/media/waveform.d.ts +34 -0
  273. package/dist/session-shell/index.d.ts +31 -204
  274. package/dist/session-shell/nav-guard.d.ts +170 -0
  275. package/dist/session-shell/path.d.ts +19 -0
  276. package/dist/signoff/cli.d.ts +4 -7
  277. package/dist/signoff/config.d.ts +12 -0
  278. package/dist/signoff/exec.d.ts +44 -0
  279. package/dist/signoff/index.d.ts +56 -14
  280. package/dist/signoff/invoked-as-script.d.ts +25 -0
  281. package/dist/signoff/node-version.d.ts +50 -0
  282. package/dist/signoff/proof-attach.d.ts +88 -0
  283. package/dist/signoff/proof-cli.d.ts +1 -0
  284. package/dist/signoff/proof-fixture.d.ts +13 -0
  285. package/dist/signoff/proof-from-report.d.ts +22 -0
  286. package/dist/signoff/proof-git.d.ts +57 -0
  287. package/dist/signoff/proof-record.d.ts +202 -0
  288. package/dist/signoff/proof-verify.d.ts +103 -0
  289. package/dist/signoff/proof.d.ts +35 -310
  290. package/dist/signoff/report.d.ts +7 -0
  291. package/dist/{run-D80hoLKh.d.ts → signoff/run.d.ts} +3 -6
  292. package/dist/signoff/schedule.d.ts +55 -0
  293. package/dist/signoff/seeds.d.ts +50 -0
  294. package/dist/signoff/store.d.ts +22 -0
  295. package/dist/{types-Bd6uW9vQ.d.ts → signoff/types.d.ts} +15 -17
  296. package/dist/signoff/workflow-pin.d.ts +56 -0
  297. package/dist/signoff/workspace.d.ts +40 -0
  298. package/dist/skills/index.d.ts +28 -32
  299. package/dist/skills-placement/index.d.ts +7 -11
  300. package/dist/spend/budget.d.ts +123 -0
  301. package/dist/spend/ceiling.d.ts +51 -0
  302. package/dist/spend/cli-args.d.ts +20 -0
  303. package/dist/spend/cli.d.ts +1 -0
  304. package/dist/spend/fixtures/incident-parked-time.d.ts +55 -0
  305. package/dist/spend/index.d.ts +38 -1144
  306. package/dist/spend/liveness.d.ts +131 -0
  307. package/dist/spend/ownership.d.ts +87 -0
  308. package/dist/spend/reconcile.d.ts +109 -0
  309. package/dist/spend/reference.d.ts +42 -0
  310. package/dist/spend/report.d.ts +12 -0
  311. package/dist/spend/store.d.ts +123 -0
  312. package/dist/spend/types.d.ts +466 -0
  313. package/dist/store/index.d.ts +10 -12
  314. package/dist/stories/app-shell/fixtures.d.ts +43 -0
  315. package/dist/stories/app-shell/shell.d.ts +81 -0
  316. package/dist/stories/assistant/fixtures.d.ts +73 -0
  317. package/dist/stories/chat/fixtures.d.ts +70 -0
  318. package/dist/stories/chat/markdown.d.ts +11 -0
  319. package/dist/stories/chat/run-drill-in.d.ts +19 -0
  320. package/dist/stories/chat-controls/fixtures.d.ts +116 -0
  321. package/dist/stories/design-canvas/fixtures.d.ts +57 -0
  322. package/dist/stories/fixtures/canvas.d.ts +10 -0
  323. package/dist/stories/fixtures/catalog.d.ts +7 -0
  324. package/dist/stories/fixtures/chat.d.ts +39 -0
  325. package/dist/stories/fixtures/index.d.ts +4 -0
  326. package/dist/stories/fixtures/sequences.d.ts +17 -0
  327. package/dist/stories/panels/fixtures.d.ts +63 -0
  328. package/dist/stories/sequences/fixtures.d.ts +30 -0
  329. package/dist/stories/studio/fixtures.d.ts +22 -0
  330. package/dist/stream/index.d.ts +10 -56
  331. package/dist/{stream-normalizer-DKRxyVlZ.d.ts → stream/stream-normalizer.d.ts} +23 -26
  332. package/dist/{turn-buffer-COMQUwO2.d.ts → stream/turn-buffer.d.ts} +21 -23
  333. package/dist/stream/turn-identity.d.ts +49 -0
  334. package/dist/studio/generation.d.ts +179 -0
  335. package/dist/studio/index.d.ts +12 -181
  336. package/dist/studio-react/avatar-composer.d.ts +8 -0
  337. package/dist/studio-react/composer-hero.d.ts +12 -0
  338. package/dist/studio-react/composer-shell.d.ts +18 -0
  339. package/dist/studio-react/generation-card.d.ts +9 -0
  340. package/dist/studio-react/generation-detail-modal.d.ts +11 -0
  341. package/dist/studio-react/generation-detail.d.ts +6 -0
  342. package/dist/studio-react/generation-grid.d.ts +15 -0
  343. package/dist/studio-react/image-composer.d.ts +8 -0
  344. package/dist/studio-react/index.d.ts +32 -245
  345. package/dist/studio-react/library-drawer.d.ts +12 -0
  346. package/dist/studio-react/library-panel.d.ts +15 -0
  347. package/dist/studio-react/publish-package-composer.d.ts +18 -0
  348. package/dist/studio-react/result-canvas.d.ts +6 -0
  349. package/dist/studio-react/speech-composer.d.ts +4 -0
  350. package/dist/studio-react/studio-header.d.ts +5 -0
  351. package/dist/studio-react/studio-sheet.d.ts +12 -0
  352. package/dist/studio-react/studio-workspace.d.ts +23 -0
  353. package/dist/studio-react/transcription-composer.d.ts +12 -0
  354. package/dist/studio-react/type-config.d.ts +11 -0
  355. package/dist/studio-react/use-studio-generations.d.ts +20 -0
  356. package/dist/studio-react/video-composer.d.ts +10 -0
  357. package/dist/tangle/index.d.ts +7 -9
  358. package/dist/teams/drizzle/access.d.ts +82 -0
  359. package/dist/{invitations-schema-_fI7HkJP.d.ts → teams/drizzle/invitations-schema.d.ts} +39 -27
  360. package/dist/teams/drizzle/personal-organization.d.ts +41 -0
  361. package/dist/{access-490O6aOU.d.ts → teams/drizzle/schema.d.ts} +57 -122
  362. package/dist/teams/drizzle.d.ts +12 -44
  363. package/dist/teams/index.d.ts +20 -44
  364. package/dist/teams/invitations-api.d.ts +17 -21
  365. package/dist/{invitations-DoYMvXea.d.ts → teams/invitations.d.ts} +14 -18
  366. package/dist/teams/invite.d.ts +42 -0
  367. package/dist/teams/members-api.d.ts +12 -16
  368. package/dist/teams/resend.d.ts +3 -13
  369. package/dist/{roles-B4nU3jDi.d.ts → teams/roles.d.ts} +18 -20
  370. package/dist/teams-react/components/BrandMark.d.ts +10 -0
  371. package/dist/teams-react/components/InvitationsPanel.d.ts +13 -0
  372. package/dist/teams-react/components/InviteAcceptPage.d.ts +10 -0
  373. package/dist/teams-react/components/MembersPanel.d.ts +14 -0
  374. package/dist/teams-react/components/RoleSelect.d.ts +17 -0
  375. package/dist/teams-react/components/index.d.ts +3 -0
  376. package/dist/teams-react/contracts.d.ts +134 -0
  377. package/dist/teams-react/index.d.ts +12 -143
  378. package/dist/teams-react/lazy.d.ts +11 -11
  379. package/dist/test-setup.d.ts +1 -0
  380. package/dist/theme/index.d.ts +6 -104
  381. package/dist/theme/tailwind-preset.d.ts +1 -2
  382. package/dist/theme/theme.d.ts +106 -0
  383. package/dist/theme-contract/cli.d.ts +21 -0
  384. package/dist/theme-contract/index.d.ts +4 -6
  385. package/dist/{auth-BYtiazA4.d.ts → tools/auth.d.ts} +8 -11
  386. package/dist/tools/capability.d.ts +54 -0
  387. package/dist/tools/dispatch.d.ts +37 -0
  388. package/dist/tools/errors.d.ts +8 -0
  389. package/dist/tools/gating.d.ts +62 -0
  390. package/dist/tools/http.d.ts +27 -0
  391. package/dist/tools/index.d.ts +12 -217
  392. package/dist/{mcp-rpc-DYwPlYbZ.d.ts → tools/mcp-rpc.d.ts} +7 -9
  393. package/dist/{mcp-xxoZZfor.d.ts → tools/mcp.d.ts} +14 -16
  394. package/dist/tools/openai.d.ts +28 -0
  395. package/dist/tools/registry.d.ts +39 -0
  396. package/dist/tools/runtime.d.ts +22 -0
  397. package/dist/{types-B25Mib1r.d.ts → tools/types.d.ts} +15 -83
  398. package/dist/{flow-types-CJxEmaRy.d.ts → trace/flow-types.d.ts} +2 -4
  399. package/dist/trace/index.d.ts +11 -148
  400. package/dist/trace/mission-flow.d.ts +82 -0
  401. package/dist/trace/mission-trace.d.ts +52 -0
  402. package/dist/turn-health/classify.d.ts +207 -0
  403. package/dist/turn-health/index.d.ts +29 -637
  404. package/dist/turn-health/lifecycle.d.ts +75 -0
  405. package/dist/turn-health/sink.d.ts +122 -0
  406. package/dist/turn-health/sweep.d.ts +245 -0
  407. package/dist/turn-stream/adapters.d.ts +257 -0
  408. package/dist/turn-stream/core.d.ts +293 -0
  409. package/dist/turn-stream/do.d.ts +144 -0
  410. package/dist/turn-stream/index.d.ts +62 -738
  411. package/dist/turn-stream/memory.d.ts +41 -0
  412. package/dist/vault/ConfirmDialog.d.ts +22 -0
  413. package/dist/vault/VaultPane.d.ts +15 -0
  414. package/dist/{VaultPane-BDP6SB_K.d.ts → vault/contracts.d.ts} +15 -22
  415. package/dist/vault/index.d.ts +15 -22
  416. package/dist/vault/lazy.d.ts +9 -7
  417. package/dist/vault/server.d.ts +8 -10
  418. package/dist/web/free-route-limit.d.ts +187 -0
  419. package/dist/web/index.d.ts +15 -207
  420. package/dist/{rate-limit-BOVmJRXZ.d.ts → web/rate-limit.d.ts} +3 -5
  421. package/dist/web-react/agent-session-controls.d.ts +105 -0
  422. package/dist/web-react/async/async-view.d.ts +69 -0
  423. package/dist/web-react/async/index.d.ts +13 -305
  424. package/dist/web-react/async/state.d.ts +107 -0
  425. package/dist/web-react/async/use-async-resource.d.ts +41 -0
  426. package/dist/web-react/async/use-confirmed-mutation.d.ts +90 -0
  427. package/dist/web-react/brand-mark.d.ts +11 -0
  428. package/dist/web-react/chat-attachments.d.ts +21 -0
  429. package/dist/web-react/chat-composer.d.ts +174 -0
  430. package/dist/web-react/chat-interactions.d.ts +1 -0
  431. package/dist/web-react/chat-mentions.d.ts +48 -0
  432. package/dist/web-react/chat-stream.d.ts +106 -0
  433. package/dist/web-react/class-names.d.ts +10 -0
  434. package/dist/web-react/controls.d.ts +265 -0
  435. package/dist/web-react/durable-chat-cards.d.ts +40 -0
  436. package/dist/web-react/durable-interaction-submit.d.ts +22 -0
  437. package/dist/web-react/durable-plan-card.d.ts +13 -0
  438. package/dist/web-react/durable-plan-flow.d.ts +77 -0
  439. package/dist/web-react/harness-glyphs.d.ts +28 -0
  440. package/dist/web-react/index.d.ts +80 -2347
  441. package/dist/web-react/inert.d.ts +39 -0
  442. package/dist/web-react/insight-card.d.ts +203 -0
  443. package/dist/web-react/interaction-card-support.d.ts +115 -0
  444. package/dist/web-react/interaction-plan-card.d.ts +39 -0
  445. package/dist/web-react/interaction-question-card.d.ts +100 -0
  446. package/dist/web-react/message-attachments.d.ts +56 -0
  447. package/dist/web-react/mission-activity.d.ts +96 -0
  448. package/dist/web-react/motion.d.ts +43 -0
  449. package/dist/web-react/provenance-model.d.ts +195 -0
  450. package/dist/web-react/provenance.d.ts +82 -0
  451. package/dist/web-react/provider-logo.d.ts +14 -0
  452. package/dist/web-react/record-grid-model.d.ts +257 -0
  453. package/dist/web-react/record-grid.d.ts +108 -0
  454. package/dist/web-react/sandbox-terminal.d.ts +90 -0
  455. package/dist/web-react/seat-paywall.d.ts +47 -0
  456. package/dist/web-react/session-history.d.ts +196 -0
  457. package/dist/web-react/smooth-text.d.ts +29 -0
  458. package/dist/web-react/sparkline.d.ts +150 -0
  459. package/dist/web-react/terminal.d.ts +1 -92
  460. package/dist/web-react/use-chat-interactions.d.ts +78 -0
  461. package/dist/web-react/use-composer-attachments.d.ts +111 -0
  462. package/dist/web-react/use-file-mentions.d.ts +94 -0
  463. package/dist/web-react/work-product.d.ts +105 -0
  464. package/dist/work-product/claim-support.d.ts +288 -0
  465. package/dist/work-product/index.d.ts +16 -849
  466. package/dist/work-product/provenance.d.ts +61 -0
  467. package/dist/{queue-VTBA5ONX.d.ts → work-product/queue.d.ts} +10 -12
  468. package/dist/work-product/quote.d.ts +139 -0
  469. package/dist/work-product/route.d.ts +88 -0
  470. package/dist/work-product/service.d.ts +123 -0
  471. package/dist/work-product/tools.d.ts +144 -0
  472. package/dist/{types-CCeYywdS.d.ts → work-product/types.d.ts} +29 -31
  473. package/dist/work-product-react/index.d.ts +19 -8
  474. package/dist/workspace-react/index.d.ts +8 -11
  475. package/package.json +5 -4
  476. package/dist/agent-session-controls-CmlXwp_H.d.ts +0 -384
  477. package/dist/apply-6wlMOLf8.d.ts +0 -280
  478. package/dist/attachment-validation-BfJDBU1g.d.ts +0 -261
  479. package/dist/budget-BOucfcb_.d.ts +0 -142
  480. package/dist/values-C7RidJuI.d.ts +0 -156
@@ -1,2342 +1,77 @@
1
- import * as react from 'react';
2
- import { ReactNode, RefObject, ReactElement, CSSProperties } from 'react';
3
- import { ToolPart } from '@tangle-network/ui/types';
4
- import { C as ChatInteractionField, I as InteractionAnswers, a as ChatInteractionStatus, b as ChatInteraction, c as InteractionCancelData, d as ChatSelectField, e as InteractionRequestWire } from '../contract-OxG_jVMx.js';
5
- export { f as ChatFreeTextField, g as ComposerAnswerDelivery, h as INTERACTION_CANCEL_EVENT, i as INTERACTION_EVENT, j as INTERACTION_RESOLVED_EVENT, k as InteractionAnswerValue, l as InteractionPersistedPart, N as NoticeKind, m as NoticePersistedPart, P as ParseInteractionAnswersResult, n as ParseInteractionResult, o as canTransitionInteractionStatus, p as cancelStatusFor, q as composerAnswerData, r as composerAnswerDeliveries, s as dedupeQuestionInteractionsByContent, t as fieldAcceptsFreeText, u as interactionFromWireRequest, v as interactionPartKey, w as interactionToPersistedPart, x as isRenderableInteractionKind, y as isSafeInteractionFieldKey, z as isTerminalInteractionStatus, A as noticePart, B as noticePartKey, D as parseInteractionAnswers, E as parseInteractionCancel, F as parseInteractionRequest, G as persistedPartToInteraction, H as questionInteractionContentSignature, J as stampInteractionAnswers } from '../contract-OxG_jVMx.js';
6
- import { ChatPlan } from '../plans/index.js';
7
- import { InteractionData } from '@tangle-network/agent-interface';
8
- export { InteractionData, InteractionOutcome, InteractionRequest } from '@tangle-network/agent-interface';
9
- import { e as ChatMentionPart, a as ChatAttachmentPart } from '../parts-BqIHMdyu.js';
10
- export { s as attachmentInputToPart, t as attachmentKindForMime, u as attachmentPartsFromMessageParts, x as isChatAttachmentPart, H as mentionInputToPart, I as mentionPartsFromMessageParts } from '../parts-BqIHMdyu.js';
11
- import { E as EvidenceEntry, g as ExceptionEntry, b as WorkProductProvenance, P as ProfileBacktestSummary, Q as QualityCheck, W as WorkProductPersistedPart, h as WorkProductStatus } from '../types-CCeYywdS.js';
12
- export { a as AgentSessionControls, A as AgentSessionControlsProps, C as ComposerMentionProp, D as DEFAULT_EFFORT_LEVELS, b as DEFAULT_MENTION_EMPTY_TEXT, c as DEFAULT_MENTION_LIMIT, E as EFFORT_METER_SEGMENTS, d as EffortLevel, e as EffortMeter, f as EffortPicker, g as EffortPickerProps, I as INDEX_REFRESH_AFTER_MS, M as MentionItem, h as ModelPicker, i as ModelPickerProps, O as OVERLAY_SHADOW, P as POPOVER_SURFACE_ATTR, j as PopoverSurface, k as PopoverSurfaceProps, l as UseFileMentionsOptions, U as UseFileMentionsResult, m as effortLevelLabel, n as effortLevelsFromIds, o as effortMeterFill, r as rankFileMentions, p as reconcileEffortLevels, u as useFileMentions, q as usePending, s as usePopover } from '../agent-session-controls-CmlXwp_H.js';
13
- import { a as ChatAttachmentKind, b as ChatAttachmentInput } from '../wire-DOZ-O6hD.js';
14
- export { C as ChatMentionKind, e as ChatTurnFilePartInput, d as ChatTurnPartInput, c as ChatTurnRequestPayload, D as DISPATCH_MAX_MEDIA_PARTS, i as DISPATCH_MAX_PARTS, j as DISPATCH_REQUEST_MAX_BYTES, k as DISPATCH_STRUCTURAL_RESERVE_BYTES, F as FileMention, P as ProducerErrorEvent, m as ProducerNoticeEvent, n as ProducerPassthroughEvent, o as ProducerPassthroughEventType, p as ProducerReasoningEvent, q as ProducerTextEvent, r as ProducerToolCallEvent, s as ProducerToolResultEvent, t as ProducerUsageEvent, u as ProducerWireEvent, w as base64WireLen, x as buildMentionPromptBlock, y as chatTurnRequestInit, z as fileMentionsToParts, B as mediaTypeForMentionPath, E as mentionKindForPath } from '../wire-DOZ-O6hD.js';
15
- import { Harness } from '../harness/index.js';
16
- import { S as StepAgentActivity } from '../agent-activity-C8ZG0F0M.js';
17
- import { F as FlowTrace } from '../flow-types-CJxEmaRy.js';
18
- import { a as ReviewQueueItem, c as ReviewQueueState } from '../queue-VTBA5ONX.js';
19
- export { p as parseReviewQueueItem } from '../queue-VTBA5ONX.js';
20
- export { SandboxTerminalConnection, SandboxTerminalConnectionResponse, UseSandboxTerminalConnectionOptions, UseSandboxTerminalConnectionResult, tabTerminalConnectionId, useSandboxTerminalConnection } from './terminal.js';
21
- import { i as ProductSeatOffer } from '../billing-BuNlaKlE.js';
22
- import { SessionSort, SessionPage, SessionSummary, SessionRailAction } from '../session-shell/index.js';
23
- import { AsyncResourceState, AsyncEmptySpec } from './async/index.js';
24
- import { CatalogModel } from '../catalog/index.js';
25
- export { a as ATTACHMENT_ACCEPT, e as FileIndexReadyResponse, f as FileIndexResponse, g as FileIndexWarmingResponse } from '../attachment-validation-BfJDBU1g.js';
26
- export { a as attachmentPartKey } from '../stream-normalizer-DKRxyVlZ.js';
27
- import '../billing/index.js';
28
-
29
- /** Represent durable plan decisions as either approved or rejected */
30
- type DurablePlanDecision = 'approved' | 'rejected';
31
- /** Stable authority receipt for the follow-up turn dispatched by a plan
32
- * decision. Consumers must make `attachFollowUp` idempotent by `receiptId`;
33
- * reload and retry deliberately invoke it again. */
34
- interface DurablePlanFollowUpReceipt {
35
- receiptId: string;
36
- planId: string;
37
- revision: number;
38
- turnId: string;
39
- state: string;
40
- }
41
- /** Describe the result of a durable plan decision including plan details and pending statuses */
42
- interface DurablePlanDecisionResult {
43
- plan: ChatPlan;
44
- followUp?: DurablePlanFollowUpReceipt;
45
- idempotent: boolean;
46
- projectionPending?: boolean;
47
- effectPending?: boolean;
48
- }
49
- /** Define input parameters for making a durable plan decision including optional feedback */
50
- interface DurablePlanDecisionInput {
51
- planId: string;
52
- revision: number;
53
- decision: DurablePlanDecision;
54
- feedback?: string;
55
- }
56
- /** Define input parameters for retrieving the current durable plan including optional revision number */
57
- interface DurablePlanCurrentInput {
58
- planId: string;
59
- revision?: number;
60
- }
61
- /** Define methods to obtain and decide durable plan decisions asynchronously */
62
- interface DurablePlanDecisionClient {
63
- current: (input: DurablePlanCurrentInput) => Promise<DurablePlanDecisionResult>;
64
- decide: (input: DurablePlanDecisionInput) => Promise<DurablePlanDecisionResult>;
65
- }
66
- /** Represent errors from DurablePlanClient operations including status, code, and current plan details */
67
- declare class DurablePlanClientError extends Error {
68
- readonly status: number;
69
- readonly code?: string | undefined;
70
- readonly currentPlan?: ChatPlan | undefined;
71
- constructor(message: string, status: number, code?: string | undefined, currentPlan?: ChatPlan | undefined);
72
- }
73
- /** Define configuration options for creating a durable plan decision client */
74
- interface DurablePlanDecisionClientOptions {
75
- url: string | ((input: DurablePlanCurrentInput | DurablePlanDecisionInput) => string);
76
- body?: Record<string, unknown> | ((input: DurablePlanDecisionInput) => Record<string, unknown>);
77
- fetchImpl?: typeof fetch;
78
- }
79
- /** Browser client for the shared durable-plan route. The route URL and all
80
- * product routing fields are injected; workspace/session identity is still
81
- * resolved and authorized on the server. */
82
- declare function createDurablePlanDecisionClient(options: DurablePlanDecisionClientOptions): DurablePlanDecisionClient;
83
- /** Define options to configure durable plan flow with plan, client, and optional callbacks */
84
- interface UseDurablePlanFlowOptions {
85
- plan: ChatPlan;
86
- client: DurablePlanDecisionClient;
87
- /** Must be idempotent by receipt.receiptId. */
88
- attachFollowUp?: (receipt: DurablePlanFollowUpReceipt) => Promise<void> | void;
89
- onUpdated?: (plan: ChatPlan) => void;
90
- }
91
- /** Define the result and actions for managing a durable plan flow including decisions, restoration, and error handling */
92
- interface UseDurablePlanFlowResult {
93
- plan: ChatPlan;
94
- deciding: DurablePlanDecision | null;
95
- restoring: boolean;
96
- error: string | null;
97
- decide: (decision: DurablePlanDecision, feedback?: string) => Promise<DurablePlanDecisionResult | null>;
98
- restore: () => Promise<DurablePlanDecisionResult | null>;
99
- clearError: () => void;
100
- }
101
- /** Shared plan decision controller. It coalesces only concurrent attachment
102
- * attempts; a later retry/restore calls the consumer's idempotent transport
103
- * again so a lost response cannot strand an already-dispatched follow-up. */
104
- declare function useDurablePlanFlow(options: UseDurablePlanFlowOptions): UseDurablePlanFlowResult;
105
-
106
- /**
107
- * Shared answer-building + submit plumbing for the interaction cards
108
- * (question, plan). Client-safe, no React: cards own their state, this owns
109
- * the wire. Lifted from the gtm-agent fork (the most fix-absorbed of the three
110
- * product copies), including the 30s submit timeout that keeps a dead route
111
- * from wedging a card in "Submitting…".
112
- */
113
-
114
- /** Status-badge labels for an interaction card. `cancelled`/`expired` read the
115
- * same across cards; each card supplies its own verbs for the other states
116
- * (a question is answered/declined; a plan is approved/rejected). */
117
- declare function interactionStatusLabels(labels: {
118
- pending: string;
119
- answered: string;
120
- declined: string;
121
- }): Record<ChatInteractionStatus, string>;
122
- /** Terminal-state notes for an interaction card. The expiry/withdrawal lines
123
- * share one shape around the card's noun ("question"/"plan"); any extra notes
124
- * (e.g. a plan's `declined` revision line) merge on top. */
125
- declare function interactionTerminalNotes(noun: string, extra?: Partial<Record<ChatInteractionStatus, string>>): Partial<Record<ChatInteractionStatus, string>>;
126
- /** Define a record mapping field names to objects with optional selected, text, and custom string arrays or values */
127
- type FieldValues = Record<string, {
128
- selected?: string[];
129
- text?: string;
130
- custom?: string;
131
- }>;
132
- /** Converts acknowledged, persisted answers back into the local field state
133
- * consumed by the shared cards. Persisted values are authoritative: this is
134
- * intentionally used only when an interaction carries `answers`, never to
135
- * guess an answer from the absence of an outstanding sidecar ask. */
136
- declare function fieldValuesFromAnswers(fields: ChatInteractionField[], answers: InteractionAnswers | undefined): FieldValues;
137
- /** The submitted value for one field, or null when it has no answer yet.
138
- *
139
- * Returns `InteractionAnswers[string]`, not the wider `InteractionData[string]`:
140
- * a card reads its value out of a rendered control, so every branch below
141
- * yields a plain scalar or string array. `InteractionData` also admits a
142
- * one-use `secret_handle` reference, which no control here can produce and
143
- * which `onResolved` must never receive — that path persists into the visible
144
- * transcript. Declaring the narrow type keeps the handle out by construction
145
- * rather than by review. */
146
- declare function fieldAnswer(field: ChatInteractionField, values: FieldValues): InteractionAnswers[string] | null;
147
- /** All required fields answered → the respond payload; else null (not
148
- * submittable yet). Optional unanswered fields are omitted. */
149
- declare function buildAnswerData(fields: ChatInteractionField[], values: FieldValues): InteractionAnswers | null;
150
- /** Determine if a status is late answerable by checking if it is expired or cancelled */
151
- declare function isLateAnswerableStatus(status: ChatInteractionStatus): boolean;
152
- /** Secrets must never leave the sidecar answer channel for the visible chat
153
- * transcript, so a secret-bearing ask cannot be late-answered. */
154
- declare function hasSecretField(fields: ChatInteractionField[]): boolean;
155
- /** Renders the late answer as a self-contained chat message: the original
156
- * question, its context, and the user's answer(s). */
157
- declare function lateAnswerMessage(interaction: ChatInteraction, data: InteractionData): string;
158
- /** Define the timeout duration in milliseconds for submitting an interaction */
159
- declare const INTERACTION_SUBMIT_TIMEOUT_MS = 30000;
160
- /** Provide the timeout message displayed when the agent cannot be reached during interaction submission */
161
- declare const INTERACTION_SUBMIT_TIMEOUT_MESSAGE = "Could not reach the agent. Try again.";
162
- /** One card submission: which ask, resolved how, with what answers. */
163
- interface InteractionAnswerSubmission {
164
- id: string;
165
- outcome: 'accepted' | 'declined';
166
- data?: InteractionData;
167
- }
168
- /** Resolve the result of an interaction submission indicating success or failure with details */
169
- type InteractionSubmitResult = {
170
- ok: true;
171
- } | {
172
- ok: false;
173
- expired: boolean;
174
- message: string;
175
- };
176
- /** The cards' only side-effect seam: POST one resolution, report the normalized
177
- * outcome. Products bind their route URL + routing fields (workspaceId,
178
- * threadId, session path param) via `createInteractionAnswerSubmitter` or a
179
- * hand-rolled implementation. */
180
- type SubmitInteractionAnswer = (submission: InteractionAnswerSubmission) => Promise<InteractionSubmitResult>;
181
- /** Extracts the most specific error message a route returned. */
182
- declare function responseErrorMessage(res: Response): Promise<{
183
- code?: string;
184
- message: string;
185
- }>;
186
- /** Define options for submitting interaction answers including URL, body, timeout, and fetch implementation */
187
- interface InteractionAnswerSubmitterOptions {
188
- /** The product's answer route (the POST half of `createInteractionAnswerRoute`).
189
- * A function when the URL carries the session (e.g. `/api/sessions/${id}/interactions`). */
190
- url: string | ((submission: InteractionAnswerSubmission) => string);
191
- /** Extra routing fields merged into the POST body (e.g. workspaceId, threadId). */
192
- body?: Record<string, unknown> | ((submission: InteractionAnswerSubmission) => Record<string, unknown>);
193
- timeoutMs?: number;
194
- fetchImpl?: typeof fetch;
195
- }
196
- /**
197
- * Runs a host-supplied submitter under the CARD's own deadline, and always
198
- * resolves.
199
- *
200
- * `createInteractionAnswerSubmitter` aborts its own fetch, but a product may
201
- * pass any `SubmitInteractionAnswer` — commonly one wrapping an untimed
202
- * `fetch`. The deadline cannot live only in the submitter, because what gets
203
- * stuck is the card: its in-flight guard is cleared by the awaited promise
204
- * settling, so a submitter that never settles leaves that guard set for the
205
- * life of the instance — "Submitting…" forever, and no answer can be sent
206
- * again. A submitter with its own shorter timeout simply wins the race.
207
- *
208
- * Rejection is normalized too: a submitter that throws would otherwise escape
209
- * the click handler as an unhandled rejection, leaving the user with a card
210
- * that silently did nothing. It becomes a visible, retryable message instead.
211
- */
212
- declare function settleInteractionSubmit(run: () => Promise<InteractionSubmitResult>, timeoutMs?: number): Promise<InteractionSubmitResult>;
213
- /**
214
- * Builds the `SubmitInteractionAnswer` the cards consume: POSTs
215
- * `{ ...routingFields, id, outcome, data? }` with an abortable timeout and
216
- * normalizes the outcome. `expired` is the 410 path — the ask is gone
217
- * (answered elsewhere, timed out, or the session moved on) and the card must
218
- * flip to the same dead state a cancel event produces.
219
- */
220
- declare function createInteractionAnswerSubmitter(options: InteractionAnswerSubmitterOptions): SubmitInteractionAnswer;
221
-
222
- type DurableChatCard = {
223
- kind: 'plan';
224
- key: string;
225
- plan: ChatPlan;
226
- } | {
227
- kind: 'interaction';
228
- key: string;
229
- interaction: ChatInteraction;
230
- };
231
- /** Converts persisted/live parts to canonical cards. Legacy interaction-plan
232
- * cards are suppressed only when their raw part carries an explicit planId and
233
- * revision matching a durable plan. Identical markdown alone is never proof. */
234
- declare function durableChatCardsFromParts(parts: Array<Record<string, unknown>>): DurableChatCard[];
235
- interface DurableChatCardsProps {
236
- parts: Array<Record<string, unknown>>;
237
- canWrite: boolean;
238
- submitInteraction: SubmitInteractionAnswer;
239
- decidePlan: (plan: ChatPlan, decision: DurablePlanDecision, feedback?: string) => Promise<DurablePlanDecisionResult | null>;
240
- decidingPlan?: (plan: ChatPlan) => DurablePlanDecision | null;
241
- planError?: (plan: ChatPlan) => string | null;
242
- onInteractionResolved?: (id: string, status: Exclude<ChatInteraction['status'], 'pending'>, answers?: InteractionAnswers) => void;
243
- onLateAnswer?: (message: string) => boolean | void | Promise<boolean | void>;
244
- /** Fired when the user asks the agent to re-submit an expired/withdrawn
245
- * plan card as a new chat turn; receives that card's interaction. Omit to
246
- * hide the affordance entirely. */
247
- onReRequest?: (interaction: ChatInteraction) => boolean | void | Promise<boolean | void>;
248
- /** Overrides the default re-request button label. */
249
- reRequestLabel?: string;
250
- renderMarkdown?: (markdown: string) => ReactNode;
251
- className?: string;
252
- }
253
- /** Ready-to-embed canonical question/plan card lane for persisted assistant
254
- * parts. Apps inject transport and styling callbacks instead of rebuilding the
255
- * lifecycle/render switch. */
256
- declare function DurableChatCards({ parts, canWrite, submitInteraction, decidePlan, decidingPlan, planError, onInteractionResolved, onLateAnswer, onReRequest, reRequestLabel, renderMarkdown, className, }: DurableChatCardsProps): react.JSX.Element | null;
257
-
258
- /**
259
- * Client-side chat-stream consumption — the NDJSON parse loop every agent
260
- * app's chat UI hand-rolls (and breaks). Normalizes the three line shapes the
261
- * agent-app chat routes emit:
262
- *
263
- * {kind:'event', event:{type:'text'|'reasoning'|'tool_call'|'usage'|'notice'|'error', ...}}
264
- * {kind:'tool_result', toolCallId, toolName, label, outcome}
265
- * {type:'turn'|'metadata'|'error'|'turn_status', ...} (route-level)
266
- * {type:'interaction', data:{request}} (sidecar ask)
267
- *
268
- * Replayed lines carry an extra `seq` — transparently ignored. Works for
269
- * router-backed and sandbox-backed chats alike: anything producing these
270
- * lines (live pump, queued follow, resume replay) feeds the same callbacks.
271
- */
272
-
273
- /** Define the structure for a chat tool call including optional ID, name, and arguments object */
274
- interface ChatStreamToolCall {
275
- toolCallId?: string;
276
- toolName: string;
277
- args: Record<string, unknown>;
278
- }
279
- /** Describe the result of a chat stream tool including its outcome and optional metadata fields */
280
- interface ChatStreamToolResult {
281
- toolCallId?: string;
282
- toolName?: string;
283
- label?: string;
284
- outcome: {
285
- ok: boolean;
286
- result?: unknown;
287
- code?: string;
288
- message?: string;
289
- };
290
- }
291
- /** Define callbacks to handle events and data during a chat streaming session */
292
- interface ChatStreamCallbacks {
293
- onTurnId?: (turnId: string) => void;
294
- onText?: (delta: string) => void;
295
- onReasoning?: (delta: string) => void;
296
- onToolCall?: (call: ChatStreamToolCall) => void;
297
- onToolResult?: (result: ChatStreamToolResult) => void;
298
- onUsage?: (usage: {
299
- promptTokens: number;
300
- completionTokens: number;
301
- }) => void;
302
- onNotice?: (notice: {
303
- id: string;
304
- noticeKind: 'warning' | 'auto-declined';
305
- text: string;
306
- }) => void;
307
- onMetadata?: (data: Record<string, unknown>) => void;
308
- /** Structured detail from a loop-level error event. Fired alongside the
309
- * legacy string-only `onErrorEvent` callback. */
310
- onErrorEventDetail?: (detail: {
311
- message: string;
312
- code?: string;
313
- details?: Record<string, unknown>;
314
- }) => void;
315
- /** A loop-level error event (the turn failed server-side). Optional, but the
316
- * error never vanishes: when omitted, the message is synthesized into the
317
- * transcript via `onText` (rendered by ChatMessages as a text segment) and
318
- * logged with `console.error`. */
319
- onErrorEvent?: (message: string) => void;
320
- /** A sidecar interaction ask (kind: "question"/"plan"/…). The run is BLOCKED
321
- * in the broker until the user answers; a pending ask is "waiting on the
322
- * user", not "model working". Optional — a consumer that doesn't wire it
323
- * parses the same stream unchanged. */
324
- onInteraction?: (interaction: ChatInteraction) => void;
325
- /** A terminal withdrawal/timeout for a previously emitted interaction. */
326
- onInteractionCancel?: (cancel: InteractionCancelData) => void;
327
- /** A durable-plan snapshot from any plan lifecycle event. */
328
- onPlan?: (plan: ChatPlan) => void;
329
- }
330
- /** Represent the result of consuming a chat stream including turn ID and content reception status */
331
- interface ConsumeChatStreamResult {
332
- turnId: string | null;
333
- /** True when any text/reasoning/tool activity was received. */
334
- receivedContent: boolean;
335
- }
336
- /** Parse one NDJSON line into the callbacks. Exposed for tests. */
337
- declare function dispatchChatStreamLine(line: string, cb: ChatStreamCallbacks): {
338
- turnId?: string;
339
- receivedContent: boolean;
340
- };
341
- /** Drain one NDJSON body into the callbacks. Throws on transport failure
342
- * (caller decides whether to resume). */
343
- declare function consumeChatStream(body: ReadableStream<Uint8Array>, cb: ChatStreamCallbacks): Promise<ConsumeChatStreamResult>;
344
- /** Define options for managing and resuming streaming chat interactions with callbacks */
345
- interface StreamChatOptions {
346
- /** Start the turn (POST the chat request); must return a streaming Response. */
347
- start: () => Promise<Response>;
348
- /** Re-attach to a turn after a transport drop (GET the resume route). */
349
- resume?: (turnId: string, fromSeq: number) => Promise<Response>;
350
- callbacks: ChatStreamCallbacks;
351
- /** Called before a resume replays from 0 so the UI can reset accumulated
352
- * turn state (text, reasoning, tool chips). */
353
- onResetForResume?: () => void;
354
- }
355
- /**
356
- * Run one chat turn with automatic single-shot resume: if the transport drops
357
- * mid-turn and the server announced a turnId, reset and replay the buffered
358
- * turn. Server-side the turn keeps running either way (queued runner).
359
- */
360
- declare function streamChatTurn(opts: StreamChatOptions): Promise<ConsumeChatStreamResult>;
361
-
362
- /** Prompt-part descriptor an uploaded file carries (the upload route's
363
- * `UploadedChatFile.part`), echoed back in the turn body on send. Mirrors
364
- * `/chat-routes`' wire shape structurally — no server import here. */
365
- interface ComposerFilePart {
366
- type: 'image' | 'file';
367
- filename?: string;
368
- mediaType?: string;
369
- url?: string;
370
- path?: string;
371
- content?: string;
372
- }
373
- interface ComposerFile {
374
- id: string;
375
- name: string;
376
- size?: number;
377
- kind: 'file' | 'folder';
378
- /** Number of files inside, for a folder chip. */
379
- fileCount?: number;
380
- status: 'pending' | 'uploading' | 'ready' | 'error';
381
- /** Uploaded part descriptor; set once the upload route returns. Only
382
- * `status: 'ready'` files with a part travel on a parts-aware send. */
383
- part?: ComposerFilePart;
384
- }
385
- /** A send the host refused. `error` is shown verbatim in the composer's notice;
386
- * omit it for the generic copy. */
387
- interface ComposerSendRejected {
388
- ok: false;
389
- error?: string;
390
- }
391
- /**
392
- * What a send handler reports back. `void` — what every handler returned before
393
- * this existed — reads as accepted, so wiring stays unchanged; a thrown error, a
394
- * rejected promise, or `{ ok: false }` is the rejection that restores the draft.
395
- * A handler that resolves only when the whole turn finishes still reports
396
- * correctly: the input already cleared on dispatch, so the answer only decides
397
- * whether the draft comes back.
398
- */
399
- type ComposerSendOutcome = void | {
400
- ok: true;
401
- } | ComposerSendRejected;
402
- type ComposerSendResult = ComposerSendOutcome | Promise<ComposerSendOutcome>;
403
- /**
404
- * A send handler, typed as a UNION with the legacy `=> void` signature rather
405
- * than as `(…) => ComposerSendResult` alone.
406
- *
407
- * TypeScript's return-type-`void` rule accepts a function returning ANYTHING
408
- * where a `=> void` is expected, and that rule fires only when the target's
409
- * return type is exactly `void` — not when it is a union that contains `void`.
410
- * So narrowing this prop to `ComposerSendResult` would reject handler shapes
411
- * that compiled against the shipped `onSend?: (message: string) => void`:
412
- * `onSend={(m) => rows.push(m)}` (returns `number`) and
413
- * `onSend={(m) => append({ role: 'user', content: m })}` (an ai-sdk append
414
- * returns `Promise<string | null | undefined>`) both stop compiling, on a
415
- * package whose pinned consumers must never need a source edit to take a minor.
416
- *
417
- * The union keeps both: a legacy handler lands on the first member, and a
418
- * handler that reports an outcome lands on the second. A call through it
419
- * resolves to `void | ComposerSendResult`, which IS `ComposerSendResult`, so
420
- * the composer reads the outcome exactly as before.
421
- */
422
- type ComposerSendHandler = ((message: string) => void) | ((message: string) => ComposerSendResult);
423
- /** @see ComposerSendHandler — the parts-aware arity, same union for the same reason. */
424
- type ComposerSendPartsHandler = ((message: string, parts: ComposerFilePart[]) => void) | ((message: string, parts: ComposerFilePart[]) => ComposerSendResult);
425
- /** The rejected send, handed to `onSendFailed` so the host can undo whatever it
426
- * cleared optimistically — most importantly the staged attachments, which the
427
- * composer does not own (`pendingFiles` is a prop). */
428
- interface ComposerSendFailure {
429
- /** The reason as the composer renders it. */
430
- message: string;
431
- /** The user's exact draft, untrimmed. */
432
- text: string;
433
- /** The parts the rejected send carried. */
434
- parts: ComposerFilePart[];
435
- /** Whatever the handler threw / rejected with, or the `{ ok: false }` value. */
436
- error: unknown;
437
- /** True when the draft was put back in the textarea (the box was empty).
438
- * False means the user had typed a replacement, so the unsent text is held in
439
- * the notice instead. */
440
- restored: boolean;
441
- }
442
- interface ChatComposerProps {
443
- /** Send the trimmed, non-empty message. Attached files travel separately via
444
- * `onAttach` + `pendingFiles` (the host consumes and clears them on send).
445
- * Optional when `onSendParts` is wired.
446
- *
447
- * Report a refused send by throwing, rejecting, or returning `{ ok: false }`
448
- * — the composer restores the draft rather than losing it. */
449
- onSend?: ComposerSendHandler;
450
- /** Parts-aware send: receives the trimmed message plus the `part`
451
- * descriptors of every `ready` pending file. Takes precedence over
452
- * `onSend`; enables file-only sends (empty text, ≥1 ready part).
453
- *
454
- * Same rejection contract as `onSend`. */
455
- onSendParts?: ComposerSendPartsHandler;
456
- /** Notified when a send is rejected, after the composer has restored what it
457
- * owns. The host uses it to put back the `pendingFiles` it consumed. */
458
- onSendFailed?: (failure: ComposerSendFailure) => void;
459
- /** Notice copy when the handler names no reason of its own. */
460
- sendFailureMessage?: string;
461
- /** Stop the in-flight turn; shown in place of Send while `isStreaming`. */
462
- onCancel?: () => void;
463
- isStreaming?: boolean;
464
- /** Block input + send (e.g. while restoring). Distinct from `isStreaming`,
465
- * which keeps the textarea editable so the next turn can be composed. */
466
- disabled?: boolean;
467
- placeholder?: string;
468
- /** Controlled value. Omit for self-managed internal state (cleared on send). */
469
- value?: string;
470
- onValueChange?: (value: string) => void;
471
- /** Initial text in uncontrolled mode; ignored when `value` is provided. */
472
- initialValue?: string;
473
- /** One-shot external prefill: when this becomes a non-null string the
474
- * composer adopts it as the draft (replacing any current draft), focuses the
475
- * input with the caret at the end, and reports consumption via
476
- * `onSeedApplied` so the host can clear its seed state. */
477
- seed?: string | null;
478
- onSeedApplied?: () => void;
479
- /** Inline controls (e.g. `<ModelPicker/>` + `<EffortPicker/>` or
480
- * `<AgentSessionControls/>`). */
481
- controls?: ReactNode;
482
- /**
483
- * Where {@link controls} sit. `inline` (default) puts them on the card's own
484
- * action row, beside attach and Send — the model a turn will use reads as
485
- * part of the input rather than as a separate widget floating above it.
486
- * `above` keeps them outside the card, for a host that wants the input to be
487
- * nothing but the input.
488
- */
489
- controlsPlacement?: 'above' | 'inline';
490
- /** Attachments are opt-in: pass `onAttach` to show the attach button, accept
491
- * drag-and-drop onto the input, and render `pendingFiles` chips. */
492
- onAttach?: (files: FileList) => void;
493
- onAttachFolder?: (files: FileList) => void;
494
- pendingFiles?: ComposerFile[];
495
- onRemoveFile?: (id: string) => void;
496
- accept?: string;
497
- dropTitle?: string;
498
- dropDescription?: string;
499
- /** Cmd/Ctrl+L focuses the input and shows the hint. Default true. */
500
- focusShortcut?: boolean;
501
- /** Float the card on a soft two-layer foreground-tinted shadow (opt-in).
502
- * Elevation only — radius, ring, and control layout are unchanged. */
503
- floating?: boolean;
504
- /** Send button label. Default "Send". */
505
- sendLabel?: string;
506
- className?: string;
507
- }
508
- declare function ChatComposer({ onSend, onSendParts, onSendFailed, sendFailureMessage, onCancel, isStreaming, disabled, placeholder, value, onValueChange, initialValue, seed, onSeedApplied, controls, controlsPlacement, onAttach, onAttachFolder, pendingFiles, onRemoveFile, accept, dropTitle, dropDescription, focusShortcut, floating, sendLabel, className, }: ChatComposerProps): react.JSX.Element;
509
-
510
- type InteractionBadgeVariant = 'outline' | 'default' | 'destructive';
511
- declare function InteractionBadge({ variant, children }: {
512
- variant: InteractionBadgeVariant;
513
- children: string;
514
- }): react.JSX.Element;
515
- declare function InteractionActionButton({ variant, onClick, disabled, children, }: {
516
- variant?: 'primary' | 'outline';
517
- onClick: () => void;
518
- disabled?: boolean;
519
- children: string;
520
- }): react.JSX.Element;
521
- interface QuestionOptionListProps {
522
- /** Radio/checkbox group name — unique per field so selection is isolated. */
523
- groupName: string;
524
- /** Stable prefix for per-option input ids (label htmlFor pairing). */
525
- idPrefix: string;
526
- options: ChatSelectField['options'];
527
- /** Checkbox (multi-select) vs radio (single). */
528
- multi: boolean;
529
- selectedValues: string[];
530
- disabled: boolean;
531
- onToggle: (value: string) => void;
532
- /** Terminal answered state: the selected rows highlight (primary edge, tint,
533
- * trailing check) so the card shows WHAT was answered, not just that it was. */
534
- answered?: boolean;
535
- }
536
- /** The radio/checkbox option rows for a select field. Renders a fragment of
537
- * option `<label>` rows so a card keeps its own wrapping layout and appends
538
- * its own write-in input.
539
- *
540
- * The rows arrive as a SEQUENCE (`.agent-arrive` + `--stagger-index`), which
541
- * is the difference between reading a list and being shown one: the eye is
542
- * told there are N choices and in what order before it has read any of them.
543
- * The index is safe to take straight from the map because an option list does
544
- * not re-sort under a mounted card — a different set of options is a
545
- * different `key`, and a different ask resets the card wholesale. */
546
- declare function QuestionOptionList({ groupName, idPrefix, options, multi, selectedValues, disabled, onToggle, answered, }: QuestionOptionListProps): react.JSX.Element;
547
- interface InteractionQuestionCardProps {
548
- interaction: ChatInteraction;
549
- /** Viewer-vs-editor gate: false renders everything read-only. */
550
- canWrite: boolean;
551
- /** POST one resolution to the product's answer route (see
552
- * `createInteractionAnswerSubmitter`). Never called for late answers. */
553
- submitAnswer: SubmitInteractionAnswer;
554
- /** Fired when this card resolves locally (answered, or discovered expired
555
- * via a 410) so the stream/route state stays in sync. */
556
- onResolved?: (id: string, status: Exclude<ChatInteractionStatus, 'pending'>, answers?: ChatInteraction['answers']) => void;
557
- /** Delivers a late answer (the ask expired/was withdrawn) as a fresh chat
558
- * turn. Return/resolve `false` when the send was rejected so the card stays
559
- * retryable. Omit to hide the late-answer affordance entirely. */
560
- onLateAnswer?: (message: string) => boolean | void | Promise<boolean | void>;
561
- /** Overrides the kind badge ("Question"). */
562
- kindLabel?: string;
563
- /** What happens if nobody answers, rendered beside the submit action.
564
- *
565
- * The caller owns both the clock and the copy: this card holds no timer, so a
566
- * deadline that counts down re-renders on the caller's cadence rather than
567
- * driving one of its own — and the consequence of silence ("the default is
568
- * taken", "the run fails") is the host's policy to state, not this card's to
569
- * infer. */
570
- timeoutNote?: ReactNode;
571
- /** Renders `body` as markdown. Omitted, `body` renders as plain text — so a
572
- * host that passes authored markdown without this shows its syntax raw.
573
- *
574
- * `body` ONLY. `title` and every `field.label` stay plain strings: a label is
575
- * also the input's accessible name (`aria-label`), which has to be text, and
576
- * rendering one as nodes would either break that or silently disagree with
577
- * what a screen reader announces. Put prose in `body`.
578
- *
579
- * `interaction.body` is untrusted: it arrives off the wire, written by an
580
- * agent or whoever authored the ask. This card never injects HTML, but a
581
- * renderer that does is an XSS sink — so return React elements, and sanitize
582
- * (DOMPurify or equivalent) if you must produce HTML. */
583
- renderMarkdown?: (markdown: string) => ReactNode;
584
- className?: string;
585
- }
586
- declare function InteractionQuestionCard({ interaction, canWrite, submitAnswer, onResolved, onLateAnswer, kindLabel, timeoutNote, renderMarkdown, className, }: InteractionQuestionCardProps): react.JSX.Element;
587
-
588
- interface InteractionPlanCardProps {
589
- interaction: ChatInteraction;
590
- /** Viewer-vs-editor gate: false renders everything read-only. */
591
- canWrite: boolean;
592
- /** POST one resolution to the product's answer route (see
593
- * `createInteractionAnswerSubmitter`). */
594
- submitAnswer: SubmitInteractionAnswer;
595
- /** Fired when this card resolves locally (approved/rejected, or discovered
596
- * expired via a 410) so the stream/route state stays in sync. */
597
- onResolved?: (id: string, status: Exclude<ChatInteractionStatus, 'pending'>) => void;
598
- /** Fired when the user asks the agent to re-submit an expired/withdrawn plan
599
- * as a new chat turn. Receives the interaction so a callback shared across
600
- * cards (e.g. via DurableChatCards) knows which plan fired. Return/resolve
601
- * `false` (or throw) to report the send failed and keep the affordance
602
- * retryable. Omit to hide it entirely. */
603
- onReRequest?: (interaction: ChatInteraction) => boolean | void | Promise<boolean | void>;
604
- /** Overrides the default re-request button label
605
- * ("Ask agent to re-submit the plan" — gtm's exact current copy). */
606
- reRequestLabel?: string;
607
- /** Renders the plan body (markdown). Falls back to pre-wrapped plain text. */
608
- renderMarkdown?: (markdown: string) => ReactNode;
609
- className?: string;
610
- }
611
- declare function InteractionPlanCard({ interaction, canWrite, submitAnswer, onResolved, onReRequest, reRequestLabel, renderMarkdown, className, }: InteractionPlanCardProps): react.JSX.Element;
612
-
613
- interface DurablePlanCardProps {
614
- plan: ChatPlan;
615
- canWrite: boolean;
616
- decide: (decision: DurablePlanDecision, feedback?: string) => Promise<DurablePlanDecisionResult | null>;
617
- deciding?: DurablePlanDecision | null;
618
- error?: string | null;
619
- renderMarkdown?: (markdown: string) => ReactNode;
620
- className?: string;
621
- }
622
- declare function DurablePlanCard({ plan, canWrite, decide, deciding, error, renderMarkdown, className, }: DurablePlanCardProps): react.JSX.Element;
623
-
624
- /** Manage storage and retrieval of interaction attempt keys by interaction and submission identifiers */
625
- interface InteractionAttemptStore {
626
- get(interactionId: string, submissionSignature: string): string | null;
627
- set(interactionId: string, submissionSignature: string, attemptKey: string): void;
628
- delete(interactionId: string, submissionSignature: string): void;
629
- }
630
- /** Create a session-based store to manage interaction attempts using provided storage and optional namespace */
631
- declare function createSessionInteractionAttemptStore(storage: Pick<Storage, 'getItem' | 'setItem' | 'removeItem'>, namespace?: string): InteractionAttemptStore;
632
- /** Create an in-memory store to manage interaction attempts keyed by ID and signature */
633
- declare function createMemoryInteractionAttemptStore(): InteractionAttemptStore;
634
- /** Generate a stable string signature from an interaction answer submission */
635
- declare function interactionSubmissionSignature(submission: InteractionAnswerSubmission): string;
636
- /** Define options for submitting durable interaction answers with attempt tracking and optional key creation */
637
- interface DurableInteractionAnswerSubmitterOptions extends InteractionAnswerSubmitterOptions {
638
- attempts: InteractionAttemptStore;
639
- createAttemptKey?: () => string;
640
- }
641
- /** Answer submitter for a durable interaction route. One opaque attempt key is
642
- * retained for an ambiguous transport/5xx result and reused after reload. A
643
- * changed answer has a different signature and therefore a new attempt. */
644
- declare function createDurableInteractionAnswerSubmitter(options: DurableInteractionAnswerSubmitterOptions): SubmitInteractionAnswer;
645
-
646
- /**
647
- * useChatInteractions — the interaction-state wiring every consumer of
648
- * `ChatStreamCallbacks.onInteraction` re-implements: an id-keyed,
649
- * insertion-ordered list with
650
- *
651
- * - forward-only status transitions (a replayed/stale `pending` never
652
- * resurrects a resolved card),
653
- * - pending-question content dedupe (a re-emitted duplicate ask never renders
654
- * a second card),
655
- * - cancel-event application (`interaction.cancel` → cancelled/expired),
656
- * - local resolution marking (the card's `onResolved`),
657
- * - reload restore from the answer route's GET list (sidecar registry is the
658
- * source of truth after a reload),
659
- * - turn-end settling (client mirror of the server's finalize pass: a turn
660
- * that completed without a cancel was answered; a failed turn can make no
661
- * such claim).
662
- *
663
- * The reducer functions are pure and exported for non-React consumers/tests;
664
- * the hook is a thin `useState` shell over them.
665
- */
666
-
667
- /** Insert or update one interaction. A terminal existing entry wins over any
668
- * incoming state for the same id; a new pending ask that duplicates another
669
- * pending ask's content is dropped. Returns the same array when unchanged. */
670
- declare function upsertChatInteraction(list: ChatInteraction[], interaction: ChatInteraction): ChatInteraction[];
671
- /** Applies an `interaction.cancel` event: only a pending ask moves, to
672
- * `expired` (reason:"timeout") or `cancelled`. */
673
- declare function cancelChatInteraction(list: ChatInteraction[], cancel: InteractionCancelData): ChatInteraction[];
674
- /** Marks one ask resolved locally (the card's `onResolved`). Forward-only. */
675
- declare function resolveChatInteraction(list: ChatInteraction[], id: string, status: Exclude<ChatInteractionStatus, 'pending'>, answers?: InteractionAnswers): ChatInteraction[];
676
- /** Settles every still-pending ask when the turn ends: `answered` for a turn
677
- * that completed cleanly, `expired` for one that failed. */
678
- declare function terminalizePendingChatInteractions(list: ChatInteraction[], status: Extract<ChatInteractionStatus, 'answered' | 'expired'>): ChatInteraction[];
679
- /** Define modes for restoring chat interactions with legacy or durable strategies */
680
- type ChatInteractionRestoreMode = 'legacy' | 'durable';
681
- /** Define options to control how chat interactions are restored during the restore process */
682
- interface RestoreChatInteractionsOptions {
683
- /**
684
- * `legacy` settles pending asks absent from the sidecar list as answered,
685
- * preserving the pre-durable restore contract. `durable` leaves them
686
- * pending because absence is ambiguous until `hydrateChatInteractions`
687
- * applies the durable projection.
688
- */
689
- mode?: ChatInteractionRestoreMode;
690
- }
691
- /** Reload restore from the answer route's GET list. Legacy consumers retain
692
- * the historical absence→answered behavior; durable consumers opt into the
693
- * ambiguity-preserving mode and apply terminal parts through `hydrate`. */
694
- declare function restoreChatInteractions(list: ChatInteraction[], outstanding: InteractionRequestWire[], options?: RestoreChatInteractionsOptions): ChatInteraction[];
695
- /** Applies transcript/state-store projections after reload. Terminal state and
696
- * acknowledged answer values enrich an existing pending card without relying
697
- * on the sidecar's outstanding-list absence. */
698
- declare function hydrateChatInteractions(list: ChatInteraction[], persisted: ChatInteraction[]): ChatInteraction[];
699
- /** Resolve and manage chat interactions with methods to update, cancel, mark resolved, and restore state */
700
- interface UseChatInteractionsResult {
701
- /** All known interactions, insertion-ordered. */
702
- interactions: ChatInteraction[];
703
- /** The asks currently blocking the run (waiting on the user). */
704
- pending: ChatInteraction[];
705
- /** Wire to `ChatStreamCallbacks.onInteraction` (and persisted-part replay). */
706
- upsert: (interaction: ChatInteraction) => void;
707
- /** Wire to `interaction.cancel` events. */
708
- applyCancel: (cancel: InteractionCancelData) => void;
709
- /** Wire to the cards' `onResolved`. */
710
- markResolved: (id: string, status: Exclude<ChatInteractionStatus, 'pending'>, answers?: InteractionAnswers) => void;
711
- /** Wire to the answer route's GET list after a reload/reconnect. */
712
- restore: (outstanding: InteractionRequestWire[], options?: RestoreChatInteractionsOptions) => void;
713
- /** Apply durable transcript/state projections after a reload. */
714
- hydrate: (persisted: ChatInteraction[]) => void;
715
- /** Settle still-pending asks when the turn ends. */
716
- terminalizePending: (status: Extract<ChatInteractionStatus, 'answered' | 'expired'>) => void;
717
- /** Drop everything (thread switch). */
718
- reset: () => void;
719
- }
720
- /** Resolve options for restoring chat interactions from previous sessions */
721
- type UseChatInteractionsOptions = RestoreChatInteractionsOptions;
722
- /** Manage chat interactions state with upsert, cancel, resolve, and restore capabilities */
723
- declare function useChatInteractions(options?: UseChatInteractionsOptions): UseChatInteractionsResult;
724
-
725
- /**
726
- * Transcript-side counterpart to the composer's `@`-mention primitive
727
- * (sandbox-ui#184). The composer serializes a picked file into the message
728
- * text as `@<path>`; this module is the exact inverse — it finds those tokens
729
- * again in a PERSISTED message and splits the text so a renderer can draw a
730
- * pill where the user typed one and leave the rest as prose.
731
- *
732
- * Pure and product-agnostic: no React, no fetch, no DOM. The only input beyond
733
- * the text is the message's OWN mention parts, so one message can never render
734
- * a pill for a path another message mentioned.
735
- *
736
- * `ChatMentionPart` and the runtime helpers `mentionInputToPart` /
737
- * `mentionPartsFromMessageParts` are re-exported here from `../chat-store/parts`
738
- * directly (not the `/chat-store` barrel), so a browser bundle gets the mention
739
- * vocabulary and its converters without importing `/chat-store`, whose barrel
740
- * pulls the drizzle peer.
741
- */
742
-
743
- /** One run of a segmented message: literal prose, or a matched mention with
744
- * the part that produced it. `text` for a mention segment is the token as it
745
- * appears in the message (`@<path>`), so a renderer that ignores `part` still
746
- * reproduces the original string exactly. */
747
- interface MentionTextSegment {
748
- type: 'text' | 'mention';
749
- text: string;
750
- part?: ChatMentionPart;
751
- }
752
- /**
753
- * Split a message's text into plain-text and mention segments by matching
754
- * `@<path>` runs against that message's own mention parts.
755
- *
756
- * Only a part whose exact `@<path>` token appears in `content`, at a token
757
- * boundary on both sides, counts as a match; everything else — including
758
- * unrelated `@` text — passes through as plain text untouched. When two parts'
759
- * tokens both match at the same position (one path a prefix of another), the
760
- * LONGEST token wins, so nested-looking paths split at the right boundary.
761
- *
762
- * Returns the matched parts alongside the segments: a caller that also renders
763
- * a fallback chip row can drop the chip for anything now shown inline and keep
764
- * it only for mentions the text does not actually contain (a restored draft, a
765
- * queued message whose text was edited).
766
- */
767
- declare function segmentMentionContent(content: string, parts: ReadonlyArray<ChatMentionPart>): {
768
- segments: MentionTextSegment[];
769
- matched: Set<ChatMentionPart>;
770
- };
771
-
772
- /**
773
- * Renders a message's attachment parts (images + files) as thumbnails and
774
- * download chips — the transcript-side counterpart to `ChatComposer`'s
775
- * staged-upload chips. Ported from gtm-agent's `chat-attachment-parts.tsx`
776
- * onto agent-app's RAW-BYTES download contract: the host supplies
777
- * `resolveFileUrl(part)`, a URL that serves the attachment's raw bytes
778
- * directly, so this module never parses a JSON `{file:{blobUrl,body}}`
779
- * envelope or decodes a `[base64]` marker the way gtm's vault route did.
780
- *
781
- * No icon-library or primitives dependency (`ChatComposer`'s house style):
782
- * the loading skeleton is an inline `animate-pulse` span and the few glyphs
783
- * are inline SVGs.
784
- */
785
-
786
- /** Typed outcome of fetching one attachment's raw bytes. Callers must check
787
- * `ok` before touching `blob` — a failed fetch never produces a blank
788
- * render, it produces a visible error state. */
789
- type AttachmentFileResult = {
790
- ok: true;
791
- blob: Blob;
792
- } | {
793
- ok: false;
794
- message: string;
795
- };
796
- declare function __resetAttachmentFileCacheForTests(): void;
797
- /** Fetches (and caches) the raw bytes behind one attachment url. Concurrent
798
- * callers for the SAME url dedupe to one in-flight fetch. Only a successful
799
- * settlement stays cached — evicting failures means a remount or click-retry
800
- * after a transient error issues a fresh fetch. */
801
- declare function loadAttachmentFile(url: string, fetchFile?: (url: string) => Promise<Response>): Promise<AttachmentFileResult>;
802
- /** Drives an anchor-click download from an already-resolved blob. Returns a
803
- * typed outcome rather than throwing — a chip that fails to synthesize the
804
- * download must show the failure, not silently no-op. */
805
- declare function triggerAttachmentDownload(name: string, blob: Blob): {
806
- ok: true;
807
- } | {
808
- ok: false;
809
- message: string;
810
- };
811
- interface MessageAttachmentsProps {
812
- parts: ChatAttachmentPart[];
813
- /** URL serving the attachment's RAW bytes. */
814
- resolveFileUrl: (part: ChatAttachmentPart) => string;
815
- /** Row alignment — a user-bubble attachment row is right-aligned by
816
- * default; pass `"start"` for an assistant-turn attachment, which sits
817
- * inline with the rest of the transcript. */
818
- justify?: 'start' | 'end';
819
- /** Override the fetch used to load an attachment's bytes. Default:
820
- * `fetch(url, { credentials: 'same-origin' })`. */
821
- fetchFile?: (url: string) => Promise<Response>;
822
- }
823
- /** Renders a message's attachment parts as a row of image thumbnails and file
824
- * chips. `null` when there are none, so callers can render unconditionally
825
- * without an extra length check. */
826
- declare function MessageAttachments({ parts, resolveFileUrl, justify, fetchFile }: MessageAttachmentsProps): ReactNode;
827
-
828
- /**
829
- * `useComposerAttachments` — the composer's staged-upload lifecycle: validate
830
- * selected/dropped/pasted files against the shared limits (the SAME
831
- * `sniffBinary`/`checkAttachmentType`/size-cap vocabulary the store-backed
832
- * upload route enforces server-side, `../chat-routes/attachment-validation`
833
- * + `../chat-routes/binary-sniff`), upload each accepted file with one POST
834
- * request per file (so a single failure never poisons the batch), and track
835
- * every file's status so a host composer can render chips and gate sending.
836
- *
837
- * Ported from gtm-agent's `src/components/composer-attachments.tsx`
838
- * (gtm#584/#592/#593 hardened the sniff gate and batch semantics this leans
839
- * on), de-gtm-ified:
840
- * - the hardcoded `/api/vault/upload?workspaceId=` URL becomes
841
- * `uploadUrl`/`buildUploadRequest` (the latter wins — it hands back both
842
- * the URL and a `RequestInit` override, e.g. an auth header);
843
- * - `sonner` toasts become `onReject` (client pre-validation, never hits the
844
- * network) and `onError` (a request that reached the server and failed);
845
- * - the sandbox-ui `validateComposerFiles` import becomes a small
846
- * accept-list matcher re-implemented locally (`isAcceptedFileType`,
847
- * mirroring its `accept`-string matching byte-for-byte) — this module
848
- * stays free of the sandbox-ui peer;
849
- * - the response is expected to be `{ files: ChatAttachmentInput[] }` (full
850
- * server-authoritative descriptors — size/mediaType/kind — not gtm's
851
- * `{path, name}`), so `references` is a verbatim pass-through with no
852
- * client recompute;
853
- * - `workspaceId`'s truthiness gate becomes `enabled` (default `true`).
854
- *
855
- * Import-free beyond React + the browser-safe `/chat-routes` validation core:
856
- * this module ships through `/web-react` into client bundles
857
- * (`tests/browser-safe-subpaths.test.ts` walks the graph), so nothing here
858
- * may reach a Node builtin, `sandbox-ui`, or an engine package.
859
- */
860
-
861
- /** Define options for configuring file upload behavior and handling in a composer component */
862
- interface UseComposerAttachmentsOptions {
863
- /** Simple upload target: every file POSTs here. Ignored when
864
- * `buildUploadRequest` is provided. */
865
- uploadUrl?: string;
866
- /** Full request-building seam (auth headers, per-file routing, …) — wins
867
- * over `uploadUrl` when both are set. */
868
- buildUploadRequest?: (args: {
869
- file: File;
870
- name: string;
871
- form: FormData;
872
- }) => {
873
- url: string;
874
- init?: Omit<RequestInit, 'body' | 'signal'>;
875
- };
876
- /** Client pre-validation rejections — a file that never reaches the
877
- * network (bad type, over a size cap, over count, disallowed kind). */
878
- onReject?: (reason: string, file?: File) => void;
879
- /** A file that reached the upload endpoint and failed (HTTP error,
880
- * transport error, malformed response). */
881
- onError?: (reason: string) => void;
882
- limits?: {
883
- maxCount?: number;
884
- maxBinaryBytes?: number;
885
- maxTextBytes?: number;
886
- maxTotalBytes?: number;
887
- };
888
- /** Attachment kinds accepted, checked against the sniffed content's
889
- * mime. Default: both (`['image', 'file']` — i.e. no restriction). */
890
- allowedKinds?: ChatAttachmentKind[];
891
- /** `<input accept>`-style gate for the file picker/drop/paste path.
892
- * Default {@link ATTACHMENT_ACCEPT}. */
893
- accept?: string;
894
- /** When `false`, `addFiles` rejects every call via `onReject` (and
895
- * `blockReason` explains why) instead of staging anything — the
896
- * replacement for gtm's `workspaceId`-truthiness gate (e.g. no workspace
897
- * loaded yet). Default `true`. */
898
- enabled?: boolean;
899
- }
900
- /** Provide staged file chips, ready attachments, and methods to add, retry, or drop composer files */
901
- interface UseComposerAttachmentsResult {
902
- /** Chip models for `ChatComposer`'s `pendingFiles` prop, one per staged
903
- * file — `kind` is always `'file'` (agent-app's `ComposerFile.kind`
904
- * discriminates file-vs-folder chips, not attachment media type). */
905
- composerFiles: ComposerFile[];
906
- /** Ready-to-send attachment descriptors — only files whose upload
907
- * succeeded, straight from the server's response (no recompute). Feed
908
- * this into `ChatTurnRequestPayload.attachments`. */
909
- references: ChatAttachmentInput[];
910
- /** Validate + stage + upload the given files, one request per file. */
911
- addFiles: (files: File[] | FileList) => Promise<void>;
912
- /** Re-upload a failed entry using its retained `File`. */
913
- retry: (id: string) => void;
914
- /** Drop one staged entry, aborting its upload and revoking its preview. */
915
- removeAttachment: (id: string) => void;
916
- /** Forget every staged entry (call after a successful send). */
917
- clear: () => void;
918
- /** True while any file is still pending or uploading. */
919
- hasPending: boolean;
920
- /** True while any file failed to upload. */
921
- hasError: boolean;
922
- /** Why a send is blocked, or `null` when the queue is clean. */
923
- blockReason: string | null;
924
- }
925
- /**
926
- * Owns the composer's attachment lifecycle: validate selected/dropped/pasted
927
- * files against the shared limits, upload each accepted file to the
928
- * product's store (one request per file), and track every file's status so
929
- * the composer can render chips and gate sending.
930
- *
931
- * Failures surface loud — a rejected file calls `onReject` and is never
932
- * uploaded; a failed upload calls `onError` and leaves an error chip the user
933
- * can retry or remove. `references` only ever contains files whose upload the
934
- * server actually confirmed.
935
- */
936
- declare function useComposerAttachments(options: UseComposerAttachmentsOptions): UseComposerAttachmentsResult;
937
-
938
- /**
939
- * Provider brand marks — real logo path data (simple-icons / SVG Logos, both
940
- * CC0) inlined so the picker shows actual provider identity instead of
941
- * colored-initial monograms. Providers without a usable mark fall back to a
942
- * tinted monogram chip. Aliases (z-ai/zai, moonshot/moonshotai, deepseek_ai)
943
- * normalize to one entry.
944
- */
945
-
946
- interface ProviderLogoProps {
947
- provider?: string;
948
- size?: number;
949
- }
950
- /** Real brand mark when we have one; tinted monogram otherwise. */
951
- declare function ProviderLogo({ provider, size }: ProviderLogoProps): ReactNode;
952
-
953
- /**
954
- * Per-harness brand marks for the canonical pickers — the same marks the
955
- * legacy sandbox-ui harness picker (`dashboard/harness-logo.tsx`) shipped,
956
- * vendored as inline SVG so `/web-react` stays dependency-free beyond React:
957
- * sandbox-ui (and its `@lobehub/icons-static-svg` bundle) is an OPTIONAL peer
958
- * the canonical pickers must not force on a consumer. Geometry is the lobehub
959
- * single-color artwork, rendered in `currentColor` exactly as the legacy
960
- * component painted it (a foreground-filled CSS mask), so every mark tracks
961
- * the theme. Harnesses with no published brand mark get an honest inline
962
- * lucide glyph — bot / plug / terminal, the same fallbacks the legacy picker
963
- * used — and an unknown id falls back to the neutral bot. Data-record
964
- * structure mirrors `./provider-logo`.
965
- */
966
-
967
- interface HarnessGlyphProps {
968
- /** Harness to mark. Typed as the canonical union; an out-of-union runtime
969
- * value still renders — it gets the neutral fallback glyph. */
970
- harness: Harness;
971
- className?: string;
972
- }
973
- /**
974
- * Brand mark for a harness — size it from the call site (`className="h-4
975
- * w-4"`). Unknown ids render the neutral bot, never an invented logo.
976
- * `data-glyph` names the resolved mark so tests and stories can assert
977
- * brand-vs-fallback without snapshotting path data.
978
- */
979
- declare function HarnessGlyph({ harness, className }: HarnessGlyphProps): ReactNode;
980
-
981
- /**
982
- * Smooth text reveal — turns chunky network deltas into a continuous
983
- * typewriter paint. Streamed turns arrive in 100-500ms slabs (model burst,
984
- * flush windows, replay polls); revealing characters at an adaptive rate
985
- * makes the same bytes read as top-tier streaming. The rate scales with the
986
- * backlog so the reveal never falls behind the stream — it crawls when caught
987
- * up and sprints when a burst lands (e.g. a reasoning summary arriving all at
988
- * once still *types out* instead of popping in).
989
- */
990
- /** Define configuration options for controlling smooth text reveal animation rates */
991
- interface SmoothRevealOptions {
992
- /** Baseline reveal rate when nearly caught up. Default 90 chars/s. */
993
- baseCharsPerSecond?: number;
994
- /** Extra chars/s per backlog character — the catch-up pressure. Default 5. */
995
- catchUpPerChar?: number;
996
- /** Hard ceiling so giant bursts still animate. Default 2400 chars/s. */
997
- maxCharsPerSecond?: number;
998
- }
999
- /** Pure reveal step: how many characters should be visible after `dtMs`.
1000
- * Exposed for tests; the hook is a thin rAF wrapper around it. */
1001
- declare function nextRevealCount(shown: number, targetLength: number, dtMs: number, opts?: SmoothRevealOptions): number;
1002
- /**
1003
- * Animate `target` text into view. While `enabled`, the returned string grows
1004
- * smoothly toward `target` (which may itself keep growing); when `enabled` is
1005
- * false the full text returns immediately (history, completed turns). A
1006
- * target that is not an extension of the revealed prefix (new message) resets
1007
- * the reveal.
1008
- */
1009
- declare function useSmoothText(target: string, enabled: boolean, opts?: SmoothRevealOptions): string;
1010
-
1011
- type ActivityTone = 'live' | 'ok' | 'error' | 'neutral';
1012
- /** Map a delegation status (free-form string on the wire) to a render tone. */
1013
- declare function activityTone(status: string): ActivityTone;
1014
- /** "$0.4000" under a cent shows 4 decimals; null when unknown/zero. */
1015
- declare function formatActivityCost(costUsd?: number): string | null;
1016
- /** "8s" / "2m 05s" / "1h 12m"; null when unknown. */
1017
- declare function formatActivityDuration(durationMs?: number): string | null;
1018
- /** A delegation record on the cross-context surface; `missionRef` links a
1019
- * promoted delegation back to the mission/step that spawned it. */
1020
- interface AgentActivityRecord extends StepAgentActivity {
1021
- missionRef?: {
1022
- missionId: string;
1023
- stepId?: string;
1024
- label?: string;
1025
- };
1026
- }
1027
- interface AgentActivityPage {
1028
- items: AgentActivityRecord[];
1029
- /** Opaque continuation token; absent ⇒ no further pages. */
1030
- nextCursor?: string;
1031
- }
1032
- /**
1033
- * Fold a fetched page into the held rows: dedupe by `taskId` with the
1034
- * incoming row winning (a refresh re-fetches the head page, so newer
1035
- * snapshots of in-flight runs replace stale ones), newest `startedAt` first.
1036
- */
1037
- declare function mergeActivityPages(existing: AgentActivityRecord[], incoming: AgentActivityRecord[]): AgentActivityRecord[];
1038
- interface WaterfallRow {
1039
- name: string;
1040
- kind: 'pipeline' | 'model' | 'tool';
1041
- /** Bar geometry as percentages of the trace's total span. */
1042
- offsetPct: number;
1043
- widthPct: number;
1044
- durationLabel: string;
1045
- approx: boolean;
1046
- /** False only when the span's meta carries an explicit failure. */
1047
- ok: boolean;
1048
- }
1049
- /** Project a FlowTrace into proportional bar geometry for {@link FlowWaterfall}. */
1050
- declare function waterfallLayout(trace: FlowTrace): WaterfallRow[];
1051
- interface FlowWaterfallProps {
1052
- trace: FlowTrace;
1053
- }
1054
- /** Compact proportional waterfall over a FlowTrace — span name, bar, duration
1055
- * per row; total + cost in the footer. */
1056
- declare function FlowWaterfall({ trace }: FlowWaterfallProps): react.JSX.Element | null;
1057
- interface MissionActivityLaneProps {
1058
- /** The step's delegated-run snapshot (`MissionStepState.agentActivity`). */
1059
- activity: StepAgentActivity[];
1060
- /** Epoch ms origin for the expanded waterfall — usually the step start. */
1061
- startedAt?: number;
1062
- /** Wall clock for extending in-flight runs on the waterfall. */
1063
- nowMs?: number;
1064
- }
1065
- /**
1066
- * Collapsed sub-rows under a mission step — one row per delegated run —
1067
- * expanding to the step's waterfall. Renders nothing for an empty lane.
1068
- *
1069
- * A sub-row appears because a delegated run STARTED or FINISHED, which is the
1070
- * one kind of list change worth choreographing: it arrives, and the group
1071
- * arrives as a sequence. Keying on `taskId` is what keeps the rest still — the
1072
- * snapshot re-renders every poll, and a row whose status merely advanced holds
1073
- * the DOM node it already had.
1074
- */
1075
- declare function MissionActivityLane({ activity, startedAt, nowMs }: MissionActivityLaneProps): react.JSX.Element | null;
1076
- interface AgentActivityPanelProps {
1077
- /** Data port — page through the product's delegation records. Called with
1078
- * no cursor on mount/refresh, with `nextCursor` for older pages. */
1079
- fetchActivity: (cursor?: string) => Promise<AgentActivityPage>;
1080
- /** Render the mission link for a promoted delegation (chip, anchor, router
1081
- * Link — the product's routing, not ours). */
1082
- renderMissionRef?: (ref: NonNullable<AgentActivityRecord['missionRef']>, record: AgentActivityRecord) => ReactNode;
1083
- title?: string;
1084
- emptyLabel?: string;
1085
- }
1086
- declare function AgentActivityPanel({ fetchActivity, renderMissionRef, title, emptyLabel }: AgentActivityPanelProps): react.JSX.Element;
1087
-
1088
- /** Human label for a queue state. */
1089
- declare function reviewQueueStateLabel(state: ReviewQueueState): string;
1090
- /** Human label for a work-product status. */
1091
- declare function workProductStatusLabel(status: WorkProductStatus): string;
1092
- /** Every persisted work-product anchor on one message, re-validated. */
1093
- declare function workProductPartsFromMessageParts(parts: ReadonlyArray<Record<string, unknown>> | null | undefined): WorkProductPersistedPart[];
1094
- /** Properties for the transcript anchor card rendered in chat */
1095
- interface WorkProductCardProps {
1096
- part: WorkProductPersistedPart;
1097
- /** Open the work product (queue detail / pane) — the card's only action. */
1098
- onOpen?: (part: WorkProductPersistedPart) => void;
1099
- className?: string;
1100
- }
1101
- /** The chat transcript anchor card for one work-product version — a compact,
1102
- * system-authored pointer, not a parallel review surface. */
1103
- declare function WorkProductCard({ part, onOpen, className }: WorkProductCardProps): react.JSX.Element;
1104
- /** One fetched page of queue items with an optional continuation cursor */
1105
- interface ReviewQueuePage {
1106
- items: ReviewQueueItem[];
1107
- /** Opaque continuation token; absent ⇒ no further pages. */
1108
- nextCursor?: string;
1109
- }
1110
- /** Properties for the review queue panel over a fetch data port */
1111
- interface ReviewQueuePanelProps {
1112
- /** Data port — fetch one page of queue items (the projection's output,
1113
- * re-validated here at the JSON boundary). */
1114
- fetchQueue: (cursor?: string) => Promise<ReviewQueuePage>;
1115
- /** Open one queue item (navigate to its thread / detail pane). */
1116
- onSelect?: (item: ReviewQueueItem) => void;
1117
- title?: string;
1118
- emptyLabel?: string;
1119
- className?: string;
1120
- }
1121
- /** Merge a fetched page into held rows: dedupe by scopeKey, incoming wins,
1122
- * newest updatedAt first. Exported for tests. */
1123
- declare function mergeReviewQueuePages(existing: ReviewQueueItem[], incoming: ReviewQueueItem[]): ReviewQueueItem[];
1124
- /** The workspace review queue — cursor-paged, refreshable, selection via
1125
- * callback. States, counts, and provenance render from the projection; the
1126
- * panel holds no domain logic. */
1127
- declare function ReviewQueuePanel({ fetchQueue, onSelect, title, emptyLabel, className, }: ReviewQueuePanelProps): react.JSX.Element;
1128
- /** Properties for the evidence lineage table with source click-through */
1129
- interface EvidenceLineageTableProps {
1130
- evidence: readonly EvidenceEntry[];
1131
- /** Resolve one entry's source document to an openable URL (signed
1132
- * object-store/vault download) — the `resolveFileUrl` pattern. Absent →
1133
- * sources render as plain refs without links. */
1134
- resolveSourceUrl?: (entry: EvidenceEntry) => string;
1135
- className?: string;
1136
- }
1137
- /** Target → claim → source lineage rows: the "every material value traceable
1138
- * to source evidence" surface. Each row names the artifact target, the
1139
- * claim, and the source document location supporting it. */
1140
- declare function EvidenceLineageTable({ evidence, resolveSourceUrl, className }: EvidenceLineageTableProps): react.JSX.Element;
1141
- /** Properties for the severity-badged exception list */
1142
- interface ExceptionListProps {
1143
- exceptions: readonly ExceptionEntry[];
1144
- className?: string;
1145
- }
1146
- /** Severity-badged exception rows with resolution state. */
1147
- declare function ExceptionList({ exceptions, className }: ExceptionListProps): react.JSX.Element;
1148
- /** Properties for the pass/fail quality check list */
1149
- interface QualityCheckListProps {
1150
- checks: readonly QualityCheck[];
1151
- className?: string;
1152
- }
1153
- /** Pass/fail quality-check rows tagged with their source (agent self-report,
1154
- * platform gate, judge ensemble). */
1155
- declare function QualityCheckList({ checks, className }: QualityCheckListProps): react.JSX.Element;
1156
- /** Properties for the provenance stamp with the optional backtest slot */
1157
- interface ProvenanceStampProps {
1158
- provenance: Pick<WorkProductProvenance, 'profileHash' | 'runId' | 'servingModels'> & Partial<Pick<WorkProductProvenance, 'costUsd' | 'producedAt'>>;
1159
- /** The product-resolved backtest summary for this profile hash. When its
1160
- * trust gate failed, the composite renders as "quality: unverified" —
1161
- * never a naked number. */
1162
- backtest?: ProfileBacktestSummary;
1163
- className?: string;
1164
- }
1165
- /** The audit line a reviewer approves against: which configuration produced
1166
- * this document, what served it, and how that configuration measured on its
1167
- * backtest. */
1168
- declare function ProvenanceStamp({ provenance, backtest, className }: ProvenanceStampProps): react.JSX.Element;
1169
-
1170
- /**
1171
- * The pure half of the provenance affordance: what kind of claim a value is,
1172
- * what a reader should DO about it, and what has to be SAID when its origin
1173
- * cannot be shown.
1174
- *
1175
- * Zero React, zero DOM — a loader or a worker can decide a value's standing
1176
- * before it reaches a screen, and `./provenance`'s `ProvenanceValue` renders
1177
- * exactly what these functions decide.
1178
- *
1179
- * The distinction the module exists to hold: a person typing a number, a
1180
- * document carrying it, a formula producing it, and a model claiming it are
1181
- * four different kinds of evidence. Rendered as one grey caption they are
1182
- * indistinguishable, which is how an unverified model assertion reads to a
1183
- * reviewer as a transcribed fact.
1184
- *
1185
- * Every domain word is a caller parameter: no field names, no document kinds,
1186
- * and no confidence policy beyond a default the product overrides.
1187
- */
1188
- /**
1189
- * How a value came to exist. Four kinds, never interchangeable:
1190
- *
1191
- * - `extracted` — read out of a document or message the product can open.
1192
- * - `entered` — a person typed or confirmed it.
1193
- * - `computed` — produced from other values, each carrying its own provenance.
1194
- * - `asserted` — the agent stated it, with nothing outside the model behind it.
1195
- */
1196
- type ProvenanceBasis = 'extracted' | 'entered' | 'computed' | 'asserted';
1197
- /** Every basis, in the order a legend should list them. */
1198
- declare const PROVENANCE_BASES: readonly ProvenanceBasis[];
1199
- /** The words one basis is rendered and announced with. */
1200
- interface ProvenanceBasisMeta {
1201
- /** Marker text next to the value — short, and never only a colour. */
1202
- label: string;
1203
- /** One plain sentence naming what kind of claim this is. */
1204
- meaning: string;
1205
- /** What a reader can hold the value against, or `null` when nothing outside
1206
- * the model can. `null` is what makes an `asserted` value uncertifiable at
1207
- * any confidence. */
1208
- checkableAgainst: string | null;
1209
- }
1210
- /** Words for one basis. */
1211
- declare function provenanceBasisMeta(basis: ProvenanceBasis): ProvenanceBasisMeta;
1212
- /** Whether a source could be resolved. `ready` is the default for a source that
1213
- * says nothing. */
1214
- type ProvenanceSourceStatus = 'ready' | 'loading' | 'unavailable';
1215
- /** One thing a value came from. A `label` is mandatory because an unnamed
1216
- * source is the same as no source. */
1217
- interface ProvenanceSource {
1218
- /** What the source IS, in the reader's words: "Form W-2 (Acme Corp)",
1219
- * "Dana Whitfield", "Engagement letter". */
1220
- label: string;
1221
- /** The text in the source that carries the value. */
1222
- quote?: string;
1223
- /** Position inside the source — a page, a line, a span, a timestamp. The
1224
- * caller's words; nothing here parses it. */
1225
- locator?: string;
1226
- /** Click-through target. Absent → the source is named but not openable. */
1227
- href?: string;
1228
- /** Defaults to `ready`. */
1229
- status?: ProvenanceSourceStatus;
1230
- /** Why an `unavailable` source cannot be opened, in one sentence. */
1231
- unavailableReason?: string;
1232
- }
1233
- /**
1234
- * What the reader should DO about a value — the only form confidence takes on
1235
- * screen. "89% confidence" names no next move; these three do.
1236
- *
1237
- * - `settled` — nothing to do.
1238
- * - `check` — open the source and confirm before relying on it.
1239
- * - `confirm` — a person has to confirm the value before it is used.
1240
- */
1241
- type ProvenanceStanding = 'settled' | 'check' | 'confirm';
1242
- /** The words one standing is rendered and announced with. */
1243
- interface ProvenanceStandingMeta {
1244
- /** Short state label. */
1245
- label: string;
1246
- /** The next move, as a sentence a person can follow. */
1247
- action: string;
1248
- }
1249
- /** Words for one standing. */
1250
- declare function provenanceStandingMeta(standing: ProvenanceStanding): ProvenanceStandingMeta;
1251
- /** The weaker of two standings — `confirm` beats `check` beats `settled`. */
1252
- declare function weakerProvenanceStanding(a: ProvenanceStanding, b: ProvenanceStanding): ProvenanceStanding;
1253
- /**
1254
- * Where a product draws its confidence lines. These are a POLICY, not a truth:
1255
- * a number a model reports about itself means different things per surface, so
1256
- * the thresholds are a parameter and the number itself never reaches the screen.
1257
- */
1258
- interface ProvenanceConfidencePolicy {
1259
- /** At or above this, a value is `settled`. */
1260
- settledAtOrAbove: number;
1261
- /** At or above this (and below `settledAtOrAbove`), a value is `check`.
1262
- * Below it, `confirm`. */
1263
- checkAtOrAbove: number;
1264
- }
1265
- /** The starting policy. Products with a different tolerance pass their own. */
1266
- declare const DEFAULT_PROVENANCE_CONFIDENCE_POLICY: ProvenanceConfidencePolicy;
1267
- /** A value, where it came from, and — when it was computed — the provenanced
1268
- * values it came from. The `inputs` field is what makes the shape compose:
1269
- * a computed value's provenance IS its inputs. */
1270
- interface ProvenanceRecord {
1271
- /** The value as the reader should see it, already formatted. An empty string
1272
- * is a missing value and renders as one, never as blank space. */
1273
- display: string;
1274
- /** What the value IS ("Wages", "Filing deadline"). Optional at the top level,
1275
- * where the surface around it usually says; rendered for every composed
1276
- * input, where nothing else names them. */
1277
- label?: string;
1278
- basis: ProvenanceBasis;
1279
- /** Where it came from. An `extracted` value without one is a gap, not a
1280
- * detail. */
1281
- sources?: readonly ProvenanceSource[];
1282
- /** The provenanced values a `computed` value was produced from. */
1283
- inputs?: readonly ProvenanceRecord[];
1284
- /** How the inputs combine, in the caller's words ("wages + interest"). */
1285
- derivation?: string;
1286
- /** 0–1. Never rendered as a number — it selects a standing. */
1287
- confidence?: number;
1288
- /** Overrides the standing confidence and basis would produce — a reviewer
1289
- * approved it, a gate failed. It can only make a value WEAKER: the
1290
- * structural floors below still apply, so a product cannot mark a value
1291
- * settled that has no origin on file. */
1292
- standing?: ProvenanceStanding;
1293
- }
1294
- /** The standing a bare confidence maps to under a policy. */
1295
- declare function standingFromConfidence(confidence: number, policy?: ProvenanceConfidencePolicy): ProvenanceStanding;
1296
- /** Something missing that the reader has to be TOLD about, because the value
1297
- * renders either way and a bare number reads as a fact. */
1298
- type ProvenanceGapKind = 'no-source' | 'no-inputs' | 'unavailable-source';
1299
- /** One stated gap. `message` is rendered verbatim. */
1300
- interface ProvenanceGap {
1301
- kind: ProvenanceGapKind;
1302
- message: string;
1303
- /** The source that could not be resolved (`unavailable-source` only). */
1304
- source?: ProvenanceSource;
1305
- }
1306
- /** The sentence for a source that is not `ready`, or `null` when it is. One
1307
- * source of this copy, so the row and the gap list never disagree. */
1308
- declare function describeProvenanceSourceStatus(source: ProvenanceSource): string | null;
1309
- /**
1310
- * What this record cannot show, at its own level. Inputs are not walked: every
1311
- * composed input renders its own gaps next to its own value, where a reader can
1312
- * act on them.
1313
- */
1314
- declare function provenanceGaps(record: ProvenanceRecord): ProvenanceGap[];
1315
- /** The sources still resolving — rendered as their own state, never as an
1316
- * absence. A load in flight is not a missing source. */
1317
- declare function loadingProvenanceSources(record: ProvenanceRecord): ProvenanceSource[];
1318
1
  /**
1319
- * This record's own standing, ignoring its inputs.
1320
- *
1321
- * The order is: start from the explicit standing, else from confidence, else
1322
- * from the basis then apply every structural floor, taking the WEAKEST. The
1323
- * floors are what a caller cannot talk its way out of:
1324
- *
1325
- * - an `asserted` value never reaches `settled` (a model's own confidence
1326
- * cannot certify the model's claimthere is nothing to check it against),
1327
- * - a `no-source` / `no-inputs` gap forces `confirm` (a value dressed as
1328
- * evidence with no evidence behind it is worse than an open guess),
1329
- * - an unopenable source forces `check` (the value may be right; the reader
1330
- * just cannot confirm it).
1331
- */
1332
- declare function resolveProvenanceStanding(record: ProvenanceRecord, policy?: ProvenanceConfidencePolicy): ProvenanceStanding;
1333
- /**
1334
- * The standing a reader should see: this record's own, weakened by every value
1335
- * it was computed from, however deep.
1336
- *
1337
- * A total is only as trustworthy as the weakest number in it. Rendering the
1338
- * parent's own standing instead is how an exact sum of one document figure and
1339
- * one model guess presents as traced.
1340
- *
1341
- * Cycle-safe: a record reachable from itself is counted once.
1342
- */
1343
- declare function rollUpProvenanceStanding(record: ProvenanceRecord, policy?: ProvenanceConfidencePolicy, seen?: Set<ProvenanceRecord>): ProvenanceStanding;
1344
- /**
1345
- * One plain sentence naming where the value came from — the panel's first line
1346
- * and part of what a screen reader announces. It states the absence when there
1347
- * is one, so no code path produces silence.
1348
- */
1349
- declare function describeProvenance(record: ProvenanceRecord): string;
1350
- /**
1351
- * The move THIS value's reader can actually make.
1352
- *
1353
- * `provenanceStandingMeta().action` is the generic sentence for a standing;
1354
- * this is the one that accounts for what is on file. "Open the source and
1355
- * confirm it" is a dead instruction on a value that has no source — an action
1356
- * a reader cannot perform is the same defect as no action at all.
1357
- */
1358
- declare function provenanceNextMove(record: ProvenanceRecord, standing: ProvenanceStanding, policy?: ProvenanceConfidencePolicy): string;
1359
- /**
1360
- * The accessible name of the disclosure control: the value, how it came to
1361
- * exist, and — unless there is nothing to do — the next move. This is the
1362
- * whole affordance for someone who never sees the colour.
1363
- */
1364
- declare function provenanceTriggerLabel(record: ProvenanceRecord, standing: ProvenanceStanding): string;
1365
-
1366
- /** Properties for one provenanced value and its disclosure. */
1367
- interface ProvenanceValueProps {
1368
- /** The value and where it came from. */
1369
- record: ProvenanceRecord;
1370
- /**
1371
- * Open one source in the product's own way (a document pane at the right
1372
- * page, a drawer, a route). Takes precedence over `href` when both are
1373
- * present, because a product that routes wants its router — a source with
1374
- * neither is named but not openable, which is a legitimate state and is
1375
- * rendered as such.
1376
- */
1377
- onOpenSource?: (source: ProvenanceSource, record: ProvenanceRecord) => void;
1378
- /** Retry resolving an `unavailable` source. Absent → the failure is stated
1379
- * without a retry control, never swallowed. */
1380
- onRetrySource?: (source: ProvenanceSource, record: ProvenanceRecord) => void;
1381
- /** Where this product draws its confidence lines. */
1382
- confidencePolicy?: ProvenanceConfidencePolicy;
1383
- /**
1384
- * How many levels of composed inputs stay expandable. Past it an input still
1385
- * renders its value, its basis and its origin sentence — it just stops
1386
- * carrying its own disclosure, so a deep tree cannot run away and a record
1387
- * that reaches itself cannot recurse forever. Default 2.
1388
- */
1389
- maxDepth?: number;
1390
- /** Open the disclosure on first render — for a review surface where the
1391
- * trail is the point. Several of these coexist: only a reader opening a
1392
- * trail closes another one. */
1393
- defaultOpen?: boolean;
1394
- /** What an empty `display` renders as. A blank cell is the defect this
1395
- * component exists to remove. */
1396
- missingValueLabel?: string;
1397
- className?: string;
1398
- }
1399
- /**
1400
- * A value, its origin marker, and the disclosure that shows where it came
1401
- * from. The marker states the basis in words and, whenever there is something
1402
- * to do about the value, the next move — so the standing is legible at rest
1403
- * and does not depend on anyone opening the panel.
1404
- */
1405
- declare function ProvenanceValue({ record, onOpenSource, onRetrySource, confidencePolicy, maxDepth, defaultOpen, missingValueLabel, className, }: ProvenanceValueProps): react.JSX.Element;
1406
- /** Properties for the basis legend. */
1407
- interface ProvenanceLegendProps {
1408
- /** Only the bases present on screen. Passing all four when only two appear
1409
- * teaches distinctions the reader cannot use. */
1410
- bases: readonly ProvenanceBasis[];
1411
- className?: string;
1412
- }
1413
- /** The marker key for a surface that renders several bases at once — a review
1414
- * pane, a grid, a return. Each row is the same glyph, tone and words the
1415
- * markers use, plus what the basis MEANS. */
1416
- declare function ProvenanceLegend({ bases, className }: ProvenanceLegendProps): react.JSX.Element | null;
1417
-
1418
- /**
1419
- * `SeatPaywall` — the shared "unlock this product" screen every agent app
1420
- * shows when a user has no active seat and has spent past the free tier.
1421
- *
1422
- * Copy contract (design §6.8): the included monthly AI usage is framed as a
1423
- * BENEFIT the buyer receives — never the ratio, never the word "margin", never
1424
- * "we debit 50%". Surface the allowance, hide the economics.
1425
- *
1426
- * Styling contract matches the rest of `web-react`: Tailwind classes over the
1427
- * shared design tokens (`bg-card`, `border-border`, `text-muted-foreground`,
1428
- * `bg-primary`, …); glyphs are inline SVGs; no icon or UI library.
1429
- */
1430
-
1431
- interface SeatPaywallProps {
1432
- /** Human product name shown in the headline, e.g. "Creative". */
1433
- product: string;
1434
- /** Fired when the user clicks the unlock CTA — route them to checkout. When
1435
- * it returns a promise the button shows a pending state and ignores repeat
1436
- * clicks until it settles (no double-charge on a slow checkout open). */
1437
- onCheckout: () => void | Promise<void>;
1438
- /** Monthly seat price in whole dollars. Default 100. */
1439
- priceUsd?: number;
1440
- /** Included monthly AI usage in whole dollars. Default 50. */
1441
- includedUsageUsd?: number;
1442
- /** Platform catalog terms. When present, these override the legacy dollar
1443
- * props and show any introductory period without product-local price copy. */
1444
- offer?: ProductSeatOffer;
1445
- /** Optional one-line value prop under the headline. */
1446
- tagline?: string;
1447
- /** CTA label. Default "Continue to checkout". */
1448
- ctaLabel?: string;
1449
- /** Value-prop bullets. Default = product/usage-derived only; pass your own to
1450
- * supply product-specific value props (the shell bakes no GTM copy). */
1451
- benefits?: ReactNode[];
1452
- /** Optional fine print under the CTA (e.g. "Cancel anytime."). Omitted by default. */
1453
- footnote?: ReactNode;
1454
- }
1455
- /**
1456
- * Centered card paywall. The price line reads
1457
- * "$100/mo · includes $50/mo of AI usage" so the included allowance anchors the
1458
- * value without ever exposing the ratio — and says it ONCE: the default
1459
- * benefits don't restate the usage line the subline already carries, and the
1460
- * CTA is the next step ("Continue to checkout"), not a third repeat of the
1461
- * eyebrow + headline's "Unlock {product}".
1462
- */
1463
- declare function SeatPaywall({ product, onCheckout, priceUsd, includedUsageUsd, offer, tagline, ctaLabel, benefits, footnote, }: SeatPaywallProps): ReactNode;
1464
-
1465
- interface UseInfiniteScrollOptions {
1466
- /** Only fire `onLoadMore` while true (a next page exists, none in flight). */
1467
- enabled: boolean;
1468
- /** Scroll container the sentinel lives in. Defaults to the viewport. */
1469
- root?: RefObject<HTMLElement | null>;
1470
- /** Prefetch distance before the sentinel is actually reached. */
1471
- rootMargin?: string;
1472
- }
1473
- /**
1474
- * Fires `onLoadMore` when a sentinel element scrolls into view. Returns a ref
1475
- * callback for that sentinel (typically the last element in a list).
1476
- *
1477
- * The observer is re-created whenever `enabled` flips, so a short first page
1478
- * that leaves the sentinel on-screen keeps loading: when a load finishes and
1479
- * `enabled` returns to true, the fresh observer re-reads the current
1480
- * intersection state and fires again until the sentinel is pushed off-screen.
1481
- */
1482
- declare function useInfiniteScroll(onLoadMore: () => void, { enabled, root, rootMargin }: UseInfiniteScrollOptions): (node: HTMLElement | null) => void;
1483
- interface SessionPageQuery {
1484
- /** Trimmed search term; empty string means no filter. */
1485
- q: string;
1486
- sort: SessionSort;
1487
- /** `null` for the first page. */
1488
- cursor: string | null;
1489
- /** Aborted when the view changes or the component unmounts. */
1490
- signal: AbortSignal;
1491
- }
1492
- /** Data port — one page of sessions for the current view. */
1493
- type FetchSessionPage = (query: SessionPageQuery) => Promise<SessionPage>;
1494
- interface UseSessionHistoryOptions {
1495
- fetchPage: FetchSessionPage;
1496
- /** Trimmed search term driving the fetch. */
1497
- q: string;
1498
- sort: SessionSort;
1499
- /** SSR page 1 of the default view, so the first paint costs no request. */
1500
- initialPage: SessionPage;
1501
- /** The sort `initialPage` was rendered for. Default `'newest'`. */
1502
- defaultSort?: SessionSort;
1503
- }
1504
- interface SessionHistoryState {
1505
- items: SessionSummary[];
1506
- hasMore: boolean;
1507
- isLoadingFirst: boolean;
1508
- isLoadingMore: boolean;
1509
- isError: boolean;
1510
- loadMore: () => void;
1511
- /** Re-run whichever load failed. */
1512
- retry: () => void;
1513
- /** Refetch page 1 — call after a client-side mutation (e.g. a delete). */
1514
- reload: () => void;
1515
- }
1516
- /**
1517
- * Infinite-scroll data source for the history view. Seeds from `initialPage`
1518
- * for the default view (no fetch) and otherwise fetches page 1 for the current
1519
- * search/sort; `loadMore` appends the next cursor page.
1520
- *
1521
- * Raw promises + `AbortController` rather than a router fetcher, so a filter
1522
- * change cancels in-flight requests, pages accumulate, and a late response from
1523
- * a superseded view is dropped by the monotonic `seq` guard.
1524
- */
1525
- declare function useSessionHistory({ fetchPage, q, sort, initialPage, defaultSort, }: UseSessionHistoryOptions): SessionHistoryState;
1526
- interface SessionActionsOptions {
1527
- /** Persist a new title. Reject to surface the error in the dialog. */
1528
- renameSession: (sessionId: string, title: string) => Promise<void>;
1529
- deleteSession: (sessionId: string) => Promise<void>;
1530
- /** Called after a successful rename/delete — revalidate the rail here. */
1531
- onChanged?: () => void;
1532
- /** Called after deleting the session the user is currently viewing, so the
1533
- * product can navigate away from a route that no longer resolves. */
1534
- onDeletedCurrent?: () => void;
1535
- /** The open session, compared against the delete target. */
1536
- currentSessionId?: string | null;
1537
- /** Product toast/log seam. Errors also render inside the dialog. */
1538
- notify?: (level: 'success' | 'error', message: string) => void;
1539
- labels?: Partial<SessionActionLabels>;
1540
- }
1541
- interface SessionActionLabels {
1542
- renameTitle: string;
1543
- renameField: string;
1544
- renameSubmit: string;
1545
- deleteTitle: string;
1546
- deleteBody: (title: string) => string;
1547
- deleteSubmit: string;
1548
- cancel: string;
1549
- renamed: string;
1550
- deleted: string;
1551
- renameFailed: string;
1552
- deleteFailed: string;
1553
- }
1554
- interface SessionActions {
1555
- openRename: (session: SessionSummary) => void;
1556
- openDelete: (session: SessionSummary) => void;
1557
- /** Render once, anywhere that survives navigation (the layout). */
1558
- dialogs: ReactNode;
1559
- busy: boolean;
1560
- }
1561
- /**
1562
- * Rename + delete for one session, shared by the rail kebab and the history
1563
- * row menu so both drive the same dialogs and the same product mutations.
1564
- *
1565
- * Dialogs are owned here rather than returned as raw state: two surfaces
1566
- * needing the same confirm step is exactly how a product ends up with two
1567
- * subtly different delete confirmations.
1568
- */
1569
- declare function useSessionActions({ renameSession, deleteSession, onChanged, onDeletedCurrent, currentSessionId, notify, labels, }: SessionActionsOptions): SessionActions;
1570
- interface SessionHistoryPanelProps {
1571
- history: SessionHistoryState;
1572
- /** Whether the workspace has any sessions at all — decided by the SSR page,
1573
- * independent of the active search, so filtering to zero shows "no matches"
1574
- * rather than the first-run empty state. */
1575
- hasAnySessions: boolean;
1576
- query: string;
1577
- onQueryChange: (value: string) => void;
1578
- sort: SessionSort;
1579
- onSortChange: (value: SessionSort) => void;
1580
- /** Product route for one session row. */
1581
- hrefForSession: (sessionId: string) => string;
1582
- /** Rendered as the row link. Defaults to an `<a>`; pass a router Link to keep
1583
- * client-side navigation. */
1584
- linkComponent?: LinkLikeComponent;
1585
- /** Ids currently mid-turn — renders the responding treatment. */
1586
- respondingSessionIds?: ReadonlySet<string>;
1587
- onRename?: (session: SessionSummary) => void;
1588
- onDelete?: (session: SessionSummary) => void;
1589
- /** Product-owned mutation for selected rows or a workspace-wide age range. */
1590
- onBulkAction?: (action: SessionBulkAction) => Promise<void>;
1591
- /** Menu wording, so this surface and the rail name the same act the same way
1592
- * — a product whose delete is really an archive says so in both places. */
1593
- renameLabel?: string;
1594
- deleteLabel?: string;
1595
- /**
1596
- * Row actions this shell has no opinion about — pin, categorise, share.
1597
- * Same seam and same ordering as the rail's `SessionRowActions.extraActions`:
1598
- * evaluated per session, placed between rename and delete. This menu is
1599
- * text-only, so `icon` is ignored here and honoured on the rail.
1600
- */
1601
- extraActions?: (session: SessionSummary) => SessionRailAction[];
1602
- /** New-session destination for the header action. Omitted ⇒ no button. */
1603
- newSessionHref?: string;
1604
- title?: string;
1605
- untitledLabel?: string;
1606
- emptyTitle?: string;
1607
- emptyDescription?: string;
1608
- /** Absolute → relative timestamp. Defaults to a compact built-in. */
1609
- formatTimestamp?: (isoDate: string | null) => string;
1610
- /** Max width of the reading column. `'full'` opts out for a product whose
1611
- * surface really is a wide table. Default keeps title and timestamp inside
1612
- * one scannable line rather than at opposite edges of a 1440px viewport. */
1613
- contentWidth?: 'reading' | 'full';
1614
- className?: string;
1615
- }
1616
- type SessionBulkAction = {
1617
- kind: 'selected';
1618
- ids: string[];
1619
- } | {
1620
- kind: 'older-than';
1621
- days: number;
1622
- } | {
1623
- kind: 'newer-than';
1624
- days: number;
1625
- };
1626
- interface LinkLikeProps {
1627
- to: string;
1628
- className?: string;
1629
- children?: ReactNode;
1630
- }
1631
- type LinkLikeComponent = (props: LinkLikeProps) => ReactNode;
1632
- /** Compact relative time. Overridable — a product with its own i18n passes
1633
- * `formatTimestamp` rather than this being the only option. */
1634
- declare function formatSessionTimestamp(isoDate: string | null): string;
1635
- /**
1636
- * The full session history: search, sort, cursor-paged rows with per-row
1637
- * actions, and the states in between (first-run empty, loading, no matches,
1638
- * error + retry).
1639
- *
1640
- * This is the surface the rail's capped list overflows into — the reason the
1641
- * rail can stay short without hiding the user's work.
1642
- */
1643
- declare function SessionHistoryPanel({ history, hasAnySessions, query, onQueryChange, sort, onSortChange, hrefForSession, linkComponent: Link, respondingSessionIds, onRename, onDelete, onBulkAction, renameLabel, deleteLabel, extraActions, newSessionHref, title, untitledLabel, emptyTitle, emptyDescription, formatTimestamp, contentWidth, className, }: SessionHistoryPanelProps): react.JSX.Element;
1644
-
1645
- /**
1646
- * The pure half of the editable record grid: the typed column vocabulary, the
1647
- * per-cell parse/validate rules, display + editor formatting, and the
1648
- * optimistic overlay a caller's rows are projected through.
1649
- *
1650
- * Zero React, zero DOM — a product can validate a row on a worker before it
1651
- * ever reaches storage, and the component in `./record-grid` renders exactly
1652
- * what these functions decide.
1653
- *
1654
- * Every domain word is a caller parameter: the module knows no column names,
1655
- * no currencies, no option sets. What it owns is the mechanism four verticals
1656
- * each re-derived — typed cells, an error a person can act on, and an
1657
- * optimistic edit that can be taken back.
1658
- */
1659
-
1660
- /** The value one cell can hold. `null` is "no value on file". */
1661
- type RecordGridValue = string | number | boolean | null;
1662
- /** Typed outcome for one cell. Callers MUST inspect `succeeded` before reading
1663
- * `value`; nothing here throws. */
1664
- type RecordGridCellOutcome = {
1665
- succeeded: true;
1666
- value: RecordGridValue;
1667
- } | {
1668
- succeeded: false;
1669
- error: string;
1670
- };
1671
- /** Typed outcome for a whole row of inputs (the add form). `cellErrors` is
1672
- * keyed by column id so each control can render its own message. */
1673
- type RecordGridRowOutcome = {
1674
- succeeded: true;
1675
- value: Record<string, RecordGridValue>;
1676
- } | {
1677
- succeeded: false;
1678
- error: string;
1679
- cellErrors: Readonly<Record<string, string>>;
1680
- };
1681
- /** Build a cell success outcome. */
1682
- declare function recordGridOk(value: RecordGridValue): RecordGridCellOutcome;
1683
- /** Build a cell failure outcome carrying the message shown next to the cell. */
1684
- declare function recordGridFail(error: string): RecordGridCellOutcome;
1685
- /**
1686
- * How a value came to sit in a cell. Rendered as the provenance tone.
1687
- *
1688
- * A type alias of `./provenance-model`'s `ProvenanceBasis`, not a lookalike:
1689
- * two vocabularies for the same concept — a grid cell's origin — shipped one
1690
- * day apart and would have drifted the moment either one added a value. The
1691
- * grid gains `asserted` for free (a cell an agent claimed with nothing behind
1692
- * it), where the caller previously had no way to say that.
1693
- */
1694
- type RecordGridSourceBasis = ProvenanceBasis;
1695
- /**
1696
- * Where one cell's value came from. Optional on every row — a grid over data
1697
- * with no lineage renders identically without it.
1698
- */
1699
- interface RecordGridCellSource {
1700
- /** The text in the source that supports this value. */
1701
- quote?: string;
1702
- /** Human name of the source document, message, or system. */
1703
- label?: string;
1704
- /** Click-through to the source. */
1705
- href?: string;
1706
- /** Position inside the source: a page, a line, a span — the caller's words. */
1707
- locator?: string;
1708
- /** How the value got here. Absent renders as `asserted` — the weakest claim
1709
- * in the union — because a caller that stated no basis has established
1710
- * nothing about a document, and an omission must never read as one. */
1711
- basis?: RecordGridSourceBasis;
1712
- }
1713
- /** One option of a `select` column. */
1714
- interface RecordGridSelectOption {
1715
- value: string;
1716
- label: string;
1717
- }
1718
- /** A cell is only editable, rendered, and validated when the column it depends
1719
- * on holds `equals`. This is how a nested sub-form (a vesting schedule behind
1720
- * a "has vesting" toggle) stays a set of flat, individually-typed columns. */
1721
- interface RecordGridDependency {
1722
- column: string;
1723
- equals: RecordGridValue;
1724
- }
1725
- /** Fields every column kind carries. */
1726
- interface RecordGridColumnBase {
1727
- /** Key into a row's `values` bag. */
1728
- id: string;
1729
- /** Column heading, and the accessible name of every control in the column. */
1730
- header: string;
1731
- /** Short hint rendered under the control in the add form. */
1732
- hint?: string;
1733
- /** An empty cell is rejected. */
1734
- required?: boolean;
1735
- /** Cells are editable unless this is `false`. */
1736
- editable?: boolean;
1737
- /** Cell alignment. Numeric kinds default to `right`. */
1738
- align?: 'left' | 'right';
1739
- /** Groups this column under a labelled sub-form in the add form. */
1740
- group?: string;
1741
- /** Only applicable when another column holds a given value. */
1742
- dependsOn?: RecordGridDependency;
1743
- /** Extra rule, run after the kind's own checks pass. Return the message to
1744
- * reject with, or `null` to accept. */
1745
- validate?: (value: RecordGridValue) => string | null;
1746
- /** Column summary rendered in the footer row. */
1747
- footerValue?: (rows: readonly RecordGridRow[]) => RecordGridValue;
1748
- }
1749
- /** Free text, optionally length- or pattern-constrained. */
1750
- interface RecordGridTextColumn extends RecordGridColumnBase {
1751
- kind: 'text';
1752
- minLength?: number;
1753
- maxLength?: number;
1754
- pattern?: RegExp;
1755
- /** Message when `pattern` rejects. Without it the pattern source is shown. */
1756
- patternMessage?: string;
1757
- /** Render a textarea instead of a single-line input. */
1758
- multiline?: boolean;
1759
- }
1760
- /** A plain number. */
1761
- interface RecordGridNumberColumn extends RecordGridColumnBase {
1762
- kind: 'number';
1763
- min?: number;
1764
- max?: number;
1765
- integer?: boolean;
1766
- /** Passed through to the editor's `step`. */
1767
- step?: number;
1768
- }
1769
- /** A money amount. The currency is a caller parameter — this module bakes no
1770
- * domain value, so a product with two currencies declares two columns. */
1771
- interface RecordGridCurrencyColumn extends RecordGridColumnBase {
1772
- kind: 'currency';
1773
- /** ISO 4217 code, e.g. `USD`. */
1774
- currency: string;
1775
- min?: number;
1776
- max?: number;
1777
- /** Fraction digits for display. Defaults to the currency's own. */
1778
- fractionDigits?: number;
1779
- }
1780
- /** A calendar date held as `YYYY-MM-DD`; no time, no zone. */
1781
- interface RecordGridDateColumn extends RecordGridColumnBase {
1782
- kind: 'date';
1783
- /** Earliest accepted date, `YYYY-MM-DD`. */
1784
- min?: string;
1785
- /** Latest accepted date, `YYYY-MM-DD`. */
1786
- max?: string;
1787
- }
1788
- /** One of a closed set of values. */
1789
- interface RecordGridSelectColumn extends RecordGridColumnBase {
1790
- kind: 'select';
1791
- options: readonly RecordGridSelectOption[];
1792
- }
1793
- /** A checkbox. */
1794
- interface RecordGridBooleanColumn extends RecordGridColumnBase {
1795
- kind: 'boolean';
1796
- /** Label for `true`. Defaults to `Yes`. */
1797
- trueLabel?: string;
1798
- /** Label for `false`. Defaults to `No`. */
1799
- falseLabel?: string;
1800
- }
1801
- /** Every column shape the grid renders. */
1802
- type RecordGridColumn = RecordGridTextColumn | RecordGridNumberColumn | RecordGridCurrencyColumn | RecordGridDateColumn | RecordGridSelectColumn | RecordGridBooleanColumn;
1803
- /** One row: an id, a flat value bag keyed by column id, and optional per-cell
1804
- * provenance. A record-backed product maps its fold output straight onto
1805
- * this — one entry per cell, its quote and link in `sources`. */
1806
- interface RecordGridRow {
1807
- id: string;
1808
- values: Readonly<Record<string, RecordGridValue>>;
1809
- /** Per-cell provenance, keyed by column id. */
1810
- sources?: Readonly<Record<string, RecordGridCellSource>>;
1811
- /** No cell in this row may be edited or deleted. */
1812
- readOnly?: boolean;
1813
- /** Accessible name for the row's own controls. Falls back to the first text
1814
- * or select column's value, then the row id. */
1815
- label?: string;
1816
- }
1817
- /** True when the column's dependency (if any) is satisfied by the row's other
1818
- * values. An inapplicable cell is never required, never validated, and never
1819
- * editable. */
1820
- declare function isRecordGridCellApplicable(column: RecordGridColumn, values: Readonly<Record<string, RecordGridValue>>): boolean;
1821
- /** Value equality across the grid's value union, treating `undefined` as
1822
- * `null` so an absent key and an explicit null never read as a change. */
1823
- declare function sameRecordGridValue(a: RecordGridValue | undefined, b: RecordGridValue | undefined): boolean;
1824
- /**
1825
- * Turn what an editor control produced into a typed value. Syntax only —
1826
- * range, length, and membership are {@link validateRecordGridCell}'s job.
1827
- */
1828
- declare function parseRecordGridInput(column: RecordGridColumn, raw: string): RecordGridCellOutcome;
1829
- /**
1830
- * Check one already-typed value against its column. Returns the value the grid
1831
- * should store (empty text normalizes to `null`) or the message a person can
1832
- * act on.
1833
- */
1834
- declare function validateRecordGridCell(column: RecordGridColumn, value: RecordGridValue): RecordGridCellOutcome;
1835
- /** Parse editor text and validate it in one step — what a committing cell
1836
- * editor calls. */
1837
- declare function readRecordGridCell(column: RecordGridColumn, raw: string): RecordGridCellOutcome;
1838
- /**
1839
- * Validate a whole value bag against the columns. Inapplicable cells (an
1840
- * unsatisfied `dependsOn`) are forced to `null` rather than carried, so a
1841
- * sub-form the user turned off cannot smuggle stale values into a write.
1842
- */
1843
- declare function validateRecordGridRow(columns: readonly RecordGridColumn[], values: Readonly<Record<string, RecordGridValue>>): RecordGridRowOutcome;
1844
- /** Display text for a cell. `null` renders as the empty string; the component
1845
- * decides what a missing value looks like. */
1846
- declare function formatRecordGridValue(column: RecordGridColumn, value: RecordGridValue, locale?: string): string;
1847
- /** The text an editor control starts with — the raw value, never the formatted
1848
- * one, so committing an untouched cell is a no-op. */
1849
- declare function recordGridEditorText(column: RecordGridColumn, value: RecordGridValue): string;
1850
- /** Accessible name for a row's own controls. */
1851
- declare function recordGridRowLabel(columns: readonly RecordGridColumn[], row: RecordGridRow): string;
1852
- /** Sum a numeric column over the rows that hold a number. Rows with no value
1853
- * are absent from the sum, not zero — a total over three of five filled cells
1854
- * is the total of what is on file. */
1855
- declare function sumRecordGridColumn(rows: readonly RecordGridRow[], columnId: string): number;
1856
- /**
1857
- * Edits the grid has applied locally but the caller's `rows` prop has not yet
1858
- * caught up with. Every field is what rollback removes: drop the entry and the
1859
- * caller's own data shows through again.
1860
- */
1861
- interface RecordGridOverlay {
1862
- /** rowId → columnId → optimistic value. */
1863
- updates: Readonly<Record<string, Readonly<Record<string, RecordGridValue>>>>;
1864
- /** Rows created locally, in insertion order. */
1865
- created: readonly RecordGridRow[];
1866
- /** Row ids removed locally. */
1867
- removed: readonly string[];
1868
- }
1869
- /** An overlay holding nothing. */
1870
- declare const EMPTY_RECORD_GRID_OVERLAY: RecordGridOverlay;
1871
- /** The rows to render: caller rows minus local deletes, with local cell edits
1872
- * applied, then locally-created rows. */
1873
- declare function projectRecordGridRows(rows: readonly RecordGridRow[], overlay: RecordGridOverlay): RecordGridRow[];
1874
- /** Record one optimistic cell edit. */
1875
- declare function withRecordGridUpdate(overlay: RecordGridOverlay, rowId: string, columnId: string, value: RecordGridValue): RecordGridOverlay;
1876
- /** Take back one optimistic cell edit — the rollback path. */
1877
- declare function withoutRecordGridUpdate(overlay: RecordGridOverlay, rowId: string, columnId: string): RecordGridOverlay;
1878
- /** Adopt a row the writer returned as canonical: for a locally-created row it
1879
- * replaces the draft; for an existing row it replaces the optimistic cells.
1880
- * Either way the draft's pending cell edits go with it — the canonical row IS
1881
- * the answer, and leaving an edit layered over it is how a grid keeps showing
1882
- * a value the server normalized away. */
1883
- declare function withRecordGridServerRow(overlay: RecordGridOverlay, draftId: string, row: RecordGridRow): RecordGridOverlay;
1884
- /** Record an optimistic create. */
1885
- declare function withRecordGridCreated(overlay: RecordGridOverlay, row: RecordGridRow): RecordGridOverlay;
1886
- /** Take back an optimistic create — the rollback path. Cell edits made against
1887
- * the draft go with it; the row they applied to no longer exists anywhere. */
1888
- declare function withoutRecordGridCreated(overlay: RecordGridOverlay, rowId: string): RecordGridOverlay;
1889
- /** Record an optimistic delete. */
1890
- declare function withRecordGridRemoved(overlay: RecordGridOverlay, rowId: string): RecordGridOverlay;
1891
- /** Take back an optimistic delete — the rollback path. */
1892
- declare function withoutRecordGridRemoved(overlay: RecordGridOverlay, rowId: string): RecordGridOverlay;
1893
- /**
1894
- * Drop the overlay entries the caller's own rows have caught up with: a cell
1895
- * whose value now matches, a created row now present, a removed row now gone.
1896
- * Without this an overlay would mask every later refresh of the same cell.
1897
- *
1898
- * Returns the SAME overlay object when nothing settled, so a caller can prune
1899
- * on every render without looping.
1900
- */
1901
- declare function pruneRecordGridOverlay(rows: readonly RecordGridRow[], overlay: RecordGridOverlay): RecordGridOverlay;
1902
-
1903
- /** One committed cell edit, handed to `onUpdate`. */
1904
- interface RecordGridCellChange {
1905
- /** The row as it was BEFORE the edit — what rollback restores. */
1906
- row: RecordGridRow;
1907
- columnId: string;
1908
- value: RecordGridValue;
1909
- /** The full value bag after the edit: what a whole-row write would send. */
1910
- values: Readonly<Record<string, RecordGridValue>>;
1911
- }
1912
- /** Outcome of an update or a delete. `value` optionally carries the server's
1913
- * canonical row, which replaces the optimistic one. */
1914
- type RecordGridWriteOutcome = {
1915
- succeeded: true;
1916
- value?: RecordGridRow;
1917
- } | {
1918
- succeeded: false;
1919
- error: string;
1920
- };
1921
- /** Outcome of a create. The row is REQUIRED on success: a create that does not
1922
- * name the row it wrote leaves the grid unable to address it. */
1923
- type RecordGridCreateOutcome = {
1924
- succeeded: true;
1925
- value: RecordGridRow;
1926
- } | {
1927
- succeeded: false;
1928
- error: string;
1929
- };
1930
- /** Properties for the editable, provenance-aware record grid. */
1931
- interface RecordGridProps {
1932
- /** Column definitions, in render order. */
1933
- columns: readonly RecordGridColumn[];
1934
- /** Fetch state over the caller's rows — `web-react/async`'s
1935
- * `AsyncResourceState`, the same three-state contract every other screen
1936
- * in the shell fetches through. `ready`/`empty`'s value is the base rows;
1937
- * optimistic edits are layered over it and dropped as a later value
1938
- * catches up. `error` always carries `retry` — there is no way to render a
1939
- * failed fetch with no recovery action, by construction. */
1940
- state: AsyncResourceState<readonly RecordGridRow[]>;
1941
- /** Accessible name for the grid. Required — an unnamed grid is unusable with
1942
- * a screen reader. */
1943
- caption: string;
1944
- /** What the empty state says, and what it offers next — `web-react/async`'s
1945
- * `AsyncEmptySpec`, so an empty grid reads in the same words as an empty
1946
- * list or panel elsewhere in the product. */
1947
- empty: AsyncEmptySpec;
1948
- /** Persist one created row. Absent → no add affordance. */
1949
- onCreate?: (values: Readonly<Record<string, RecordGridValue>>) => Promise<RecordGridCreateOutcome>;
1950
- /** Persist one cell edit. Absent → every cell renders read-only. */
1951
- onUpdate?: (change: RecordGridCellChange) => Promise<RecordGridWriteOutcome>;
1952
- /** Delete one row. Absent → no delete affordance. */
1953
- onDelete?: (row: RecordGridRow) => Promise<RecordGridWriteOutcome>;
1954
- /** Starting values for the add form. */
1955
- newRowDefaults?: Readonly<Record<string, RecordGridValue>>;
1956
- /** Label of the add control and of the add form. Defaults to `Add row`. */
1957
- addLabel?: string;
1958
- /** BCP-47 locale for number, currency, and date display. */
1959
- locale?: string;
1960
- /** Rendered above the grid — filters, counts, a product action row. */
1961
- toolbar?: ReactNode;
1962
- /** Skeleton rows in the loading state. Defaults to 3. */
1963
- loadingRowCount?: number;
1964
- className?: string;
1965
- }
1966
- /**
1967
- * The shared editable record table. A row is a flat value bag keyed by column
1968
- * id, so a record store's fold output maps straight on: one cell per entry,
1969
- * its quote and link in `sources`.
1970
- */
1971
- declare function RecordGrid({ columns, caption, state, empty, onCreate, onUpdate, onDelete, newRowDefaults, addLabel, locale, toolbar, loadingRowCount, className, }: RecordGridProps): react.JSX.Element;
1972
-
1973
- /**
1974
- * `Sparkline` — the series behind a number, as inline SVG.
1975
- *
1976
- * `/spend`, `/missions` and the eval lanes all produce a number for today, and
1977
- * every product renders it as text. Text cannot separate "$41, up from $38"
1978
- * from "$41, up from $4" — the same sentence, two different situations — so the
1979
- * reader opens a second surface to find out which one they are in. The series
1980
- * next to the number answers it in one glance.
1981
- *
1982
- * No chart dependency: this subpath is react + `@tangle-network/ui` only, and a
1983
- * polyline is not worth a bundle. What a chart library would give us here is
1984
- * axes, ticks and a tooltip, none of which belong on a 96×24 glyph.
1985
- *
1986
- * The three shapes a hand-rolled sparkline gets wrong, each handled here rather
1987
- * than left to the caller:
1988
- *
1989
- * - **no readings** renders an explicit empty label, never a line. A line
1990
- * along the baseline is a claim — "this metric sat at zero" — and a series
1991
- * nobody has measured yet did not sit anywhere.
1992
- * - **one reading** renders a point. A line needs two coordinates; drawing one
1993
- * from a single reading invents the segment before it.
1994
- * - **equal readings** render flat at MID height. The obvious normalisation
1995
- * divides by `max - min`, which is `0` for a perfectly stable metric, and
1996
- * the resulting `NaN` lands in the `points` attribute — SVG drops the whole
1997
- * polyline, so the metric that never moved is the one that disappears.
1998
- * - **a missing reading renders as a GAP, and the accessible name says so.**
1999
- * A `null` from a hole in a series and a `NaN` from a producer's unguarded
2000
- * division are not smaller series — they are readings nobody has. Deleting
2001
- * them closed the line straight across the hole and announced a count that
2002
- * was short by the number deleted: measured on `[1, NaN, 3]`, one continuous
2003
- * two-point line labelled "2 readings, rising from 1 to 3", with nothing
2004
- * anywhere saying a reading was unreadable. The card's figure slot already
2005
- * refuses to let a non-measurement look measured; the series one line below
2006
- * it holds the same rule. The x axis is the SAMPLE index, so the hole keeps
2007
- * its width, the line breaks at it, and the label carries "N not available".
2008
- *
2009
- * Accessibility: `role="img"` with an `aria-label` naming the metric, its range
2010
- * and its direction. A sparkline with no accessible name is decoration a screen
2011
- * reader cannot report, which would leave the shape — the entire reason the
2012
- * component exists — visible to exactly one kind of reader.
2013
- *
2014
- * Deliberately not animated. `docs/product-surfaces.md` Pattern 4 lists chart
2015
- * draw-on under what this package does not animate: the shape IS the answer,
2016
- * and easing it in taxes every read of a surface people sit in for hours. The
2017
- * card around it arrives (`.agent-arrive`); the line does not draw itself.
2018
- */
2019
-
2020
- /** Where a series ended relative to where it started. */
2021
- type SparklineDirection = 'rising' | 'falling' | 'flat';
2022
- interface SparklinePoint {
2023
- readonly x: number;
2024
- readonly y: number;
2025
- }
2026
- interface SparklineGeometry {
2027
- /** The finite readings, in order — what was actually plotted. */
2028
- readonly readings: readonly number[];
2029
- /** Every plotted point, in order. Positions are on the SAMPLE axis, so a
2030
- * missing reading leaves its width behind rather than closing up. */
2031
- readonly points: readonly SparklinePoint[];
2032
- /** The points split into runs of CONSECUTIVE samples. One run is one stroke:
2033
- * a line drawn across a missing reading states a movement nobody measured. */
2034
- readonly segments: readonly (readonly SparklinePoint[])[];
2035
- /** Samples that carried no usable reading — a `null`, a `NaN`, an infinity.
2036
- * Counted rather than discarded, because the accessible name has to state
2037
- * them: a shorter series announced as a complete one is the silent loss. */
2038
- readonly gaps: number;
2039
- readonly min: number;
2040
- readonly max: number;
2041
- readonly first: number;
2042
- readonly last: number;
2043
- readonly direction: SparklineDirection;
2044
- }
2045
- interface SparklineGeometryOptions {
2046
- width?: number;
2047
- height?: number;
2048
- /** Keeps the stroke and the end dot inside the viewBox instead of clipping
2049
- * them at the extremes, where the interesting readings always are. */
2050
- inset?: number;
2051
- }
2052
- declare const DEFAULT_SPARKLINE_WIDTH = 96;
2053
- declare const DEFAULT_SPARKLINE_HEIGHT = 24;
2054
- /** Only a name, never a metric: it exists so the accessible label is never
2055
- * empty. Every caller in this package passes the metric's own title. */
2056
- declare const DEFAULT_SPARKLINE_LABEL = "Trend";
2057
- declare const DEFAULT_SPARKLINE_EMPTY_LABEL = "No history yet";
2058
- /** Nothing was measurable, which is not the same as nothing was measured yet —
2059
- * and "No history yet" over a series that arrived full of `NaN` reads as the
2060
- * metric being new when the producer is broken. */
2061
- declare const DEFAULT_SPARKLINE_UNAVAILABLE_LABEL = "No readings available";
2062
- /** The package's default number rendering, pinned to `en-US` so a card and its
2063
- * series read the same on every host — a series formatted by the server's
2064
- * locale and a value formatted by the browser's is a defect nobody sees until
2065
- * the decimal separators disagree. */
2066
- declare function formatSparklineValue(value: number): string;
2067
- /**
2068
- * The readings that can be plotted.
2069
- *
2070
- * A `null` from a gap in a series, or a `NaN` from a division a producer did
2071
- * not guard, is not plotted rather than coerced to `0`: plotting a missing
2072
- * reading at the baseline draws a cliff that never happened.
2073
- *
2074
- * This returns the readings ALONE, so it cannot tell a caller how many are
2075
- * missing. That is what {@link SparklineGeometry.gaps} is for, and what the
2076
- * accessible name reports — dropping a sample and then announcing the shorter
2077
- * count as the whole series is the defect, not the filter.
2078
- */
2079
- declare function sparklineReadings(values: readonly number[]): number[];
2080
- /**
2081
- * Plots the series into the viewBox.
2082
- *
2083
- * Pure and exported so the cases that produce a broken chart — nothing, one
2084
- * reading, a flat series, negatives — are unit-testable without a DOM.
2085
- */
2086
- declare function sparklineGeometry(values: readonly number[], { width, height, inset }?: SparklineGeometryOptions): SparklineGeometry;
2087
- /** `"2,14 48,3 94,21"` — the `points` attribute of the polyline. */
2088
- declare function sparklinePointsAttribute(points: readonly SparklinePoint[]): string;
2089
- interface SparklineLabelOptions {
2090
- label?: string;
2091
- format?: (value: number) => string;
2092
- }
2093
- /**
2094
- * The accessible name: metric, how many readings, how many are missing, the
2095
- * range, and the direction.
2096
- *
2097
- * All of it is load-bearing. The range without the direction describes a shape
2098
- * that could have been walked in either order; the direction without the range
2099
- * says "rising" about a metric that moved by a rounding error; and the count
2100
- * without the gaps is the number of readings that SURVIVED announced as the
2101
- * number that were taken — the shape a reader cannot see is exactly the one
2102
- * this sentence exists to carry.
2103
- */
2104
- declare function sparklineLabel(values: readonly number[], { label, format }?: SparklineLabelOptions): string;
2105
- interface SparklineProps {
2106
- values: readonly number[];
2107
- /** Names the metric in the accessible label. */
2108
- label?: string;
2109
- /** Renders a reading in that label; defaults to the package number format. */
2110
- format?: (value: number) => string;
2111
- width?: number;
2112
- height?: number;
2113
- /** Shown instead of a line when the metric has no history yet. */
2114
- emptyLabel?: string;
2115
- /** Shown instead of a line when every sample arrived unreadable — a different
2116
- * state from "no history yet", and one the reader has to be able to tell
2117
- * apart, because one is a new metric and the other is a broken producer. */
2118
- unavailableLabel?: string;
2119
- className?: string;
2120
- }
2121
- /** The series glyph. Strokes in `currentColor`, so tone is the caller's. */
2122
- declare function Sparkline({ values, label, format, width, height, emptyLabel, unavailableLabel, className, }: SparklineProps): ReactElement;
2123
-
2124
- /**
2125
- * `InsightCard` + `InsightDeck` — the number that moved, and the paged deck of
2126
- * them.
2127
- *
2128
- * Every product on this shell computes insights already: `/spend` knows today's
2129
- * burn against yesterday's, `/missions` knows how many runs landed, the eval
2130
- * lanes know a pass rate per release. All of it renders as a line of text, so
2131
- * the reader does the comparison in their head and the series behind the number
2132
- * never reaches the screen at all.
2133
- *
2134
- * Two rules this surface exists to hold:
2135
- *
2136
- * - **A delta needs a baseline.** `previous` absent means no delta is drawn —
2137
- * not a green `+0%`, which is the specific fabrication a hand-rolled card
2138
- * produces when it defaults its baseline to zero, and which reads as "we
2139
- * measured, nothing changed" when the truth is "we have nothing to compare
2140
- * against". {@link insightDelta} returns `null` rather than a zero.
2141
- * - **Direction is not sentiment.** Spend going up and missions going up are
2142
- * the same arrow and opposite news, so tone is a caller declaration
2143
- * (`polarity`), and the default is neutral. A card that paints every rise
2144
- * green teaches the reader to stop reading the label.
2145
- *
2146
- * The deck is built on `web-react/async` rather than a loading boolean, so it
2147
- * inherits that module's invariant instead of restating it: `AsyncView` renders
2148
- * `error` with its message and retry, and `empty` is reachable only from a load
2149
- * that resolved — a failed fetch can never paint "No insights yet"
2150
- * (`docs/async-state-module.md`).
2151
- *
2152
- * Motion: cards arrive with `.agent-arrive`, staggered by `--stagger-index`
2153
- * from the deck, and a page TURN remounts them so the next page arrives as a
2154
- * sequence instead of swapping text under cards that never moved. A REFRESH is
2155
- * the opposite case and gets the opposite treatment — see the deck's own note.
2156
- * Every piece of that is decoration, carries no `data-motion`, and collapses
2157
- * under `prefers-reduced-motion` — the live label included.
2158
- *
2159
- * The live label does NOT opt out, and the reasoning is worth stating because
2160
- * the opposite reads plausible. What tells the reader a figure is still being
2161
- * computed is the WORD (`liveLabel`, "Updating"): it is rendered only while
2162
- * `live`, and a settled card does not render it at all. The sweep through its
2163
- * glyphs is emphasis on a signal that is already there, not the signal. So a
2164
- * reader who asked for less motion still sees the word — static, in the
2165
- * shimmer's resting gradient, still legible, and still disappearing the moment
2166
- * the figure is final. Nothing here overrides a request the reader made.
2167
- */
2168
-
2169
- type InsightDirection = 'up' | 'down' | 'flat';
2170
- /** Which way is good news for THIS metric. `neutral` is the default because it
2171
- * is the only answer that is true for every metric. */
2172
- type InsightPolarity = 'higher-is-better' | 'lower-is-better' | 'neutral';
2173
- type InsightTone = 'positive' | 'negative' | 'neutral';
2174
- interface InsightDelta {
2175
- /** The baseline the move is measured against — rendered, so the delta is
2176
- * never a number floating free of what produced it. */
2177
- readonly previous: number;
2178
- readonly absolute: number;
2179
- /** `null` when the baseline is `0`: a share of nothing is undefined, and
2180
- * "+∞%" or a silently-dropped percentage are both worse than the absolute. */
2181
- readonly percent: number | null;
2182
- readonly direction: InsightDirection;
2183
- }
2184
- /**
2185
- * The move, or `null` when there is no honest one to state.
2186
- *
2187
- * `unknown` inputs on purpose: these arrive from a fetched payload, and the
2188
- * cases that must not produce a delta — a missing baseline, a `null` from a
2189
- * first-ever reading, a `NaN` from a producer's division — are exactly the ones
2190
- * a narrower signature would let through as `0`.
2191
- */
2192
- declare function insightDelta(value: unknown, previous: unknown): InsightDelta | null;
2193
- /** Maps a direction onto good/bad news, which only the caller knows. */
2194
- declare function insightDeltaTone(direction: InsightDirection, polarity?: InsightPolarity): InsightTone;
2195
- /**
2196
- * The delta as words: direction, magnitude, and the baseline it is measured
2197
- * against. Words rather than an arrow plus a bare number, because the arrow is
2198
- * `aria-hidden` and a reader hearing "12%" learns nothing about which way.
2199
- */
2200
- declare function formatInsightDelta(delta: InsightDelta, format?: (value: number) => string): string;
2201
- interface InsightAction {
2202
- label: string;
2203
- onClick: () => void;
2204
- }
2205
- interface InsightCardProps {
2206
- /** What was measured, in the reader's words ("Spend today"). */
2207
- title: string;
2208
- /** The number that moved. A `string` renders verbatim — a total the caller
2209
- * already formatted with its own currency — and takes no delta, because
2210
- * there is nothing to subtract. A non-finite number is not a measurement and
2211
- * renders as {@link INSIGHT_UNAVAILABLE_GLYPH}, never as "NaN" or "∞". */
2212
- value: number | string;
2213
- /** "USD", "runs", "%" — the unit the number is in, beside it rather than
2214
- * glued into it, so the figure stays scannable. */
2215
- unit?: string;
2216
- /** The baseline. Absent ⇒ the card renders the value and no delta. */
2217
- previous?: number;
2218
- polarity?: InsightPolarity;
2219
- /** One number format for the value, the delta and the series, so the three
2220
- * cannot disagree about decimals on the same card. */
2221
- format?: (value: number) => string;
2222
- series?: readonly number[];
2223
- /** Names the series in its accessible label; defaults to the card's title. */
2224
- seriesLabel?: string;
2225
- /** One line of context under the number — what the window is, what is
2226
- * excluded. Not a restatement of the title. */
2227
- description?: string;
2228
- /** The next action for this insight. An element renders as supplied (a link,
2229
- * a dialog trigger); the object form renders the standard button. */
2230
- action?: InsightAction | ReactElement;
2231
- /** The number is still being computed. The label's PRESENCE is the signal, so
2232
- * it reads the same with motion collapsed — see the module note. */
2233
- live?: boolean;
2234
- liveLabel?: string;
2235
- className?: string;
2236
- style?: CSSProperties;
2237
- }
2238
- declare function InsightCard({ title, value, unit, previous, polarity, format, series, seriesLabel, description, action, live, liveLabel, className, style, }: InsightCardProps): ReactElement;
2239
- interface Insight extends InsightCardProps {
2240
- /** Stable across refreshes: it keys the card. Paired with the deck holding
2241
- * the last loaded page across a reload, a stable id is what lets a settled
2242
- * card keep its own DOM node — and therefore not replay its arrival — when
2243
- * a poll returns the same insight. */
2244
- readonly id: string;
2245
- }
2246
- declare const DEFAULT_INSIGHT_PAGE_SIZE = 3;
2247
- /**
2248
- * The page size — ONE definition, read by the count and by the slice.
2249
- *
2250
- * Two definitions is how a deck hides an insight with no error at all: a count
2251
- * that divides by the raw `2.5` claims two pages of a five-card deck, a slice
2252
- * that floors it puts two cards on each, and the fifth card is on no page the
2253
- * reader can reach. Nothing renders wrong; a card is simply gone.
2254
- *
2255
- * A page size is a count of cards, so a fraction, a zero and a negative are not
2256
- * smaller decks — they are caller mistakes, and this normalises them back to the
2257
- * default and says so once per offending value. Normalised rather than thrown
2258
- * because the value is often computed from a measured viewport, where the first
2259
- * paint legitimately produces a `0`: a deck that pages in threes is a far
2260
- * smaller failure than a dashboard that throws during render.
2261
- */
2262
- declare function insightPageSize(pageSize?: number): number;
2263
- /** Always at least one page, so "Page 1 of 0" cannot be rendered. */
2264
- declare function insightPageCount(total: number, pageSize?: number): number;
2265
- /** The items on `page`, with the page clamped into range — a deck whose list
2266
- * shrank under the reader shows the last page that exists, never a blank one. */
2267
- declare function insightPageSlice<T>(items: readonly T[], page: number, pageSize?: number): readonly T[];
2268
- interface InsightDeckProps {
2269
- /** The same five-state contract every other screen fetches through. */
2270
- state: AsyncResourceState<readonly Insight[]>;
2271
- /** Required by `AsyncView`: an empty deck must say what is missing and what
2272
- * to do about it. */
2273
- empty: AsyncEmptySpec | ReactElement;
2274
- /** Names the region for assistive tech and titles nothing visually — the
2275
- * cards carry their own headings. */
2276
- label?: string;
2277
- pageSize?: number;
2278
- loadingLabel?: string;
2279
- retryLabel?: string;
2280
- className?: string;
2281
- /**
2282
- * The page the reader is ON, whatever moved them there.
2283
- *
2284
- * That includes the render-time clamp: a list that shrinks under a reader
2285
- * standing on page 3 leaves them on the last page that exists, and a parent
2286
- * persisting this to a URL or to storage would otherwise keep writing a page
2287
- * number nothing can reach. Reported once per effective page, never twice for
2288
- * the same one.
2289
- */
2290
- onPageChange?: (page: number) => void;
2291
- }
2292
- /**
2293
- * The paged deck.
2294
- *
2295
- * `AsyncView` owns the non-`ready` branches, which is what makes the invariant
2296
- * structural here: the cards are rendered from one branch of that component,
2297
- * and no branch of this one could paint the empty copy over a failure.
2298
- *
2299
- * **A REFRESH DOES NOT REPLACE WHAT IS ON SCREEN.** `useAsyncResource` re-enters
2300
- * `loading` with no value held on every reload, and handing that straight to
2301
- * `AsyncView` swaps the ready subtree for the busy block — which destroys the
2302
- * DOM the reader is standing in. Measured, on a real reload: `document.
2303
- * activeElement` fell to `document.body`, so a keyboard reader mid-page lost
2304
- * their place on every automatic poll; and every settled card was a NEW node, so
2305
- * `.agent-arrive` replayed across the whole visible page — the exact flash this
2306
- * surface's motion rules exist to prevent. Holding the page NUMBER above the
2307
- * boundary fixed the counter and none of that, because the subtree under it was
2308
- * still being torn down.
2309
- *
2310
- * So the deck holds the last insights it rendered and keeps handing them to the
2311
- * SAME `AsyncView` branch while a reload is in flight: same element, same
2312
- * position, same keys — React reuses the nodes, focus stays where the reader put
2313
- * it, and nothing re-animates. `aria-busy` on the region is the signal that a
2314
- * load is in flight; a per-card one is `live` on the card.
2315
- *
2316
- * The bridge is only ever over a WAIT. `error` and `empty` are answers about the
2317
- * resource, so they drop what was held and render their own branch — a failed
2318
- * fetch still cannot paint stale numbers, and the async module's invariant is
2319
- * untouched.
2320
- *
2321
- * It bridges one resource, not one component: if the SUBJECT changes (a
2322
- * different workspace, a different window), give the deck a `key` so it remounts
2323
- * rather than showing the previous subject's numbers while the new ones load.
2324
- */
2325
- declare function InsightDeck({ state, empty, label, pageSize, loadingLabel, retryLabel, className, onPageChange, }: InsightDeckProps): ReactElement;
2326
-
2
+ * `@tangle-network/agent-app/web-react` the shared chat-shell components
3
+ * every agent app's web UI hand-rolls: a model picker over the runtime's
4
+ * model catalogue, a reasoning-effort selector, and a message thread with
5
+ * User/Agent identity, per-message model + cost + tokens/sec metrics,
6
+ * canonical tool rows, and a collapsible thinking section.
7
+ *
8
+ * Works for BOTH chat shapes: router-backed copilots (LoopEvents from
9
+ * `runtime/openai-stream`) and sandbox-backed chatsthe thread renders
10
+ * `ChatUiMessage`s; how they're produced is the app's business.
11
+ *
12
+ * Styling contract: Tailwind classes against the shared design tokens
13
+ * (`bg-card`, `border-border`, `text-muted-foreground`, `bg-primary`, …) that
14
+ * Tangle app shells define. No icon library of its own — the few local glyphs
15
+ * are inline SVGs. Markdown and provider logos are injected (`renderMarkdown`,
16
+ * `renderProviderBadge`).
17
+ *
18
+ * Tool rows compose the canonical run-row grammar from `@tangle-network/ui`
19
+ * (`InlineToolItem` over `RunRowShell`): `chatToolCallPart` adapts each
20
+ * `ChatToolCallInfo` to ui's `ToolPart` (the same adapter pattern ui's own
21
+ * `ToolCallStep` uses), so the chat surface and every other Tangle run view
22
+ * share one row implementation instead of drifting. That makes
23
+ * `@tangle-network/ui` a peer of this subpath.
24
+ */
25
+ import { type ReactNode } from 'react';
26
+ import type { ToolPart } from '@tangle-network/ui/types';
27
+ import { type DurableChatCardsProps } from './durable-chat-cards';
28
+ import { type ChatAttachmentPart } from './chat-attachments';
29
+ import type { WorkProductPersistedPart } from '../work-product/types';
30
+ export * from './chat-stream';
31
+ export * from './chat-interactions';
32
+ export * from './chat-composer';
33
+ export * from './interaction-card-support';
34
+ export * from './interaction-question-card';
35
+ export * from './interaction-plan-card';
36
+ export * from './durable-plan-flow';
37
+ export * from './durable-plan-card';
38
+ export * from './durable-chat-cards';
39
+ export * from './durable-interaction-submit';
40
+ export * from './use-chat-interactions';
41
+ export * from './use-file-mentions';
42
+ export * from './chat-mentions';
43
+ export * from './chat-attachments';
44
+ export * from './message-attachments';
45
+ export * from './use-composer-attachments';
46
+ export * from './provider-logo';
47
+ export * from './harness-glyphs';
48
+ export * from './smooth-text';
49
+ export * from './mission-activity';
50
+ export * from './work-product';
51
+ export * from './provenance';
52
+ export * from './sandbox-terminal';
53
+ export * from './seat-paywall';
54
+ export * from './session-history';
55
+ export * from './record-grid';
56
+ export * from './sparkline';
57
+ export * from './insight-card';
58
+ export { usePopover, usePending, PopoverSurface, POPOVER_SURFACE_ATTR, ModelPicker, EffortPicker, EffortMeter, effortMeterFill, effortLevelLabel, effortLevelsFromIds, reconcileEffortLevels, DEFAULT_EFFORT_LEVELS, EFFORT_METER_SEGMENTS, OVERLAY_SHADOW, type ModelPickerProps, type EffortPickerProps, type EffortLevel, type PopoverSurfaceProps, } from './controls';
59
+ export { AgentSessionControls, type AgentSessionControlsProps, } from './agent-session-controls';
60
+ import type { CatalogModel } from '../runtime/model-catalog';
61
+ export type { CatalogModel } from '../runtime/model-catalog';
2327
62
  /** Describe metrics related to a chat message including model, token counts, and duration */
2328
- interface ChatMessageMetrics {
63
+ export interface ChatMessageMetrics {
2329
64
  modelUsed?: string;
2330
65
  promptTokens?: number;
2331
66
  completionTokens?: number;
2332
67
  durationMs?: number;
2333
68
  }
2334
69
  /** "$0.0042" from token counts × catalogue per-token pricing; null when unknown. */
2335
- declare function formatModelCost(msg: ChatMessageMetrics, models: CatalogModel[]): string | null;
70
+ export declare function formatModelCost(msg: ChatMessageMetrics, models: CatalogModel[]): string | null;
2336
71
  /** "38 tok/s" from completion tokens over first-token→end duration; null when unknown. */
2337
- declare function formatTokensPerSecond(msg: ChatMessageMetrics): string | null;
72
+ export declare function formatTokensPerSecond(msg: ChatMessageMetrics): string | null;
2338
73
  /** One step of a retained tool run (e.g. a sandbox command + its output). */
2339
- interface ToolRunStep {
74
+ export interface ToolRunStep {
2340
75
  at: string;
2341
76
  label: string;
2342
77
  detail?: string;
@@ -2345,7 +80,7 @@ interface ToolRunStep {
2345
80
  /** A retained tool run keyed by the parent message's toolCallId. The product
2346
81
  * persists these server-side (fail-closed: only ids its own loop created)
2347
82
  * and serves them to the drill-in panel. */
2348
- interface ToolRunRecord {
83
+ export interface ToolRunRecord {
2349
84
  toolCallId: string;
2350
85
  toolName: string;
2351
86
  title: string;
@@ -2353,7 +88,7 @@ interface ToolRunRecord {
2353
88
  steps: ToolRunStep[];
2354
89
  }
2355
90
  /** Define properties required to run a drill and handle its closure event */
2356
- interface RunDrillInProps {
91
+ export interface RunDrillInProps {
2357
92
  run: ToolRunRecord;
2358
93
  onClose: () => void;
2359
94
  }
@@ -2362,9 +97,9 @@ interface RunDrillInProps {
2362
97
  * "drill into what the sandbox actually did" view. Follow-ups happen in the
2363
98
  * main chat, never here.
2364
99
  */
2365
- declare function RunDrillIn({ run, onClose }: RunDrillInProps): react.JSX.Element;
100
+ export declare function RunDrillIn({ run, onClose }: RunDrillInProps): import("react").JSX.Element;
2366
101
  /** Describe the structure and state of a tool call within a chat interaction */
2367
- interface ChatToolCallInfo {
102
+ export interface ChatToolCallInfo {
2368
103
  id: string;
2369
104
  name: string;
2370
105
  status: 'running' | 'done' | 'error';
@@ -2377,7 +112,7 @@ interface ChatToolCallInfo {
2377
112
  }
2378
113
  /** Extract `{proposalId, status}` from a tool outcome when it is a proposal
2379
114
  * awaiting human approval; null otherwise. */
2380
- declare function pendingApprovalOf(call: ChatToolCallInfo): {
115
+ export declare function pendingApprovalOf(call: ChatToolCallInfo): {
2381
116
  proposalId: string;
2382
117
  } | null;
2383
118
  /** One ordered piece of an assistant turn: a run of answer text, or a tool
@@ -2385,7 +120,7 @@ declare function pendingApprovalOf(call: ChatToolCallInfo): {
2385
120
  * is rendered in order — interleaving text and tool rows — so the agent's
2386
121
  * pre- and post-tool reasoning reads chronologically instead of as one text
2387
122
  * blob with the tool rows collected after it. */
2388
- type ChatMessageSegment = {
123
+ export type ChatMessageSegment = {
2389
124
  kind: 'text';
2390
125
  content: string;
2391
126
  } | {
@@ -2393,7 +128,7 @@ type ChatMessageSegment = {
2393
128
  call: ChatToolCallInfo;
2394
129
  };
2395
130
  /** Describe the structure and properties of a chat message with roles, content, and optional metadata */
2396
- interface ChatUiMessage extends ChatMessageMetrics {
131
+ export interface ChatUiMessage extends ChatMessageMetrics {
2397
132
  id: string;
2398
133
  role: 'user' | 'assistant' | 'system';
2399
134
  content: string;
@@ -2408,7 +143,7 @@ interface ChatUiMessage extends ChatMessageMetrics {
2408
143
  parts?: Array<Record<string, unknown>>;
2409
144
  }
2410
145
  /** Define properties for rendering chat messages with optional models, markdown, extras, and durable cards */
2411
- interface ChatMessagesProps {
146
+ export interface ChatMessagesProps {
2412
147
  messages: ChatUiMessage[];
2413
148
  /** Shared reading scale for both user and assistant prose. Defaults to 16px
2414
149
  * at a 1.6 line height; `large` uses 17px at the same leading without
@@ -2477,7 +212,7 @@ interface ChatMessagesProps {
2477
212
  }
2478
213
  /** One starting "door" in the chat first-run state — a concrete, labeled action
2479
214
  * (start from a template, do it by hand, ask the agent), not a placeholder. */
2480
- interface ChatEmptyDoor {
215
+ export interface ChatEmptyDoor {
2481
216
  label: string;
2482
217
  description?: string;
2483
218
  onSelect: () => void;
@@ -2485,7 +220,7 @@ interface ChatEmptyDoor {
2485
220
  icon?: ReactNode;
2486
221
  }
2487
222
  /** Define properties for rendering the chat empty state with customizable text and starting doors */
2488
- interface ChatEmptyStateProps {
223
+ export interface ChatEmptyStateProps {
2489
224
  /** Product name shown next to the Tangle mark. Default "Agent". */
2490
225
  productName?: string;
2491
226
  /** Headline. Default frames delegation, not messaging. */
@@ -2500,15 +235,15 @@ interface ChatEmptyStateProps {
2500
235
  * up to three concrete doors. Replaces the blank thread that read as "empty or
2501
236
  * broken". Concrete + actionable — never a "coming soon" placeholder.
2502
237
  */
2503
- declare function ChatEmptyState({ productName, headline, subline, doors, }: ChatEmptyStateProps): react.JSX.Element;
238
+ export declare function ChatEmptyState({ productName, headline, subline, doors, }: ChatEmptyStateProps): import("react").JSX.Element;
2504
239
  /** Handle approval and rejection actions for proposals with asynchronous support */
2505
- interface ProposalApprovalHandlers {
240
+ export interface ProposalApprovalHandlers {
2506
241
  onApprove: (proposalId: string, toolCallId: string) => void | Promise<void>;
2507
242
  onReject: (proposalId: string, toolCallId: string) => void | Promise<void>;
2508
243
  }
2509
244
  /** Per-tool custom detail renderers for the expanded card body — keyed by
2510
245
  * tool name. Return null to fall back to the generic detail view. */
2511
- type ToolDetailRenderers = Record<string, (call: ChatToolCallInfo, message: ChatUiMessage) => ReactNode>;
246
+ export type ToolDetailRenderers = Record<string, (call: ChatToolCallInfo, message: ChatUiMessage) => ReactNode>;
2512
247
  /**
2513
248
  * Adapt a chat tool call to the canonical `@tangle-network/ui` `ToolPart`, so
2514
249
  * the row renders through ui's `InlineToolItem` — one run-row grammar shared
@@ -2518,12 +253,12 @@ type ToolDetailRenderers = Record<string, (call: ChatToolCallInfo, message: Chat
2518
253
  * every other tool keeps its real name. agent-app carries no per-call timings,
2519
254
  * so `state.time` stays unset and the row shows no duration.
2520
255
  */
2521
- declare function chatToolCallPart(call: ChatToolCallInfo): ToolPart;
256
+ export declare function chatToolCallPart(call: ChatToolCallInfo): ToolPart;
2522
257
  /** Whole seconds elapsed while `active`, ticking once a second. Powers the live
2523
258
  * "thinking" timers (the pre-first-token row and the reasoning box) so a long
2524
259
  * thinking gap shows progress instead of a frozen label. Counts from when
2525
260
  * `active` first turns true; freezes when it clears. */
2526
- declare function useThinkingSeconds(active: boolean): number;
261
+ export declare function useThinkingSeconds(active: boolean): number;
2527
262
  /**
2528
263
  * The message thread: one centered column; user messages are right-aligned
2529
264
  * bubbles with a User label; agent messages carry an Agent meta line with
@@ -2531,6 +266,4 @@ declare function useThinkingSeconds(active: boolean): number;
2531
266
  * tool rows. `chrome="quiet"` opts into the label-free variant: the
2532
267
  * label/meta row becomes a hover-revealed meta lane under each row.
2533
268
  */
2534
- declare function ChatMessages({ messages, messageSize, chrome, models, renderMarkdown, renderExtras, durableCards, userLabel, agentLabel, loading, approval, onToolCallClick, toolRenderers, error, onRetry, renderEmpty, emptyState, header, resolveAttachmentUrl, workProductCards, }: ChatMessagesProps): react.JSX.Element;
2535
-
2536
- export { type ActivityTone, type AgentActivityPage, AgentActivityPanel, type AgentActivityPanelProps, type AgentActivityRecord, type AttachmentFileResult, CatalogModel, ChatAttachmentInput, ChatAttachmentKind, ChatAttachmentPart, ChatComposer, type ChatComposerProps, type ChatEmptyDoor, ChatEmptyState, type ChatEmptyStateProps, ChatInteraction, ChatInteractionField, type ChatInteractionRestoreMode, ChatInteractionStatus, ChatMentionPart, type ChatMessageMetrics, type ChatMessageSegment, ChatMessages, type ChatMessagesProps, ChatSelectField, type ChatStreamCallbacks, type ChatStreamToolCall, type ChatStreamToolResult, type ChatToolCallInfo, type ChatUiMessage, type ComposerFile, type ComposerFilePart, type ComposerSendFailure, type ComposerSendHandler, type ComposerSendOutcome, type ComposerSendPartsHandler, type ComposerSendRejected, type ComposerSendResult, type ConsumeChatStreamResult, DEFAULT_INSIGHT_PAGE_SIZE, DEFAULT_PROVENANCE_CONFIDENCE_POLICY, DEFAULT_SPARKLINE_EMPTY_LABEL, DEFAULT_SPARKLINE_HEIGHT, DEFAULT_SPARKLINE_LABEL, DEFAULT_SPARKLINE_UNAVAILABLE_LABEL, DEFAULT_SPARKLINE_WIDTH, type DurableChatCard, DurableChatCards, type DurableChatCardsProps, type DurableInteractionAnswerSubmitterOptions, DurablePlanCard, type DurablePlanCardProps, DurablePlanClientError, type DurablePlanCurrentInput, type DurablePlanDecision, type DurablePlanDecisionClient, type DurablePlanDecisionClientOptions, type DurablePlanDecisionInput, type DurablePlanDecisionResult, type DurablePlanFollowUpReceipt, EMPTY_RECORD_GRID_OVERLAY, EvidenceLineageTable, type EvidenceLineageTableProps, ExceptionList, type ExceptionListProps, type FetchSessionPage, type FieldValues, FlowWaterfall, type FlowWaterfallProps, HarnessGlyph, type HarnessGlyphProps, INTERACTION_SUBMIT_TIMEOUT_MESSAGE, INTERACTION_SUBMIT_TIMEOUT_MS, type Insight, type InsightAction, InsightCard, type InsightCardProps, InsightDeck, type InsightDeckProps, type InsightDelta, type InsightDirection, type InsightPolarity, type InsightTone, InteractionActionButton, type InteractionAnswerSubmission, type InteractionAnswerSubmitterOptions, InteractionAnswers, type InteractionAttemptStore, InteractionBadge, type InteractionBadgeVariant, InteractionCancelData, InteractionPlanCard, type InteractionPlanCardProps, InteractionQuestionCard, type InteractionQuestionCardProps, InteractionRequestWire, type InteractionSubmitResult, type LinkLikeComponent, type LinkLikeProps, type MentionTextSegment, MessageAttachments, type MessageAttachmentsProps, MissionActivityLane, type MissionActivityLaneProps, PROVENANCE_BASES, type ProposalApprovalHandlers, type ProvenanceBasis, type ProvenanceBasisMeta, type ProvenanceConfidencePolicy, type ProvenanceGap, type ProvenanceGapKind, ProvenanceLegend, type ProvenanceLegendProps, type ProvenanceRecord, type ProvenanceSource, type ProvenanceSourceStatus, ProvenanceStamp, type ProvenanceStampProps, type ProvenanceStanding, type ProvenanceStandingMeta, ProvenanceValue, type ProvenanceValueProps, ProviderLogo, type ProviderLogoProps, QualityCheckList, type QualityCheckListProps, QuestionOptionList, type QuestionOptionListProps, RecordGrid, type RecordGridBooleanColumn, type RecordGridCellChange, type RecordGridCellOutcome, type RecordGridCellSource, type RecordGridColumn, type RecordGridColumnBase, type RecordGridCreateOutcome, type RecordGridCurrencyColumn, type RecordGridDateColumn, type RecordGridDependency, type RecordGridNumberColumn, type RecordGridOverlay, type RecordGridProps, type RecordGridRow, type RecordGridRowOutcome, type RecordGridSelectColumn, type RecordGridSelectOption, type RecordGridSourceBasis, type RecordGridTextColumn, type RecordGridValue, type RecordGridWriteOutcome, type RestoreChatInteractionsOptions, ReviewQueueItem, type ReviewQueuePage, ReviewQueuePanel, type ReviewQueuePanelProps, ReviewQueueState, RunDrillIn, type RunDrillInProps, SeatPaywall, type SeatPaywallProps, type SessionActionLabels, type SessionActions, type SessionActionsOptions, type SessionBulkAction, SessionHistoryPanel, type SessionHistoryPanelProps, type SessionHistoryState, type SessionPageQuery, type SmoothRevealOptions, Sparkline, type SparklineDirection, type SparklineGeometry, type SparklineGeometryOptions, type SparklineLabelOptions, type SparklinePoint, type SparklineProps, type StreamChatOptions, type SubmitInteractionAnswer, type ToolDetailRenderers, type ToolRunRecord, type ToolRunStep, type UseChatInteractionsOptions, type UseChatInteractionsResult, type UseComposerAttachmentsOptions, type UseComposerAttachmentsResult, type UseDurablePlanFlowOptions, type UseDurablePlanFlowResult, type UseInfiniteScrollOptions, type UseSessionHistoryOptions, type WaterfallRow, WorkProductCard, type WorkProductCardProps, __resetAttachmentFileCacheForTests, activityTone, buildAnswerData, cancelChatInteraction, chatToolCallPart, consumeChatStream, createDurableInteractionAnswerSubmitter, createDurablePlanDecisionClient, createInteractionAnswerSubmitter, createMemoryInteractionAttemptStore, createSessionInteractionAttemptStore, describeProvenance, describeProvenanceSourceStatus, dispatchChatStreamLine, durableChatCardsFromParts, fieldAnswer, fieldValuesFromAnswers, formatActivityCost, formatActivityDuration, formatInsightDelta, formatModelCost, formatRecordGridValue, formatSessionTimestamp, formatSparklineValue, formatTokensPerSecond, hasSecretField, hydrateChatInteractions, insightDelta, insightDeltaTone, insightPageCount, insightPageSize, insightPageSlice, interactionStatusLabels, interactionSubmissionSignature, interactionTerminalNotes, isLateAnswerableStatus, isRecordGridCellApplicable, lateAnswerMessage, loadAttachmentFile, loadingProvenanceSources, mergeActivityPages, mergeReviewQueuePages, nextRevealCount, parseRecordGridInput, pendingApprovalOf, projectRecordGridRows, provenanceBasisMeta, provenanceGaps, provenanceNextMove, provenanceStandingMeta, provenanceTriggerLabel, pruneRecordGridOverlay, readRecordGridCell, recordGridEditorText, recordGridFail, recordGridOk, recordGridRowLabel, resolveChatInteraction, resolveProvenanceStanding, responseErrorMessage, restoreChatInteractions, reviewQueueStateLabel, rollUpProvenanceStanding, sameRecordGridValue, segmentMentionContent, settleInteractionSubmit, sparklineGeometry, sparklineLabel, sparklinePointsAttribute, sparklineReadings, standingFromConfidence, streamChatTurn, sumRecordGridColumn, terminalizePendingChatInteractions, triggerAttachmentDownload, upsertChatInteraction, useChatInteractions, useComposerAttachments, useDurablePlanFlow, useInfiniteScroll, useSessionActions, useSessionHistory, useSmoothText, useThinkingSeconds, validateRecordGridCell, validateRecordGridRow, waterfallLayout, weakerProvenanceStanding, withRecordGridCreated, withRecordGridRemoved, withRecordGridServerRow, withRecordGridUpdate, withoutRecordGridCreated, withoutRecordGridRemoved, withoutRecordGridUpdate, workProductPartsFromMessageParts, workProductStatusLabel };
269
+ export declare function ChatMessages({ messages, messageSize, chrome, models, renderMarkdown, renderExtras, durableCards, userLabel, agentLabel, loading, approval, onToolCallClick, toolRenderers, error, onRetry, renderEmpty, emptyState, header, resolveAttachmentUrl, workProductCards, }: ChatMessagesProps): import("react").JSX.Element;