@adecore/agents-react 0.0.1 → 0.17.0-beta.2

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 (513) hide show
  1. package/LICENSE +110 -0
  2. package/README.md +61 -0
  3. package/dist/agents/AccountDot.d.ts +4 -0
  4. package/dist/agents/AccountDot.js +8 -0
  5. package/dist/agents/AgentIcon.d.ts +6 -0
  6. package/dist/agents/AgentIcon.js +20 -0
  7. package/dist/agents/ModelOptionControl.d.ts +15 -0
  8. package/dist/agents/ModelOptionControl.js +33 -0
  9. package/dist/agents/ProviderLogo.d.ts +8 -0
  10. package/dist/agents/ProviderLogo.js +8 -0
  11. package/dist/agents/account-limits.d.ts +7 -0
  12. package/dist/agents/account-limits.js +40 -0
  13. package/dist/agents/accounts.d.ts +22 -0
  14. package/dist/agents/accounts.js +113 -0
  15. package/dist/agents/model-name.d.ts +12 -0
  16. package/dist/agents/model-name.js +56 -0
  17. package/dist/agents/model-options.d.ts +5 -0
  18. package/dist/agents/model-options.js +15 -0
  19. package/dist/agents/provider-paths.d.ts +2 -0
  20. package/dist/agents/provider-paths.js +8 -0
  21. package/dist/agents/status-look.d.ts +13 -0
  22. package/dist/agents/status-look.js +24 -0
  23. package/dist/chat/account-choice.d.ts +11 -0
  24. package/dist/chat/account-choice.js +30 -0
  25. package/dist/chat/actions.d.ts +6 -0
  26. package/dist/chat/actions.js +68 -0
  27. package/dist/chat/activity.d.ts +5 -0
  28. package/dist/chat/activity.js +6 -0
  29. package/dist/chat/attachments.d.ts +23 -0
  30. package/dist/chat/attachments.js +86 -0
  31. package/dist/chat/bookmarks.d.ts +14 -0
  32. package/dist/chat/bookmarks.js +73 -0
  33. package/dist/chat/chat-client.d.ts +55 -0
  34. package/dist/chat/chat-client.js +279 -0
  35. package/dist/chat/chat-references.d.ts +5 -0
  36. package/dist/chat/chat-references.js +5 -0
  37. package/dist/chat/drafts.d.ts +29 -0
  38. package/dist/chat/drafts.js +116 -0
  39. package/dist/chat/forks.d.ts +2 -0
  40. package/dist/chat/forks.js +28 -0
  41. package/dist/chat/guards.d.ts +12 -0
  42. package/dist/chat/guards.js +69 -0
  43. package/dist/chat/logic/ansi.d.ts +13 -0
  44. package/dist/chat/logic/ansi.js +185 -0
  45. package/dist/chat/logic/answers.d.ts +1 -0
  46. package/dist/chat/logic/answers.js +8 -0
  47. package/dist/chat/logic/bookmarks.d.ts +5 -0
  48. package/dist/chat/logic/bookmarks.js +33 -0
  49. package/dist/chat/logic/context-usage.d.ts +12 -0
  50. package/dist/chat/logic/context-usage.js +21 -0
  51. package/dist/chat/logic/fork.d.ts +45 -0
  52. package/dist/chat/logic/fork.js +148 -0
  53. package/dist/chat/logic/handback.d.ts +2 -0
  54. package/dist/chat/logic/handback.js +8 -0
  55. package/dist/chat/logic/json.d.ts +1 -0
  56. package/dist/chat/logic/json.js +4 -0
  57. package/dist/chat/logic/limit.d.ts +7 -0
  58. package/dist/chat/logic/limit.js +34 -0
  59. package/dist/chat/logic/resume-compaction.d.ts +14 -0
  60. package/dist/chat/logic/resume-compaction.js +47 -0
  61. package/dist/chat/logic/scrubber.d.ts +50 -0
  62. package/dist/chat/logic/scrubber.js +220 -0
  63. package/dist/chat/logic/thread-cards.d.ts +3 -0
  64. package/dist/chat/logic/thread-cards.js +59 -0
  65. package/dist/chat/logic/timeline-copy.d.ts +4 -0
  66. package/dist/chat/logic/timeline-copy.js +59 -0
  67. package/dist/chat/logic/timeline-target.d.ts +12 -0
  68. package/dist/chat/logic/timeline-target.js +34 -0
  69. package/dist/chat/logic/timeline.d.ts +115 -0
  70. package/dist/chat/logic/timeline.js +343 -0
  71. package/dist/chat/logic/tool-catalog.d.ts +10 -0
  72. package/dist/chat/logic/tool-catalog.js +44 -0
  73. package/dist/chat/logic/tools.d.ts +15 -0
  74. package/dist/chat/logic/tools.js +82 -0
  75. package/dist/chat/logic/welcome.d.ts +2 -0
  76. package/dist/chat/logic/welcome.js +10 -0
  77. package/dist/chat/logic/workflow.d.ts +14 -0
  78. package/dist/chat/logic/workflow.js +47 -0
  79. package/dist/chat/mentions.d.ts +65 -0
  80. package/dist/chat/mentions.js +184 -0
  81. package/dist/chat/persisted-json.d.ts +5 -0
  82. package/dist/chat/persisted-json.js +58 -0
  83. package/dist/chat/preferences.d.ts +27 -0
  84. package/dist/chat/preferences.js +139 -0
  85. package/dist/chat/quote.d.ts +2 -0
  86. package/dist/chat/quote.js +25 -0
  87. package/dist/chat/recent-messages.d.ts +17 -0
  88. package/dist/chat/recent-messages.js +36 -0
  89. package/dist/chat/resume-compaction-dismissals.d.ts +3 -0
  90. package/dist/chat/resume-compaction-dismissals.js +14 -0
  91. package/dist/chat/runtime-modes.d.ts +4 -0
  92. package/dist/chat/runtime-modes.js +15 -0
  93. package/dist/chat/stash.d.ts +24 -0
  94. package/dist/chat/stash.js +91 -0
  95. package/dist/chat/subagent-conversation.d.ts +41 -0
  96. package/dist/chat/subagent-conversation.js +167 -0
  97. package/dist/chat/subagent-list.d.ts +19 -0
  98. package/dist/chat/subagent-list.js +106 -0
  99. package/dist/chat/subagent-support.d.ts +6 -0
  100. package/dist/chat/subagent-support.js +14 -0
  101. package/dist/chat/subagent-view.d.ts +35 -0
  102. package/dist/chat/subagent-view.js +96 -0
  103. package/dist/chat/thumbnails.d.ts +10 -0
  104. package/dist/chat/thumbnails.js +89 -0
  105. package/dist/chat/timeline-flash.d.ts +12 -0
  106. package/dist/chat/timeline-flash.js +16 -0
  107. package/dist/chat/timeline-scroll.d.ts +27 -0
  108. package/dist/chat/timeline-scroll.js +152 -0
  109. package/dist/chat/ui/AccountPill.d.ts +3 -0
  110. package/dist/chat/ui/AccountPill.js +23 -0
  111. package/dist/chat/ui/AnsiOutput.d.ts +5 -0
  112. package/dist/chat/ui/AnsiOutput.js +9 -0
  113. package/dist/chat/ui/BookmarkMarker.d.ts +8 -0
  114. package/dist/chat/ui/BookmarkMarker.js +57 -0
  115. package/dist/chat/ui/BookmarkSubmenu.d.ts +3 -0
  116. package/dist/chat/ui/BookmarkSubmenu.js +33 -0
  117. package/dist/chat/ui/ChatActivity.d.ts +7 -0
  118. package/dist/chat/ui/ChatActivity.js +84 -0
  119. package/dist/chat/ui/ChatReferenceChip.d.ts +4 -0
  120. package/dist/chat/ui/ChatReferenceChip.js +16 -0
  121. package/dist/chat/ui/CodeBlock.d.ts +4 -0
  122. package/dist/chat/ui/CodeBlock.js +132 -0
  123. package/dist/chat/ui/Composer.d.ts +15 -0
  124. package/dist/chat/ui/Composer.js +856 -0
  125. package/dist/chat/ui/ComposerInput.d.ts +29 -0
  126. package/dist/chat/ui/ComposerInput.js +127 -0
  127. package/dist/chat/ui/DiffPool.d.ts +5 -0
  128. package/dist/chat/ui/DiffPool.js +26 -0
  129. package/dist/chat/ui/EditDiff.d.ts +4 -0
  130. package/dist/chat/ui/EditDiff.js +21 -0
  131. package/dist/chat/ui/FadingWords.d.ts +3 -0
  132. package/dist/chat/ui/FadingWords.js +5 -0
  133. package/dist/chat/ui/ImageView.d.ts +6 -0
  134. package/dist/chat/ui/ImageView.js +81 -0
  135. package/dist/chat/ui/LimitState.d.ts +8 -0
  136. package/dist/chat/ui/LimitState.js +112 -0
  137. package/dist/chat/ui/Markdown.d.ts +18 -0
  138. package/dist/chat/ui/Markdown.js +159 -0
  139. package/dist/chat/ui/MessageActions.d.ts +9 -0
  140. package/dist/chat/ui/MessageActions.js +53 -0
  141. package/dist/chat/ui/Pickers.d.ts +21 -0
  142. package/dist/chat/ui/Pickers.js +111 -0
  143. package/dist/chat/ui/PromptComposer.d.ts +13 -0
  144. package/dist/chat/ui/PromptComposer.js +56 -0
  145. package/dist/chat/ui/QuoteButton.d.ts +7 -0
  146. package/dist/chat/ui/QuoteButton.js +74 -0
  147. package/dist/chat/ui/ResumeCompactionDock.d.ts +5 -0
  148. package/dist/chat/ui/ResumeCompactionDock.js +14 -0
  149. package/dist/chat/ui/RunSettings.d.ts +28 -0
  150. package/dist/chat/ui/RunSettings.js +153 -0
  151. package/dist/chat/ui/Scrubber.d.ts +17 -0
  152. package/dist/chat/ui/Scrubber.js +118 -0
  153. package/dist/chat/ui/SubagentControls.d.ts +11 -0
  154. package/dist/chat/ui/SubagentControls.js +36 -0
  155. package/dist/chat/ui/SubagentInfo.d.ts +4 -0
  156. package/dist/chat/ui/SubagentInfo.js +34 -0
  157. package/dist/chat/ui/SubagentStopButton.d.ts +7 -0
  158. package/dist/chat/ui/SubagentStopButton.js +34 -0
  159. package/dist/chat/ui/SubagentTimeline.d.ts +4 -0
  160. package/dist/chat/ui/SubagentTimeline.js +107 -0
  161. package/dist/chat/ui/Timeline.d.ts +6 -0
  162. package/dist/chat/ui/Timeline.js +424 -0
  163. package/dist/chat/ui/TimelineMenu.d.ts +12 -0
  164. package/dist/chat/ui/TimelineMenu.js +54 -0
  165. package/dist/chat/ui/UnifiedDiff.d.ts +11 -0
  166. package/dist/chat/ui/UnifiedDiff.js +66 -0
  167. package/dist/chat/ui/UploadThumb.d.ts +4 -0
  168. package/dist/chat/ui/UploadThumb.js +11 -0
  169. package/dist/chat/ui/Welcome.d.ts +4 -0
  170. package/dist/chat/ui/Welcome.js +16 -0
  171. package/dist/chat/ui/chips.d.ts +4 -0
  172. package/dist/chat/ui/chips.js +11 -0
  173. package/dist/chat/ui/code-lines.d.ts +18 -0
  174. package/dist/chat/ui/code-lines.js +46 -0
  175. package/dist/chat/ui/code-streaming.d.ts +1 -0
  176. package/dist/chat/ui/code-streaming.js +3 -0
  177. package/dist/chat/ui/code-theme.d.ts +3 -0
  178. package/dist/chat/ui/code-theme.js +12 -0
  179. package/dist/chat/ui/composer/chips.d.ts +6 -0
  180. package/dist/chat/ui/composer/chips.js +31 -0
  181. package/dist/chat/ui/composer/editor.d.ts +11 -0
  182. package/dist/chat/ui/composer/editor.js +98 -0
  183. package/dist/chat/ui/composer/insert.d.ts +2 -0
  184. package/dist/chat/ui/composer/insert.js +19 -0
  185. package/dist/chat/ui/composer/keys.d.ts +30 -0
  186. package/dist/chat/ui/composer/keys.js +100 -0
  187. package/dist/chat/ui/diff-theme.d.ts +2 -0
  188. package/dist/chat/ui/diff-theme.js +20 -0
  189. package/dist/chat/ui/file-links.d.ts +5 -0
  190. package/dist/chat/ui/file-links.js +20 -0
  191. package/dist/chat/ui/find-reveal.d.ts +7 -0
  192. package/dist/chat/ui/find-reveal.js +13 -0
  193. package/dist/chat/ui/full-diff.d.ts +6 -0
  194. package/dist/chat/ui/full-diff.js +19 -0
  195. package/dist/chat/ui/icons.d.ts +4 -0
  196. package/dist/chat/ui/icons.js +20 -0
  197. package/dist/chat/ui/markdown-blocks.d.ts +6 -0
  198. package/dist/chat/ui/markdown-blocks.js +103 -0
  199. package/dist/chat/ui/quote-selection.d.ts +3 -0
  200. package/dist/chat/ui/quote-selection.js +46 -0
  201. package/dist/chat/ui/rehype-chips.d.ts +23 -0
  202. package/dist/chat/ui/rehype-chips.js +32 -0
  203. package/dist/chat/ui/rehype-fade.d.ts +23 -0
  204. package/dist/chat/ui/rehype-fade.js +36 -0
  205. package/dist/chat/ui/remark-html-as-text.d.ts +8 -0
  206. package/dist/chat/ui/remark-html-as-text.js +26 -0
  207. package/dist/chat/ui/reply-context.d.ts +5 -0
  208. package/dist/chat/ui/reply-context.js +2 -0
  209. package/dist/chat/ui/reveal.d.ts +13 -0
  210. package/dist/chat/ui/reveal.js +114 -0
  211. package/dist/chat/ui/rows/ForksRow.d.ts +4 -0
  212. package/dist/chat/ui/rows/ForksRow.js +38 -0
  213. package/dist/chat/ui/rows/MessageRows.d.ts +40 -0
  214. package/dist/chat/ui/rows/MessageRows.js +204 -0
  215. package/dist/chat/ui/rows/Rows.d.ts +12 -0
  216. package/dist/chat/ui/rows/Rows.js +61 -0
  217. package/dist/chat/ui/rows/SubagentRow.d.ts +17 -0
  218. package/dist/chat/ui/rows/SubagentRow.js +101 -0
  219. package/dist/chat/ui/rows/TaskRow.d.ts +8 -0
  220. package/dist/chat/ui/rows/TaskRow.js +63 -0
  221. package/dist/chat/ui/rows/WorkRows.d.ts +47 -0
  222. package/dist/chat/ui/rows/WorkRows.js +168 -0
  223. package/dist/chat/ui/rows/WorkflowRow.d.ts +8 -0
  224. package/dist/chat/ui/rows/WorkflowRow.js +48 -0
  225. package/dist/chat/ui/rows/row-rhythm.d.ts +6 -0
  226. package/dist/chat/ui/rows/row-rhythm.js +34 -0
  227. package/dist/chat/ui/useToggleSet.d.ts +6 -0
  228. package/dist/chat/ui/useToggleSet.js +25 -0
  229. package/dist/host.d.ts +195 -0
  230. package/dist/host.js +55 -0
  231. package/dist/lazy.d.ts +6 -0
  232. package/dist/lazy.js +57 -0
  233. package/dist/locales/en/agent-chat.json +446 -0
  234. package/dist/locales/en/agent-prompts.json +42 -0
  235. package/dist/locales/en/agent-providers.json +131 -0
  236. package/dist/locales/en/agent-usage.json +131 -0
  237. package/dist/locales/nl/agent-chat.json +446 -0
  238. package/dist/locales/nl/agent-prompts.json +42 -0
  239. package/dist/locales/nl/agent-providers.json +131 -0
  240. package/dist/locales/nl/agent-usage.json +131 -0
  241. package/dist/locales.d.ts +5 -0
  242. package/dist/locales.js +20 -0
  243. package/dist/mounted-registry.d.ts +7 -0
  244. package/dist/mounted-registry.js +39 -0
  245. package/dist/port-transport.d.ts +6 -0
  246. package/dist/port-transport.js +129 -0
  247. package/dist/prompts/logic/focus.d.ts +2 -0
  248. package/dist/prompts/logic/focus.js +23 -0
  249. package/dist/prompts/logic/keys.d.ts +42 -0
  250. package/dist/prompts/logic/keys.js +94 -0
  251. package/dist/prompts/logic/prompts.d.ts +34 -0
  252. package/dist/prompts/logic/prompts.fixtures.d.ts +5 -0
  253. package/dist/prompts/logic/prompts.fixtures.js +79 -0
  254. package/dist/prompts/logic/prompts.js +32 -0
  255. package/dist/prompts/logic/subjects.d.ts +50 -0
  256. package/dist/prompts/logic/subjects.js +63 -0
  257. package/dist/prompts/logic/useFocusAfterAnswer.d.ts +6 -0
  258. package/dist/prompts/logic/useFocusAfterAnswer.js +28 -0
  259. package/dist/prompts/logic/usePromptSession.d.ts +24 -0
  260. package/dist/prompts/logic/usePromptSession.js +87 -0
  261. package/dist/prompts/ui/ApprovalBody.d.ts +13 -0
  262. package/dist/prompts/ui/ApprovalBody.js +34 -0
  263. package/dist/prompts/ui/PromptActions.d.ts +27 -0
  264. package/dist/prompts/ui/PromptActions.js +18 -0
  265. package/dist/prompts/ui/PromptCard.d.ts +16 -0
  266. package/dist/prompts/ui/PromptCard.js +50 -0
  267. package/dist/prompts/ui/PromptView.d.ts +2 -0
  268. package/dist/prompts/ui/PromptView.js +47 -0
  269. package/dist/prompts/ui/QuestionBody.d.ts +9 -0
  270. package/dist/prompts/ui/QuestionBody.js +87 -0
  271. package/dist/providers/AccountColors.d.ts +5 -0
  272. package/dist/providers/AccountColors.js +8 -0
  273. package/dist/providers/AccountDetail.d.ts +12 -0
  274. package/dist/providers/AccountDetail.js +69 -0
  275. package/dist/providers/AccountVariables.d.ts +8 -0
  276. package/dist/providers/AccountVariables.js +43 -0
  277. package/dist/providers/AddAccountForm.d.ts +10 -0
  278. package/dist/providers/AddAccountForm.js +54 -0
  279. package/dist/providers/CliDetail.d.ts +12 -0
  280. package/dist/providers/CliDetail.js +54 -0
  281. package/dist/providers/ProvidersPane.d.ts +9 -0
  282. package/dist/providers/ProvidersPane.js +86 -0
  283. package/dist/providers/account-actions.d.ts +7 -0
  284. package/dist/providers/account-actions.js +57 -0
  285. package/dist/providers/parts.d.ts +9 -0
  286. package/dist/providers/parts.js +18 -0
  287. package/dist/providers/provider-abilities.d.ts +2 -0
  288. package/dist/providers/provider-abilities.js +7 -0
  289. package/dist/providers/variables.d.ts +13 -0
  290. package/dist/providers/variables.js +63 -0
  291. package/dist/scope.d.ts +11 -0
  292. package/dist/scope.js +10 -0
  293. package/dist/settings/sections.d.ts +13 -0
  294. package/dist/settings/sections.js +32 -0
  295. package/dist/state/chats.d.ts +44 -0
  296. package/dist/state/chats.js +199 -0
  297. package/dist/state/provider-accounts.d.ts +17 -0
  298. package/dist/state/provider-accounts.js +67 -0
  299. package/dist/state/providers.d.ts +17 -0
  300. package/dist/state/providers.js +33 -0
  301. package/dist/state/usage.d.ts +44 -0
  302. package/dist/state/usage.js +121 -0
  303. package/dist/storage.d.ts +20 -0
  304. package/dist/storage.js +89 -0
  305. package/dist/theme.css +212 -0
  306. package/dist/transport.d.ts +24 -0
  307. package/dist/transport.js +18 -0
  308. package/dist/ui/PlainTextarea.d.ts +2 -0
  309. package/dist/ui/PlainTextarea.js +5 -0
  310. package/dist/usage/LimitsList.d.ts +18 -0
  311. package/dist/usage/LimitsList.js +73 -0
  312. package/dist/usage/UsageBreakdown.d.ts +9 -0
  313. package/dist/usage/UsageBreakdown.js +67 -0
  314. package/dist/usage/UsageChart.d.ts +10 -0
  315. package/dist/usage/UsageChart.js +47 -0
  316. package/dist/usage/UsageDialog.d.ts +6 -0
  317. package/dist/usage/UsageDialog.js +12 -0
  318. package/dist/usage/UsageLimits.d.ts +1 -0
  319. package/dist/usage/UsageLimits.js +57 -0
  320. package/dist/usage/UsageLimitsCard.d.ts +4 -0
  321. package/dist/usage/UsageLimitsCard.js +26 -0
  322. package/dist/usage/UsagePage.d.ts +7 -0
  323. package/dist/usage/UsagePage.js +154 -0
  324. package/dist/usage/UsagePane.d.ts +3 -0
  325. package/dist/usage/UsagePane.js +21 -0
  326. package/dist/usage/UsageSummary.d.ts +12 -0
  327. package/dist/usage/UsageSummary.js +15 -0
  328. package/dist/usage/UsageTiles.d.ts +7 -0
  329. package/dist/usage/UsageTiles.js +19 -0
  330. package/dist/usage/format.d.ts +13 -0
  331. package/dist/usage/format.js +55 -0
  332. package/dist/usage/limit-groups.d.ts +22 -0
  333. package/dist/usage/limit-groups.js +86 -0
  334. package/dist/usage/limits.d.ts +4 -0
  335. package/dist/usage/limits.js +58 -0
  336. package/dist/usage/money.d.ts +1 -0
  337. package/dist/usage/money.js +13 -0
  338. package/dist/usage/summary.d.ts +34 -0
  339. package/dist/usage/summary.js +94 -0
  340. package/package.json +895 -3
  341. package/src/agents/AccountDot.tsx +14 -0
  342. package/src/agents/AgentIcon.tsx +26 -0
  343. package/src/agents/ModelOptionControl.tsx +68 -0
  344. package/src/agents/ProviderLogo.tsx +20 -0
  345. package/src/agents/account-limits.ts +61 -0
  346. package/src/agents/accounts.ts +137 -0
  347. package/src/agents/model-name.ts +70 -0
  348. package/src/agents/model-options.ts +21 -0
  349. package/src/agents/provider-paths.ts +10 -0
  350. package/src/agents/status-look.ts +43 -0
  351. package/src/chat/account-choice.ts +44 -0
  352. package/src/chat/actions.ts +72 -0
  353. package/src/chat/activity.ts +8 -0
  354. package/src/chat/attachments.ts +118 -0
  355. package/src/chat/bookmarks.ts +87 -0
  356. package/src/chat/chat-client.ts +345 -0
  357. package/src/chat/chat-references.ts +11 -0
  358. package/src/chat/drafts.ts +165 -0
  359. package/src/chat/forks.ts +33 -0
  360. package/src/chat/guards.ts +84 -0
  361. package/src/chat/logic/ansi.ts +206 -0
  362. package/src/chat/logic/answers.ts +8 -0
  363. package/src/chat/logic/bookmarks.ts +42 -0
  364. package/src/chat/logic/context-usage.ts +36 -0
  365. package/src/chat/logic/fork.ts +200 -0
  366. package/src/chat/logic/handback.ts +10 -0
  367. package/src/chat/logic/json.ts +4 -0
  368. package/src/chat/logic/limit.ts +46 -0
  369. package/src/chat/logic/resume-compaction.ts +71 -0
  370. package/src/chat/logic/scrubber.ts +289 -0
  371. package/src/chat/logic/thread-cards.ts +64 -0
  372. package/src/chat/logic/timeline-copy.ts +65 -0
  373. package/src/chat/logic/timeline-target.ts +52 -0
  374. package/src/chat/logic/timeline.ts +419 -0
  375. package/src/chat/logic/tool-catalog.ts +62 -0
  376. package/src/chat/logic/tools.ts +102 -0
  377. package/src/chat/logic/welcome.ts +13 -0
  378. package/src/chat/logic/workflow.ts +66 -0
  379. package/src/chat/mentions.ts +232 -0
  380. package/src/chat/persisted-json.ts +67 -0
  381. package/src/chat/preferences.ts +179 -0
  382. package/src/chat/quote.ts +26 -0
  383. package/src/chat/recent-messages.ts +59 -0
  384. package/src/chat/resume-compaction-dismissals.ts +17 -0
  385. package/src/chat/runtime-modes.ts +18 -0
  386. package/src/chat/stash.ts +122 -0
  387. package/src/chat/subagent-conversation.ts +203 -0
  388. package/src/chat/subagent-list.ts +141 -0
  389. package/src/chat/subagent-support.ts +21 -0
  390. package/src/chat/subagent-view.ts +137 -0
  391. package/src/chat/thumbnails.ts +108 -0
  392. package/src/chat/timeline-flash.ts +33 -0
  393. package/src/chat/timeline-scroll.ts +199 -0
  394. package/src/chat/ui/AccountPill.tsx +31 -0
  395. package/src/chat/ui/AnsiOutput.tsx +18 -0
  396. package/src/chat/ui/BookmarkMarker.tsx +108 -0
  397. package/src/chat/ui/BookmarkSubmenu.tsx +53 -0
  398. package/src/chat/ui/ChatActivity.tsx +198 -0
  399. package/src/chat/ui/ChatReferenceChip.tsx +28 -0
  400. package/src/chat/ui/CodeBlock.tsx +175 -0
  401. package/src/chat/ui/Composer.tsx +1326 -0
  402. package/src/chat/ui/ComposerInput.tsx +187 -0
  403. package/src/chat/ui/DiffPool.tsx +36 -0
  404. package/src/chat/ui/EditDiff.tsx +30 -0
  405. package/src/chat/ui/FadingWords.tsx +18 -0
  406. package/src/chat/ui/ImageView.tsx +159 -0
  407. package/src/chat/ui/LimitState.tsx +165 -0
  408. package/src/chat/ui/Markdown.tsx +258 -0
  409. package/src/chat/ui/MessageActions.tsx +88 -0
  410. package/src/chat/ui/Pickers.tsx +272 -0
  411. package/src/chat/ui/PromptComposer.tsx +119 -0
  412. package/src/chat/ui/QuoteButton.tsx +103 -0
  413. package/src/chat/ui/ResumeCompactionDock.tsx +28 -0
  414. package/src/chat/ui/RunSettings.tsx +546 -0
  415. package/src/chat/ui/Scrubber.tsx +262 -0
  416. package/src/chat/ui/SubagentControls.tsx +66 -0
  417. package/src/chat/ui/SubagentInfo.tsx +67 -0
  418. package/src/chat/ui/SubagentStopButton.tsx +45 -0
  419. package/src/chat/ui/SubagentTimeline.tsx +170 -0
  420. package/src/chat/ui/Timeline.tsx +628 -0
  421. package/src/chat/ui/TimelineMenu.tsx +124 -0
  422. package/src/chat/ui/UnifiedDiff.tsx +99 -0
  423. package/src/chat/ui/UploadThumb.tsx +13 -0
  424. package/src/chat/ui/Welcome.tsx +22 -0
  425. package/src/chat/ui/chips.ts +15 -0
  426. package/src/chat/ui/code-lines.ts +60 -0
  427. package/src/chat/ui/code-streaming.ts +4 -0
  428. package/src/chat/ui/code-theme.ts +15 -0
  429. package/src/chat/ui/composer/chips.ts +43 -0
  430. package/src/chat/ui/composer/editor.ts +118 -0
  431. package/src/chat/ui/composer/insert.ts +22 -0
  432. package/src/chat/ui/composer/keys.ts +144 -0
  433. package/src/chat/ui/diff-theme.ts +23 -0
  434. package/src/chat/ui/file-links.ts +24 -0
  435. package/src/chat/ui/find-reveal.ts +23 -0
  436. package/src/chat/ui/full-diff.ts +25 -0
  437. package/src/chat/ui/icons.tsx +24 -0
  438. package/src/chat/ui/markdown-blocks.ts +123 -0
  439. package/src/chat/ui/quote-selection.ts +53 -0
  440. package/src/chat/ui/rehype-chips.ts +62 -0
  441. package/src/chat/ui/rehype-fade.ts +64 -0
  442. package/src/chat/ui/remark-html-as-text.ts +36 -0
  443. package/src/chat/ui/reply-context.ts +4 -0
  444. package/src/chat/ui/reveal.ts +135 -0
  445. package/src/chat/ui/rows/ForksRow.tsx +79 -0
  446. package/src/chat/ui/rows/MessageRows.tsx +415 -0
  447. package/src/chat/ui/rows/Rows.tsx +81 -0
  448. package/src/chat/ui/rows/SubagentRow.tsx +209 -0
  449. package/src/chat/ui/rows/TaskRow.tsx +91 -0
  450. package/src/chat/ui/rows/WorkRows.tsx +445 -0
  451. package/src/chat/ui/rows/WorkflowRow.tsx +120 -0
  452. package/src/chat/ui/rows/row-rhythm.ts +37 -0
  453. package/src/chat/ui/useToggleSet.ts +39 -0
  454. package/src/host.ts +324 -0
  455. package/src/lazy.tsx +64 -0
  456. package/src/locales/en/agent-chat.json +446 -0
  457. package/src/locales/en/agent-prompts.json +42 -0
  458. package/src/locales/en/agent-providers.json +131 -0
  459. package/src/locales/en/agent-usage.json +131 -0
  460. package/src/locales/nl/agent-chat.json +446 -0
  461. package/src/locales/nl/agent-prompts.json +42 -0
  462. package/src/locales/nl/agent-providers.json +131 -0
  463. package/src/locales/nl/agent-usage.json +131 -0
  464. package/src/locales.ts +33 -0
  465. package/src/mounted-registry.ts +45 -0
  466. package/src/port-transport.ts +146 -0
  467. package/src/prompts/logic/focus.ts +25 -0
  468. package/src/prompts/logic/keys.ts +116 -0
  469. package/src/prompts/logic/prompts.fixtures.ts +84 -0
  470. package/src/prompts/logic/prompts.ts +58 -0
  471. package/src/prompts/logic/subjects.ts +122 -0
  472. package/src/prompts/logic/useFocusAfterAnswer.ts +38 -0
  473. package/src/prompts/logic/usePromptSession.ts +114 -0
  474. package/src/prompts/ui/ApprovalBody.tsx +109 -0
  475. package/src/prompts/ui/PromptActions.tsx +109 -0
  476. package/src/prompts/ui/PromptCard.tsx +101 -0
  477. package/src/prompts/ui/PromptView.tsx +111 -0
  478. package/src/prompts/ui/QuestionBody.tsx +174 -0
  479. package/src/providers/AccountColors.tsx +8 -0
  480. package/src/providers/AccountDetail.tsx +209 -0
  481. package/src/providers/AccountVariables.tsx +126 -0
  482. package/src/providers/AddAccountForm.tsx +121 -0
  483. package/src/providers/CliDetail.tsx +157 -0
  484. package/src/providers/ProvidersPane.tsx +236 -0
  485. package/src/providers/account-actions.ts +67 -0
  486. package/src/providers/parts.tsx +25 -0
  487. package/src/providers/provider-abilities.ts +9 -0
  488. package/src/providers/variables.ts +87 -0
  489. package/src/scope.ts +30 -0
  490. package/src/settings/sections.ts +47 -0
  491. package/src/state/chats.ts +279 -0
  492. package/src/state/provider-accounts.ts +87 -0
  493. package/src/state/providers.ts +50 -0
  494. package/src/state/usage.ts +196 -0
  495. package/src/storage.ts +113 -0
  496. package/src/theme.css +212 -0
  497. package/src/transport.ts +50 -0
  498. package/src/ui/PlainTextarea.tsx +6 -0
  499. package/src/usage/LimitsList.tsx +232 -0
  500. package/src/usage/UsageBreakdown.tsx +210 -0
  501. package/src/usage/UsageChart.tsx +113 -0
  502. package/src/usage/UsageDialog.tsx +20 -0
  503. package/src/usage/UsageLimits.tsx +145 -0
  504. package/src/usage/UsageLimitsCard.tsx +36 -0
  505. package/src/usage/UsagePage.tsx +276 -0
  506. package/src/usage/UsagePane.tsx +52 -0
  507. package/src/usage/UsageSummary.tsx +50 -0
  508. package/src/usage/UsageTiles.tsx +34 -0
  509. package/src/usage/format.ts +71 -0
  510. package/src/usage/limit-groups.ts +119 -0
  511. package/src/usage/limits.ts +71 -0
  512. package/src/usage/money.ts +14 -0
  513. package/src/usage/summary.ts +137 -0
@@ -0,0 +1,121 @@
1
+ import { chatStorageKey, chatStorageLegacyKeys, createChatStore, onChatStorageConfiguration } from '../storage.js';
2
+ import { persistedJson } from '../chat/persisted-json.js';
3
+ import { localTimeZone } from '@adecore/ui/format';
4
+ import { useChatScope } from '../scope.js';
5
+ /* Only the id and the length. A store has no words, so the page names a period in its own language. */
6
+ export const USAGE_PERIODS = [
7
+ { id: 'today', days: 1 },
8
+ { id: '7d', days: 7 },
9
+ { id: '30d', days: 30 },
10
+ { id: '90d', days: 90 }
11
+ ];
12
+ const storageKey = () => chatStorageKey('usage');
13
+ export let USAGE_PREFERENCES_KEY = storageKey();
14
+ onChatStorageConfiguration(() => {
15
+ USAGE_PREFERENCES_KEY = storageKey();
16
+ });
17
+ export function usagePreferencesKey() {
18
+ return storageKey();
19
+ }
20
+ const DEFAULTS = { period: '7d', metric: 'cost', currency: 'USD' };
21
+ function parsePreferences(raw) {
22
+ try {
23
+ const stored = JSON.parse(raw ?? '{}');
24
+ return {
25
+ period: USAGE_PERIODS.some((period) => period.id === stored.period) ? stored.period : DEFAULTS.period,
26
+ metric: stored.metric === 'tokens' || stored.metric === 'cost' ? stored.metric : DEFAULTS.metric,
27
+ currency: stored.currency === 'EUR' ? 'EUR' : DEFAULTS.currency
28
+ };
29
+ }
30
+ catch {
31
+ return DEFAULTS;
32
+ }
33
+ }
34
+ const storage = persistedJson(storageKey, parsePreferences, DEFAULTS, () => chatStorageLegacyKeys('usage'));
35
+ function readPreferences() {
36
+ return storage.read();
37
+ }
38
+ function persist(preferences) {
39
+ storage.write(preferences);
40
+ }
41
+ /* The three stored choices out of the store, so a setter writes the other two back unchanged. */
42
+ function chosen(state) {
43
+ return { period: state.period, metric: state.metric, currency: state.currency };
44
+ }
45
+ function pad(value) {
46
+ return String(value).padStart(2, '0');
47
+ }
48
+ /* The viewer's own calendar day; the host may stand in another zone and buckets in this one. */
49
+ export function dayOf(date) {
50
+ return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}`;
51
+ }
52
+ /*
53
+ * What a period asks for. Today counts from local midnight in hours, the way the commit log already
54
+ * groups days, so every other period reads as one bar per calendar day.
55
+ */
56
+ export function windowFor(period, now = new Date()) {
57
+ const days = USAGE_PERIODS.find((entry) => entry.id === period)?.days ?? 7;
58
+ const from = new Date(now.getFullYear(), now.getMonth(), now.getDate() - (days - 1));
59
+ return {
60
+ from: dayOf(from),
61
+ to: dayOf(now),
62
+ resolution: period === 'today' ? 'hour' : 'day',
63
+ timeZone: localTimeZone() ?? 'UTC'
64
+ };
65
+ }
66
+ /* A period, and only the usage of one account when one is picked; null is every account. */
67
+ export function summaryPayload(period, account, now = new Date()) {
68
+ return account === null ? windowFor(period, now) : { ...windowFor(period, now), accounts: [account] };
69
+ }
70
+ /* What was asked, so an answer to the question before this one is never drawn over a newer one. */
71
+ export function askedKey(payload) {
72
+ return `${payload.from}\0${payload.to}\0${payload.resolution}\0${payload.timeZone}\0${payload.accounts?.join(',') ?? ''}`;
73
+ }
74
+ /* One object for a host nothing was read from yet, so a selector gets a stable snapshot. */
75
+ const EMPTY = { asked: null, summary: null, loading: false, failed: false, limits: null };
76
+ /* Reads the period, metric and currency again, once another window of the same origin wrote them. */
77
+ export function reloadUsagePreferences() {
78
+ useUsageStore.setState(readPreferences());
79
+ }
80
+ export const useUsageStore = createChatStore((set, get) => ({
81
+ ...DEFAULTS,
82
+ byScope: {},
83
+ chosen: null,
84
+ choose(scopeId) {
85
+ set({ chosen: scopeId });
86
+ },
87
+ setPeriod(period) {
88
+ persist({ ...chosen(get()), period });
89
+ set({ period });
90
+ },
91
+ setMetric(metric) {
92
+ persist({ ...chosen(get()), metric });
93
+ set({ metric });
94
+ },
95
+ setCurrency(currency) {
96
+ persist({ ...chosen(get()), currency });
97
+ set({ currency });
98
+ },
99
+ setLoading(scopeId, loading) {
100
+ set({ byScope: { ...get().byScope, [scopeId]: { ...(get().byScope[scopeId] ?? EMPTY), loading } } });
101
+ },
102
+ receive(scopeId, asked, summary) {
103
+ set({
104
+ byScope: { ...get().byScope, [scopeId]: { ...(get().byScope[scopeId] ?? EMPTY), asked, summary, loading: false, failed: false } }
105
+ });
106
+ },
107
+ fail(scopeId) {
108
+ set({ byScope: { ...get().byScope, [scopeId]: { ...(get().byScope[scopeId] ?? EMPTY), loading: false, failed: true } } });
109
+ },
110
+ setLimits(scopeId, limits) {
111
+ set({ byScope: { ...get().byScope, [scopeId]: { ...(get().byScope[scopeId] ?? EMPTY), limits } } });
112
+ },
113
+ forget(scopeId) {
114
+ const { [scopeId]: _gone, ...rest } = get().byScope;
115
+ set({ byScope: rest });
116
+ }
117
+ }), (store) => store.setState(readPreferences()));
118
+ export function useUsage(select) {
119
+ const { id } = useChatScope();
120
+ return useUsageStore((s) => select({ period: s.period, metric: s.metric, currency: s.currency, ...(s.byScope[id] ?? EMPTY) }));
121
+ }
@@ -0,0 +1,20 @@
1
+ import { type StateCreator, type StoreApi, type UseBoundStore } from 'zustand';
2
+ export type ChatStorageRecord = 'drafts' | 'preferences' | 'stash' | 'usage';
3
+ export interface ChatStorageAdapter {
4
+ getItem(key: string): string | null;
5
+ setItem(key: string, value: string): void;
6
+ }
7
+ export interface ChatStorageOptions {
8
+ namespace?: string;
9
+ keys?: Partial<Record<ChatStorageRecord, string>>;
10
+ legacyNamespaces?: readonly string[];
11
+ legacyKeys?: Partial<Record<ChatStorageRecord, readonly string[]>>;
12
+ storage?: ChatStorageAdapter | null;
13
+ }
14
+ export declare function onChatStorageConfiguration(listener: () => void): void;
15
+ export declare function configureChatStorage(configuration: ChatStorageOptions): void;
16
+ export declare function chatStorageKey(record: ChatStorageRecord): string;
17
+ export declare function chatStorageLegacyKeys(record: ChatStorageRecord): readonly string[];
18
+ export declare function chatStorageAdapter(): ChatStorageAdapter | null;
19
+ export declare function hydrateChatStorage(): void;
20
+ export declare function createChatStore<T>(initial: StateCreator<T>, hydrate: (store: StoreApi<T>) => void): UseBoundStore<StoreApi<T>>;
@@ -0,0 +1,89 @@
1
+ import { create } from 'zustand';
2
+ const SUFFIXES = {
3
+ drafts: 'chat.drafts',
4
+ preferences: 'chat.preferences',
5
+ stash: 'chat.stash',
6
+ usage: 'usage'
7
+ };
8
+ let options = {};
9
+ let hydrated = false;
10
+ const hydrators = [];
11
+ const configurationListeners = [];
12
+ export function onChatStorageConfiguration(listener) {
13
+ configurationListeners.push(listener);
14
+ }
15
+ /* Configure once before using a store, so an imported component cannot read another host's records. */
16
+ export function configureChatStorage(configuration) {
17
+ if (hydrated) {
18
+ throw new Error('Configure chat storage before using chat stores');
19
+ }
20
+ options = {
21
+ ...configuration,
22
+ keys: { ...configuration.keys },
23
+ legacyNamespaces: [...(configuration.legacyNamespaces ?? [])],
24
+ legacyKeys: Object.fromEntries(Object.entries(configuration.legacyKeys ?? {}).map(([key, values]) => [key, [...values]]))
25
+ };
26
+ for (const listener of configurationListeners) {
27
+ listener();
28
+ }
29
+ }
30
+ export function chatStorageKey(record) {
31
+ return options.keys?.[record] ?? `${options.namespace ?? 'adecore'}.${SUFFIXES[record]}`;
32
+ }
33
+ export function chatStorageLegacyKeys(record) {
34
+ return [...(options.legacyKeys?.[record] ?? []), ...(options.legacyNamespaces ?? []).map((namespace) => `${namespace}.${SUFFIXES[record]}`)];
35
+ }
36
+ export function chatStorageAdapter() {
37
+ if (options.storage !== undefined) {
38
+ return options.storage;
39
+ }
40
+ try {
41
+ return globalThis.localStorage;
42
+ }
43
+ catch {
44
+ return null;
45
+ }
46
+ }
47
+ export function hydrateChatStorage() {
48
+ if (hydrated) {
49
+ return;
50
+ }
51
+ hydrated = true;
52
+ for (const hydrate of hydrators) {
53
+ hydrate();
54
+ }
55
+ }
56
+ export function createChatStore(initial, hydrate) {
57
+ const store = create(initial);
58
+ let initialized = false;
59
+ const hydrateOnce = () => {
60
+ if (initialized) {
61
+ return;
62
+ }
63
+ initialized = true;
64
+ hydrate(store);
65
+ };
66
+ hydrators.push(hydrateOnce);
67
+ const useStore = ((...args) => {
68
+ hydrateChatStorage();
69
+ hydrateOnce();
70
+ return store(...args);
71
+ });
72
+ Object.assign(useStore, store);
73
+ useStore.getState = () => {
74
+ hydrateChatStorage();
75
+ hydrateOnce();
76
+ return store.getState();
77
+ };
78
+ useStore.subscribe = (...args) => {
79
+ hydrateChatStorage();
80
+ hydrateOnce();
81
+ return store.subscribe(...args);
82
+ };
83
+ useStore.setState = ((...args) => {
84
+ hydrateChatStorage();
85
+ hydrateOnce();
86
+ store.setState(...args);
87
+ });
88
+ return useStore;
89
+ }
package/dist/theme.css ADDED
@@ -0,0 +1,212 @@
1
+ /*
2
+ * The chat of @adecore/agents-react, its providers and its usage: the tokens only they read and the
3
+ * rules they draw with. Imported right after `@adecore/ui/theme.css`; the app scans the package with
4
+ * `@source` and loads `@tailwindcss/typography`, which the markdown of a thread builds on.
5
+ */
6
+ :root, [data-theme="light"] {
7
+ /* Skills read as a second kind of token next to a file mention, so they get their own hue. */
8
+ --skill: #9333ea;
9
+ --skill-soft: #f7eeff;
10
+ /* One color per agent CLI, so a bar, a dot and a legend row all name the same provider. Apple's
11
+ system orange and teal; Gemini and Copilot are reserved for the day their transcripts are read. */
12
+ --chart-claude: #ff9500;
13
+ --chart-codex: #30b0c7;
14
+ --chart-gemini: #3b82f6;
15
+ --chart-copilot: #64748b;
16
+ /* What a chat's context holds, one color per part; the rest is the system's and stays gray. */
17
+ --chart-context-tools: #4d7ce6;
18
+ --chart-context-files: #9a63e0;
19
+ --chart-context-conversation: #2f9e5a;
20
+ --chart-context-system: var(--text-faint);
21
+ /* The current hit of a find, which has to stand out from the accent of a bookmark next to it. */
22
+ --chat-find: #facc15;
23
+ }
24
+
25
+ [data-theme="dark"] {
26
+ --skill: #c084fc;
27
+ --skill-soft: #2f2350;
28
+ --chart-claude: #ff9f0a;
29
+ --chart-codex: #40c8e0;
30
+ --chart-gemini: #60a5fa;
31
+ --chart-copilot: #94a3b8;
32
+ --chart-context-tools: #8aa7f5;
33
+ --chart-context-files: #b98af3;
34
+ --chart-context-conversation: #6dd08b;
35
+ --chart-context-system: var(--text-faint);
36
+ --chat-find: #f5c542;
37
+ }
38
+
39
+ /* Output and diffs take the terminal's colors when the app loads `@adecore/terminal/terminal.css`,
40
+ and the base theme's otherwise. Declared on every themed element, so a nested theme resolves its own. */
41
+ :root, [data-theme] {
42
+ --chat-code-bg: var(--term-bg, var(--surface-sunken));
43
+ --chat-output: var(--term-fg, var(--text));
44
+ --chat-added: var(--term-ansi-green, var(--positive));
45
+ --chat-removed: var(--term-ansi-red, var(--status-error));
46
+ }
47
+
48
+ @theme inline {
49
+ --color-skill: var(--skill);
50
+ --color-skill-soft: var(--skill-soft);
51
+ --color-chart-claude: var(--chart-claude);
52
+ --color-chart-codex: var(--chart-codex);
53
+ --color-chart-gemini: var(--chart-gemini);
54
+ --color-chart-copilot: var(--chart-copilot);
55
+ --color-chart-context-tools: var(--chart-context-tools);
56
+ --color-chart-context-files: var(--chart-context-files);
57
+ --color-chart-context-conversation: var(--chart-context-conversation);
58
+ --color-chart-context-system: var(--chart-context-system);
59
+ --color-chat-find: var(--chat-find);
60
+ --color-chat-output: var(--chat-output);
61
+ --color-chat-added: var(--chat-added);
62
+ --color-chat-removed: var(--chat-removed);
63
+ }
64
+
65
+ @layer components {
66
+ /* ---------------------------------------------------------------- Chat */
67
+
68
+ /* Text in a chat is there to be read and copied, so the thread selects even though the app does
69
+ not. Its chrome stays out of it: a drag on a fold header or a chip would select the row.
70
+ The pretty wrap from `body` would be recomputed on the growing paragraph every frame a reply
71
+ streams, so the thread wraps the plain way.
72
+ The gaps are the air a thread needs to read as turns: the step from a question to its answer,
73
+ and the wider step from the end of one turn to the next question. A view of its own gets more
74
+ of both, the way its type does. The block gap is the step inside a turn, where a run of tool
75
+ lines meets prose or a card. */
76
+ .chat-thread { user-select: text; text-wrap-style: auto; --chat-answer-gap: 16px; --chat-turn-gap: 24px; --chat-block-gap: 12px; }
77
+ .chat-column .chat-thread { --chat-answer-gap: 20px; --chat-turn-gap: 32px; --chat-block-gap: 16px; }
78
+ .chat-thread button, .chat-thread kbd { user-select: none; }
79
+
80
+ /*
81
+ * A chat that is a view of its own reads in a column. The scroller keeps the full width of the
82
+ * main column, so its scrollbar sits at that column's right edge and nothing jumps when the
83
+ * thread grows past a screenful; only the rows and the composer inside it are centered.
84
+ */
85
+ .chat-column .chat-column-content { margin-inline: auto; max-width: 768px; }
86
+ /* Wider by the input's inset (`.composer-input .cm-content` padding plus the card's border), so what is typed lines up with the thread. */
87
+ .chat-column .chat-composer-content { margin-inline: auto; max-width: calc(768px + 2 * 21px); }
88
+
89
+ /* A diff inside a chat tool block; the library paints its own colors inside a shadow root and
90
+ takes the face it draws them in through these variables. */
91
+ .chat-diff { font-size: var(--text-code); --diffs-font-size: var(--text-code); --diffs-font-family: var(--font-mono); }
92
+ .chat-diff + .chat-diff { border-top: 1px solid var(--border); }
93
+
94
+ /* Live tool rows shine once across; a paused animation costs nothing. */
95
+ .chat-live-text {
96
+ background: linear-gradient(90deg, var(--text-muted) 0%, var(--text) 50%, var(--text-muted) 100%);
97
+ background-size: 200% 100%;
98
+ -webkit-background-clip: text;
99
+ background-clip: text;
100
+ color: transparent;
101
+ animation: chat-shine 1.6s linear infinite;
102
+ }
103
+ @keyframes chat-shine { from { background-position: 200% 0; } to { background-position: -200% 0; } }
104
+
105
+ /* A word of a reply that just arrived. The duration is REVEAL_FADE_MS in chat/ui/reveal.ts, which
106
+ keeps the spans until it is over; ease-in-out, because ease-out jumps up and then trails. */
107
+ .chat-fade { animation: chat-fade 300ms ease-in-out both; }
108
+ /* A whole reply that was written out of sight. */
109
+ .chat-fade-whole { animation: chat-fade 220ms ease-out both; }
110
+ /* A block of a reply streamed a block at a time, faded in when it is inserted and never when a
111
+ finished thread opens, which carries no `data-arriving`. */
112
+ .chat-markdown[data-arriving] > * {
113
+ transition: opacity 300ms ease-in-out;
114
+ @starting-style { opacity: 0; }
115
+ }
116
+ @keyframes chat-fade { from { opacity: 0; } to { opacity: 1; } }
117
+
118
+ /* The row a jump from outside the chat (the card of a change in a file) landed on. */
119
+ .chat-flash { animation: chat-flash 1600ms ease-out both; }
120
+ @keyframes chat-flash {
121
+ from { background: color-mix(in srgb, var(--accent) 18%, transparent); }
122
+ to { background: transparent; }
123
+ }
124
+ }
125
+
126
+ /*
127
+ * Markdown, outside every layer on purpose. The typography plugin registers `.prose` as a utility,
128
+ * and a later layer beats an earlier one whatever the specificity, so a rule that has to outrank
129
+ * prose cannot live in `components`. Unlayered styles win over every layer, which is the one
130
+ * place the app's tokens and scale are sure to land on top of the plugin's.
131
+ */
132
+ /*
133
+ * Markdown anywhere in the app: the chat timeline, a note node and the file preview all render
134
+ * the same `Markdown` component, which carries `prose prose-sm max-w-none text-sm` next to this
135
+ * class. Prose brings the rhythm; everything here is what the app decides instead of the plugin.
136
+ * The semantic tokens flip with the theme on their own, so the prose variables read from them
137
+ * and `prose-invert` is a second source of truth the app does not need. The size comes from the
138
+ * `text-sm` utility, which a node, a view and the file preview each move.
139
+ */
140
+ .prose.chat-markdown {
141
+ --tw-prose-body: var(--text);
142
+ --tw-prose-headings: var(--text);
143
+ --tw-prose-lead: var(--text-muted);
144
+ --tw-prose-links: var(--accent);
145
+ --tw-prose-bold: var(--text);
146
+ --tw-prose-counters: var(--text-faint);
147
+ --tw-prose-bullets: var(--text-faint);
148
+ --tw-prose-hr: var(--border);
149
+ --tw-prose-quotes: var(--text);
150
+ --tw-prose-quote-borders: var(--border);
151
+ --tw-prose-captions: var(--text-muted);
152
+ --tw-prose-kbd: var(--text);
153
+ --tw-prose-code: var(--text);
154
+ --tw-prose-pre-code: var(--text);
155
+ --tw-prose-pre-bg: var(--surface-sunken);
156
+ --tw-prose-th-borders: var(--border);
157
+ --tw-prose-td-borders: var(--border);
158
+ }
159
+ /* Headings stay on the app's scale, which is flatter than the one prose brings. */
160
+ .chat-markdown :is(h1, h2, h3, h4) { font-weight: 600; line-height: round(1.3em, 1px); }
161
+ .chat-markdown h1 { font-size: var(--text-lg); }
162
+ .chat-markdown h2 { font-size: var(--text-base); }
163
+ .chat-markdown :is(h3, h4) { font-size: var(--text-sm); }
164
+ .chat-markdown a { text-underline-offset: 2px; }
165
+ /* Code is the app's own: `--text-code` at every depth, and none of the quotes prose puts around
166
+ inline code, since the chip the component draws already says what it is. */
167
+ .chat-markdown code { font-size: var(--text-code); font-weight: 400; }
168
+ .chat-markdown code::before, .chat-markdown code::after { content: none; }
169
+ /* A checked box is the marker; prose would put a bullet next to it. */
170
+ .chat-markdown li:has(> input[type="checkbox"]) { list-style: none; }
171
+ .chat-markdown input[type="checkbox"] { margin-right: 6px; accent-color: var(--accent); }
172
+ /* A wide table scrolls in its own wrapper instead of stretching the column it sits in. The
173
+ wrapper is a scroll container, so the air around the table has to sit on it, not inside it. */
174
+ .chat-table { overflow-x: auto; margin-block: 2em; }
175
+ .chat-markdown table { margin: 0; border-collapse: collapse; font-size: var(--text-xs); }
176
+ .chat-markdown :is(th, td) { border: 1px solid var(--tw-prose-td-borders); padding: 4px 8px; text-align: left; }
177
+
178
+ /* A code block is shiki's own `<pre>`, which brings a background of its own to override. */
179
+ .chat-code { border-radius: 8px; border: 1px solid var(--border); background: var(--chat-code-bg); overflow: auto; }
180
+ .chat-code pre { margin: 0; padding: round(0.625rem, 1px) round(0.75rem, 1px); background: transparent !important; font-family: var(--font-mono); font-size: var(--text-code); line-height: var(--text-code--line-height); }
181
+ .chat-code code { font-family: inherit; }
182
+
183
+ /* The chat composer is a CodeMirror editor, whose base theme lands in an unlayered style tag at
184
+ mount. These rules stay unlayered too, and carry one class more than the theme's selectors. */
185
+ .composer-input .cm-editor { max-height: 200px; }
186
+ .composer-input .cm-editor.cm-focused { outline: none; }
187
+ .composer-input .cm-editor .cm-scroller { overflow: auto; font-family: inherit; line-height: inherit; }
188
+ .composer-input .cm-editor .cm-scroller .cm-content { padding: 18px 14px 6px 20px; caret-color: var(--text); }
189
+ .composer-input .cm-scroller .cm-content .cm-line { padding: 0; }
190
+ .composer-input .cm-scroller .cm-content .cm-placeholder { color: var(--text-faint); }
191
+ .composer-hints, .composer-hints-extra { display: inline-flex; align-items: center; gap: 8px; white-space: nowrap; }
192
+ /* The joiner starts with its own comma, so it sits against the lead without the gap. */
193
+ .composer-hints-extra { margin-left: -8px; }
194
+ .composer-hints kbd { padding: 0 6px; border-radius: 5px; background: var(--surface-active); color: var(--text-muted); font-family: var(--font-mono); font-size: var(--text-code); line-height: var(--text-code--line-height); }
195
+ /* The widths of Tailwind's `@md` container variant, which the rest of the composer narrows at. */
196
+ @container composer (width < 28rem) {
197
+ .composer-input .cm-editor .cm-scroller .cm-content { padding: 14px 12px 4px 14px; }
198
+ }
199
+ /* The hints stay on the line of the lead or go; wrapped, they would start left of the text. */
200
+ @container composer (width < 36rem) {
201
+ .composer-hints-extra { display: none; }
202
+ }
203
+ /* Markdown stays source while you type: the markers stay put and dim, and what they wrap takes its look. */
204
+ .composer-input .cm-md-mark { color: var(--text-faint); }
205
+ .composer-input .cm-md-strong, .composer-input .cm-md-heading { font-weight: 600; }
206
+ .composer-input .cm-md-emphasis { font-style: italic; }
207
+ .composer-input .cm-md-strike { text-decoration: line-through; }
208
+ .composer-input .cm-md-link { color: var(--accent); text-decoration: underline; }
209
+ .composer-input .cm-md-code { padding: 1px 2px; border-radius: 4px; background: var(--surface-sunken); font-family: var(--font-mono); font-size: var(--text-code); }
210
+ .composer-input .cm-content .cm-line.cm-md-fence { padding: 0 8px; background: var(--surface-sunken); font-family: var(--font-mono); font-size: var(--text-code); }
211
+ .composer-input .cm-content .cm-line.cm-md-fence-start { padding-top: 4px; border-top-left-radius: 6px; border-top-right-radius: 6px; }
212
+ .composer-input .cm-content .cm-line.cm-md-fence-end { padding-bottom: 4px; border-bottom-left-radius: 6px; border-bottom-right-radius: 6px; }
@@ -0,0 +1,24 @@
1
+ import type { z } from 'zod';
2
+ import type { AGENT_EVENT_SCHEMAS, AGENT_REQUEST_SCHEMAS, AgentEventType, AgentRequestType } from '@adecore/agent-contracts/protocol';
3
+ export type ChatRequestMap = {
4
+ [T in AgentRequestType]: {
5
+ payload: z.infer<(typeof AGENT_REQUEST_SCHEMAS)[T]['payload']>;
6
+ result: z.infer<(typeof AGENT_REQUEST_SCHEMAS)[T]['result']>;
7
+ };
8
+ };
9
+ export type ChatEventMap = {
10
+ [E in AgentEventType]: z.infer<(typeof AGENT_EVENT_SCHEMAS)[E]>;
11
+ };
12
+ export type ChatTransportStatus = 'connecting' | 'open' | 'closed';
13
+ export interface ChatTransport {
14
+ request<T extends AgentRequestType>(type: T, payload: ChatRequestMap[T]['payload']): Promise<ChatRequestMap[T]['result']>;
15
+ on<E extends AgentEventType>(event: E, handler: (payload: ChatEventMap[E]) => void): () => void;
16
+ readonly status: ChatTransportStatus;
17
+ subscribeStatus(handler: (status: ChatTransportStatus) => void): () => void;
18
+ }
19
+ export declare class ChatTransportError extends Error {
20
+ readonly code: string;
21
+ constructor(code: string, message: string);
22
+ }
23
+ export declare function errorCode(error: unknown): string | null;
24
+ export declare function isConnectionError(error: unknown): boolean;
@@ -0,0 +1,18 @@
1
+ /* A refused request always carries a code, so a caller branches on it instead of on the message. */
2
+ export class ChatTransportError extends Error {
3
+ code;
4
+ constructor(code, message) {
5
+ super(message);
6
+ this.name = 'ChatTransportError';
7
+ this.code = code;
8
+ }
9
+ }
10
+ /* The code of a refusal from any transport, this package's or the app's own: every one of them carries it the same way. */
11
+ export function errorCode(error) {
12
+ return typeof error === 'object' && error !== null && 'code' in error && typeof error.code === 'string' ? error.code : null;
13
+ }
14
+ /* Whether a request failed because the link was down rather than because the host refused it; the reconnect asks again. */
15
+ export function isConnectionError(error) {
16
+ const code = errorCode(error);
17
+ return code === 'not-connected' || code === 'disconnected';
18
+ }
@@ -0,0 +1,2 @@
1
+ import type { TextareaProps } from '../host.js';
2
+ export declare function PlainTextarea({ buttonClassName: _buttonClassName, ...props }: TextareaProps): import("react").JSX.Element;
@@ -0,0 +1,5 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ /* The field a written answer goes in when the app brings no dictation of its own. */
3
+ export function PlainTextarea({ buttonClassName: _buttonClassName, ...props }) {
4
+ return _jsx("textarea", { ...props });
5
+ }
@@ -0,0 +1,18 @@
1
+ import type { UsageLimitsSnapshot, UsageWindow } from '@adecore/agent-contracts';
2
+ import { type LimitGroup } from './limit-groups.js';
3
+ export declare function WindowBar({ window, now, compact }: {
4
+ window: UsageWindow;
5
+ now: number;
6
+ compact: boolean;
7
+ }): import("react").JSX.Element;
8
+ interface LimitsListProps {
9
+ limits: UsageLimitsSnapshot;
10
+ now: number;
11
+ compact?: boolean;
12
+ }
13
+ export declare function LimitsList({ limits, now, compact }: LimitsListProps): import("react").JSX.Element;
14
+ export declare function AccountLimitsList({ groups, now }: {
15
+ groups: readonly LimitGroup[];
16
+ now: number;
17
+ }): import("react").JSX.Element;
18
+ export {};
@@ -0,0 +1,73 @@
1
+ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Fragment } from 'react';
3
+ import clsx from 'clsx';
4
+ import { useTranslation } from 'react-i18next';
5
+ import { limitsAccountId } from '../agents/account-limits.js';
6
+ import { AccountDot } from '../agents/AccountDot.js';
7
+ import { Tooltip } from '@adecore/ui';
8
+ import { formatClock, formatWeekdayClock, isSameDay, formatCountdown, formatPercent } from '@adecore/ui/format';
9
+ import { ProviderLogo } from '../agents/ProviderLogo.js';
10
+ import { PROVIDER_COLORS, PROVIDER_LABELS } from './format.js';
11
+ import { accountNote, explain, isSignedOut, nextReset } from './limit-groups.js';
12
+ /* Red where a window is nearly spent, amber where it is worth knowing. A window with room to spare
13
+ is not news, so it takes the text color rather than a hue that competes with the two that are. */
14
+ function toneOf(used) {
15
+ return used >= 0.9 ? 'bg-status-error' : used >= 0.7 ? 'bg-status-needs-you' : 'bg-text';
16
+ }
17
+ /* A time of day when the reset is today, a weekday and a time when it is not. */
18
+ function resetAtLabel(resetsAt, now) {
19
+ return isSameDay(resetsAt, now) ? formatClock(resetsAt) : formatWeekdayClock(resetsAt);
20
+ }
21
+ /* How long the window still has, or nothing once it has run out. */
22
+ function resetInLabel(resetsAt, now) {
23
+ return resetsAt <= now ? null : formatCountdown(resetsAt - now);
24
+ }
25
+ /* How much of the window has run, or null when the provider named neither a reset nor a length. */
26
+ function elapsedShare(window, now) {
27
+ if (window.resetsAt === null || window.durationMs === null || window.durationMs <= 0) {
28
+ return null;
29
+ }
30
+ return Math.min(1, Math.max(0, 1 - (window.resetsAt - now) / window.durationMs));
31
+ }
32
+ export function WindowBar({ window, now, compact }) {
33
+ const { t } = useTranslation('agent-usage');
34
+ const percent = Math.round(window.used * 100);
35
+ const elapsed = elapsedShare(window, now);
36
+ // The bar fills as the quota is spent, so the mark beside it is how much of the window has run.
37
+ const mark = elapsed === null ? null : Math.round(elapsed * 100);
38
+ const resetsAt = window.resetsAt === null ? null : resetAtLabel(window.resetsAt, now);
39
+ const resetsIn = window.resetsAt === null ? null : resetInLabel(window.resetsAt, now);
40
+ const bar = (_jsxs("div", { role: "progressbar", "aria-label": t('limits.bar', { window: window.label, percent }), "aria-valuenow": percent, "aria-valuemin": 0, "aria-valuemax": 100, className: clsx('relative cursor-default', compact ? 'h-4' : 'h-6'), children: [_jsx("div", { className: clsx('absolute inset-x-0 rounded-full bg-surface-sunken', compact ? 'inset-y-1' : 'inset-y-1.5') }), _jsx("div", { className: clsx('absolute left-0 rounded-full', compact ? 'inset-y-1' : 'inset-y-1.5', toneOf(window.used)), style: { width: `${Math.min(100, percent)}%` } }), mark !== null && (_jsx("span", { "aria-hidden": true, className: clsx('absolute inset-y-0.5 w-px -translate-x-1/2', mark <= percent ? 'bg-surface' : 'bg-text-muted'), style: { left: `${mark}%` } }))] }));
41
+ return (_jsxs("div", { className: "flex flex-col gap-1", children: [_jsxs("div", { className: "flex items-baseline gap-2 text-xs", children: [_jsx("span", { className: "text-text", children: window.label }), _jsx("span", { className: "ml-auto tabular-nums text-text-muted", children: t('limits.used', { percent }) })] }), compact ? (bar) : (_jsx(Tooltip, { label: _jsxs("span", { className: "flex flex-col gap-0.5", children: [_jsxs("span", { children: [t('limits.used', { percent }), mark !== null && ` · ${t('limits.windowPassed', { percent: mark })}`] }), mark !== null && _jsx("span", { className: "text-text-muted", children: mark <= percent ? t('limits.faster') : t('limits.slower') })] }), children: bar })), resetsAt !== null && (_jsxs("p", { className: "text-xs whitespace-nowrap text-text-faint", children: [t('limits.resets', { at: resetsAt }), resetsIn !== null && ` · ${resetsIn}`] }))] }));
42
+ }
43
+ /* Every provider with what its plan has left, shared by the usage page and the sidebar card. */
44
+ export function LimitsList({ limits, now, compact = false }) {
45
+ return (_jsx("div", { className: clsx('flex flex-col', compact ? 'gap-4' : 'gap-6'), children: limits.providers.map((provider) => {
46
+ const note = explain(provider);
47
+ return (_jsxs("div", { className: "flex flex-col gap-2", children: [_jsxs("p", { className: "flex items-center gap-2 text-xs font-medium", children: [_jsx("span", { style: { color: PROVIDER_COLORS[provider.kind] }, children: _jsx(ProviderLogo, { provider: provider.kind }) }), PROVIDER_LABELS[provider.kind], provider.plan !== null && _jsxs("span", { className: "text-text-muted", children: ["\u00B7 ", provider.plan] })] }), note === null ? (_jsx("div", { className: clsx('flex flex-col', compact ? 'gap-3' : 'gap-4'), children: provider.windows.map((window) => (_jsx(WindowBar, { window: window, now: now, compact: compact }, window.id))) })) : (_jsx("p", { className: "text-xs text-text-faint", children: note }))] }, limitsAccountId(provider)));
48
+ }) }));
49
+ }
50
+ /* One window on one line, for a card that holds several accounts: the label, a thin bar with the elapsed mark, the percent. */
51
+ function WindowLine({ window, now }) {
52
+ const { t } = useTranslation('agent-usage');
53
+ const percent = Math.round(window.used * 100);
54
+ const elapsed = elapsedShare(window, now);
55
+ const mark = elapsed === null ? null : Math.round(elapsed * 100);
56
+ return (_jsxs(_Fragment, { children: [_jsx("span", { className: "text-text-muted", children: window.label }), _jsxs("div", { role: "progressbar", "aria-label": t('limits.bar', { window: window.label, percent }), "aria-valuenow": percent, "aria-valuemin": 0, "aria-valuemax": 100, className: "relative h-1.5 rounded-full bg-surface-sunken", children: [_jsx("div", { className: clsx('absolute inset-y-0 left-0 rounded-full', toneOf(window.used)), style: { width: `${Math.min(100, percent)}%` } }), mark !== null && (_jsx("span", { "aria-hidden": true, className: clsx('absolute -inset-y-0.5 w-px -translate-x-1/2', mark <= percent ? 'bg-surface-raised' : 'bg-text-muted'), style: { left: `${mark}%` } }))] }), _jsx("span", { className: clsx('text-right tabular-nums', window.used >= 0.9 ? 'text-status-error' : 'text-text'), children: formatPercent(percent) })] }));
57
+ }
58
+ function AccountLines({ account, now }) {
59
+ const { t } = useTranslation('agent-usage');
60
+ const signedOut = isSignedOut(account);
61
+ const note = signedOut ? null : accountNote(account);
62
+ const windows = signedOut || note !== null ? [] : (account.entry?.windows ?? []);
63
+ const next = nextReset(windows, now);
64
+ const resetsIn = next === null ? null : resetInLabel(next.resetsAt, now);
65
+ return (_jsxs(_Fragment, { children: [_jsxs("p", { className: "col-span-full mt-2 flex min-w-0 items-center gap-2", children: [_jsx(AccountDot, { color: account.color }), _jsx("span", { className: "truncate", children: account.name }), signedOut ? (_jsxs("span", { className: "shrink-0 text-text-faint", children: ["\u00B7 ", t('limits.signedOut')] })) : (account.entry?.plan && _jsxs("span", { className: "shrink-0 text-text-muted", children: ["\u00B7 ", account.entry.plan] }))] }), note !== null && _jsx("p", { className: "col-span-full text-text-faint", children: note }), windows.map((window) => (_jsx(WindowLine, { window: window, now: now }, window.id))), next !== null && (_jsxs("p", { className: "col-span-full whitespace-nowrap text-text-faint", children: [t('limits.nextReset', { window: next.label, at: resetAtLabel(next.resetsAt, now) }), resetsIn !== null && ` · ${resetsIn}`] }))] }));
66
+ }
67
+ /*
68
+ * The hover card once a CLI has several accounts: a block per account, a line per window. One grid over
69
+ * the whole card, so the bars of every account start and end at the same place whatever their labels.
70
+ */
71
+ export function AccountLimitsList({ groups, now }) {
72
+ return (_jsx("div", { className: "grid grid-cols-[auto_minmax(0,1fr)_auto] items-center gap-x-2 gap-y-1 text-xs", children: groups.map((group) => (_jsxs(Fragment, { children: [_jsxs("p", { className: "col-span-full mt-3 flex items-center gap-2 font-medium first:mt-0", children: [_jsx("span", { style: { color: PROVIDER_COLORS[group.kind] }, children: _jsx(ProviderLogo, { provider: group.kind }) }), PROVIDER_LABELS[group.kind]] }), group.accounts.map((account) => (_jsx(AccountLines, { account: account, now: now }, account.id)))] }, group.kind))) }));
73
+ }
@@ -0,0 +1,9 @@
1
+ import type { UsageProvider, UsageSummaryResult } from '@adecore/agent-contracts';
2
+ import type { UsageMetric } from '../state/usage.js';
3
+ interface UsageBreakdownProps {
4
+ summary: UsageSummaryResult;
5
+ metric: UsageMetric;
6
+ providers: readonly UsageProvider[];
7
+ }
8
+ export declare function UsageBreakdown({ summary, metric, providers }: UsageBreakdownProps): import("react").JSX.Element;
9
+ export {};