@schlessera/brain-ui-react 0.4.0

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 (311) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +70 -0
  3. package/dist/components/chat/ask-user-card.d.ts +12 -0
  4. package/dist/components/chat/ask-user-card.d.ts.map +1 -0
  5. package/dist/components/chat/ask-user-card.js +185 -0
  6. package/dist/components/chat/ask-user-card.js.map +1 -0
  7. package/dist/components/chat/brain-markdown.d.ts +35 -0
  8. package/dist/components/chat/brain-markdown.d.ts.map +1 -0
  9. package/dist/components/chat/brain-markdown.js +363 -0
  10. package/dist/components/chat/brain-markdown.js.map +1 -0
  11. package/dist/components/chat/chat-page.d.ts +2 -0
  12. package/dist/components/chat/chat-page.d.ts.map +1 -0
  13. package/dist/components/chat/chat-page.js +442 -0
  14. package/dist/components/chat/chat-page.js.map +1 -0
  15. package/dist/components/chat/command-palette.d.ts +5 -0
  16. package/dist/components/chat/command-palette.d.ts.map +1 -0
  17. package/dist/components/chat/command-palette.js +18 -0
  18. package/dist/components/chat/command-palette.js.map +1 -0
  19. package/dist/components/chat/markdown-content.d.ts +4 -0
  20. package/dist/components/chat/markdown-content.d.ts.map +1 -0
  21. package/dist/components/chat/markdown-content.js +6 -0
  22. package/dist/components/chat/markdown-content.js.map +1 -0
  23. package/dist/components/chat/message-bubble.d.ts +9 -0
  24. package/dist/components/chat/message-bubble.d.ts.map +1 -0
  25. package/dist/components/chat/message-bubble.js +129 -0
  26. package/dist/components/chat/message-bubble.js.map +1 -0
  27. package/dist/components/chat/message-share.d.ts +10 -0
  28. package/dist/components/chat/message-share.d.ts.map +1 -0
  29. package/dist/components/chat/message-share.js +65 -0
  30. package/dist/components/chat/message-share.js.map +1 -0
  31. package/dist/components/chat/renderers/claude-tools.d.ts +3 -0
  32. package/dist/components/chat/renderers/claude-tools.d.ts.map +1 -0
  33. package/dist/components/chat/renderers/claude-tools.js +38 -0
  34. package/dist/components/chat/renderers/claude-tools.js.map +1 -0
  35. package/dist/components/chat/renderers/generic.d.ts +9 -0
  36. package/dist/components/chat/renderers/generic.d.ts.map +1 -0
  37. package/dist/components/chat/renderers/generic.js +68 -0
  38. package/dist/components/chat/renderers/generic.js.map +1 -0
  39. package/dist/components/chat/renderers/index.d.ts +5 -0
  40. package/dist/components/chat/renderers/index.d.ts.map +1 -0
  41. package/dist/components/chat/renderers/index.js +17 -0
  42. package/dist/components/chat/renderers/index.js.map +1 -0
  43. package/dist/components/chat/risk-hints.d.ts +20 -0
  44. package/dist/components/chat/risk-hints.d.ts.map +1 -0
  45. package/dist/components/chat/risk-hints.js +81 -0
  46. package/dist/components/chat/risk-hints.js.map +1 -0
  47. package/dist/components/chat/session-drawer.d.ts +6 -0
  48. package/dist/components/chat/session-drawer.d.ts.map +1 -0
  49. package/dist/components/chat/session-drawer.js +96 -0
  50. package/dist/components/chat/session-drawer.js.map +1 -0
  51. package/dist/components/chat/share-block.d.ts +9 -0
  52. package/dist/components/chat/share-block.d.ts.map +1 -0
  53. package/dist/components/chat/share-block.js +70 -0
  54. package/dist/components/chat/share-block.js.map +1 -0
  55. package/dist/components/chat/tool-call-timeline.d.ts +8 -0
  56. package/dist/components/chat/tool-call-timeline.d.ts.map +1 -0
  57. package/dist/components/chat/tool-call-timeline.js +100 -0
  58. package/dist/components/chat/tool-call-timeline.js.map +1 -0
  59. package/dist/components/chat/tool-views.d.ts +116 -0
  60. package/dist/components/chat/tool-views.d.ts.map +1 -0
  61. package/dist/components/chat/tool-views.js +628 -0
  62. package/dist/components/chat/tool-views.js.map +1 -0
  63. package/dist/components/chat/welcome-state.d.ts +4 -0
  64. package/dist/components/chat/welcome-state.d.ts.map +1 -0
  65. package/dist/components/chat/welcome-state.js +10 -0
  66. package/dist/components/chat/welcome-state.js.map +1 -0
  67. package/dist/components/connectivity/connection-gate.d.ts +5 -0
  68. package/dist/components/connectivity/connection-gate.d.ts.map +1 -0
  69. package/dist/components/connectivity/connection-gate.js +42 -0
  70. package/dist/components/connectivity/connection-gate.js.map +1 -0
  71. package/dist/components/connectivity/login-screen.d.ts +9 -0
  72. package/dist/components/connectivity/login-screen.d.ts.map +1 -0
  73. package/dist/components/connectivity/login-screen.js +99 -0
  74. package/dist/components/connectivity/login-screen.js.map +1 -0
  75. package/dist/components/files/file-panel.d.ts +5 -0
  76. package/dist/components/files/file-panel.d.ts.map +1 -0
  77. package/dist/components/files/file-panel.js +46 -0
  78. package/dist/components/files/file-panel.js.map +1 -0
  79. package/dist/components/files/file-tree.d.ts +2 -0
  80. package/dist/components/files/file-tree.d.ts.map +1 -0
  81. package/dist/components/files/file-tree.js +63 -0
  82. package/dist/components/files/file-tree.js.map +1 -0
  83. package/dist/components/files/file-viewer-binary.d.ts +5 -0
  84. package/dist/components/files/file-viewer-binary.d.ts.map +1 -0
  85. package/dist/components/files/file-viewer-binary.js +20 -0
  86. package/dist/components/files/file-viewer-binary.js.map +1 -0
  87. package/dist/components/files/file-viewer-html.d.ts +4 -0
  88. package/dist/components/files/file-viewer-html.d.ts.map +1 -0
  89. package/dist/components/files/file-viewer-html.js +5 -0
  90. package/dist/components/files/file-viewer-html.js.map +1 -0
  91. package/dist/components/files/file-viewer-markdown.d.ts +4 -0
  92. package/dist/components/files/file-viewer-markdown.d.ts.map +1 -0
  93. package/dist/components/files/file-viewer-markdown.js +10 -0
  94. package/dist/components/files/file-viewer-markdown.js.map +1 -0
  95. package/dist/components/files/file-viewer-raw.d.ts +5 -0
  96. package/dist/components/files/file-viewer-raw.d.ts.map +1 -0
  97. package/dist/components/files/file-viewer-raw.js +15 -0
  98. package/dist/components/files/file-viewer-raw.js.map +1 -0
  99. package/dist/components/files/file-viewer.d.ts +2 -0
  100. package/dist/components/files/file-viewer.d.ts.map +1 -0
  101. package/dist/components/files/file-viewer.js +175 -0
  102. package/dist/components/files/file-viewer.js.map +1 -0
  103. package/dist/components/files/frontmatter-panel.d.ts +5 -0
  104. package/dist/components/files/frontmatter-panel.d.ts.map +1 -0
  105. package/dist/components/files/frontmatter-panel.js +12 -0
  106. package/dist/components/files/frontmatter-panel.js.map +1 -0
  107. package/dist/components/layout/app-shell.d.ts +5 -0
  108. package/dist/components/layout/app-shell.d.ts.map +1 -0
  109. package/dist/components/layout/app-shell.js +10 -0
  110. package/dist/components/layout/app-shell.js.map +1 -0
  111. package/dist/components/layout/mobile-tab-bar.d.ts +2 -0
  112. package/dist/components/layout/mobile-tab-bar.d.ts.map +1 -0
  113. package/dist/components/layout/mobile-tab-bar.js +16 -0
  114. package/dist/components/layout/mobile-tab-bar.js.map +1 -0
  115. package/dist/components/layout/side-rail.d.ts +2 -0
  116. package/dist/components/layout/side-rail.d.ts.map +1 -0
  117. package/dist/components/layout/side-rail.js +26 -0
  118. package/dist/components/layout/side-rail.js.map +1 -0
  119. package/dist/components/layout/slide-panel.d.ts +9 -0
  120. package/dist/components/layout/slide-panel.d.ts.map +1 -0
  121. package/dist/components/layout/slide-panel.js +18 -0
  122. package/dist/components/layout/slide-panel.js.map +1 -0
  123. package/dist/components/quick-actions/streaming-modal.d.ts +8 -0
  124. package/dist/components/quick-actions/streaming-modal.d.ts.map +1 -0
  125. package/dist/components/quick-actions/streaming-modal.js +92 -0
  126. package/dist/components/quick-actions/streaming-modal.js.map +1 -0
  127. package/dist/components/quick-actions/whatsup-modal.d.ts +5 -0
  128. package/dist/components/quick-actions/whatsup-modal.d.ts.map +1 -0
  129. package/dist/components/quick-actions/whatsup-modal.js +82 -0
  130. package/dist/components/quick-actions/whatsup-modal.js.map +1 -0
  131. package/dist/components/settings/passkey-panel.d.ts +10 -0
  132. package/dist/components/settings/passkey-panel.d.ts.map +1 -0
  133. package/dist/components/settings/passkey-panel.js +118 -0
  134. package/dist/components/settings/passkey-panel.js.map +1 -0
  135. package/dist/components/share/share-menu.d.ts +23 -0
  136. package/dist/components/share/share-menu.d.ts.map +1 -0
  137. package/dist/components/share/share-menu.js +58 -0
  138. package/dist/components/share/share-menu.js.map +1 -0
  139. package/dist/components/voice/dictation-sheet.d.ts +6 -0
  140. package/dist/components/voice/dictation-sheet.d.ts.map +1 -0
  141. package/dist/components/voice/dictation-sheet.js +91 -0
  142. package/dist/components/voice/dictation-sheet.js.map +1 -0
  143. package/dist/components/voice/mic-button.d.ts +6 -0
  144. package/dist/components/voice/mic-button.d.ts.map +1 -0
  145. package/dist/components/voice/mic-button.js +9 -0
  146. package/dist/components/voice/mic-button.js.map +1 -0
  147. package/dist/components/voice/review-card.d.ts +8 -0
  148. package/dist/components/voice/review-card.d.ts.map +1 -0
  149. package/dist/components/voice/review-card.js +8 -0
  150. package/dist/components/voice/review-card.js.map +1 -0
  151. package/dist/config.d.ts +19 -0
  152. package/dist/config.d.ts.map +1 -0
  153. package/dist/config.js +10 -0
  154. package/dist/config.js.map +1 -0
  155. package/dist/hooks/use-vpn-status.d.ts +2 -0
  156. package/dist/hooks/use-vpn-status.d.ts.map +1 -0
  157. package/dist/hooks/use-vpn-status.js +71 -0
  158. package/dist/hooks/use-vpn-status.js.map +1 -0
  159. package/dist/hooks/use-websocket.d.ts +8 -0
  160. package/dist/hooks/use-websocket.d.ts.map +1 -0
  161. package/dist/hooks/use-websocket.js +366 -0
  162. package/dist/hooks/use-websocket.js.map +1 -0
  163. package/dist/index.d.ts +25 -0
  164. package/dist/index.d.ts.map +1 -0
  165. package/dist/index.js +31 -0
  166. package/dist/index.js.map +1 -0
  167. package/dist/lib/api-client.d.ts +115 -0
  168. package/dist/lib/api-client.d.ts.map +1 -0
  169. package/dist/lib/api-client.js +70 -0
  170. package/dist/lib/api-client.js.map +1 -0
  171. package/dist/lib/backend.d.ts +7 -0
  172. package/dist/lib/backend.d.ts.map +1 -0
  173. package/dist/lib/backend.js +33 -0
  174. package/dist/lib/backend.js.map +1 -0
  175. package/dist/lib/frontmatter.d.ts +21 -0
  176. package/dist/lib/frontmatter.d.ts.map +1 -0
  177. package/dist/lib/frontmatter.js +88 -0
  178. package/dist/lib/frontmatter.js.map +1 -0
  179. package/dist/lib/image-attachments.d.ts +36 -0
  180. package/dist/lib/image-attachments.d.ts.map +1 -0
  181. package/dist/lib/image-attachments.js +175 -0
  182. package/dist/lib/image-attachments.js.map +1 -0
  183. package/dist/lib/passkeys.d.ts +18 -0
  184. package/dist/lib/passkeys.d.ts.map +1 -0
  185. package/dist/lib/passkeys.js +36 -0
  186. package/dist/lib/passkeys.js.map +1 -0
  187. package/dist/lib/share.d.ts +53 -0
  188. package/dist/lib/share.d.ts.map +1 -0
  189. package/dist/lib/share.js +144 -0
  190. package/dist/lib/share.js.map +1 -0
  191. package/dist/lib/strip-markdown.d.ts +10 -0
  192. package/dist/lib/strip-markdown.d.ts.map +1 -0
  193. package/dist/lib/strip-markdown.js +37 -0
  194. package/dist/lib/strip-markdown.js.map +1 -0
  195. package/dist/lib/tool-names.d.ts +17 -0
  196. package/dist/lib/tool-names.d.ts.map +1 -0
  197. package/dist/lib/tool-names.js +23 -0
  198. package/dist/lib/tool-names.js.map +1 -0
  199. package/dist/lib/utils.d.ts +3 -0
  200. package/dist/lib/utils.d.ts.map +1 -0
  201. package/dist/lib/utils.js +6 -0
  202. package/dist/lib/utils.js.map +1 -0
  203. package/dist/lib/ws-client.d.ts +26 -0
  204. package/dist/lib/ws-client.d.ts.map +1 -0
  205. package/dist/lib/ws-client.js +93 -0
  206. package/dist/lib/ws-client.js.map +1 -0
  207. package/dist/stores/chat-store.d.ts +131 -0
  208. package/dist/stores/chat-store.d.ts.map +1 -0
  209. package/dist/stores/chat-store.js +376 -0
  210. package/dist/stores/chat-store.js.map +1 -0
  211. package/dist/stores/connection-store.d.ts +11 -0
  212. package/dist/stores/connection-store.d.ts.map +1 -0
  213. package/dist/stores/connection-store.js +8 -0
  214. package/dist/stores/connection-store.js.map +1 -0
  215. package/dist/stores/file-store.d.ts +53 -0
  216. package/dist/stores/file-store.d.ts.map +1 -0
  217. package/dist/stores/file-store.js +284 -0
  218. package/dist/stores/file-store.js.map +1 -0
  219. package/dist/stores/provider-store.d.ts +24 -0
  220. package/dist/stores/provider-store.d.ts.map +1 -0
  221. package/dist/stores/provider-store.js +56 -0
  222. package/dist/stores/provider-store.js.map +1 -0
  223. package/dist/stores/ui-store.d.ts +21 -0
  224. package/dist/stores/ui-store.d.ts.map +1 -0
  225. package/dist/stores/ui-store.js +23 -0
  226. package/dist/stores/ui-store.js.map +1 -0
  227. package/dist/styles.css +2 -0
  228. package/dist/voice/asr-clients.d.ts +2 -0
  229. package/dist/voice/asr-clients.d.ts.map +1 -0
  230. package/dist/voice/asr-clients.js +33 -0
  231. package/dist/voice/asr-clients.js.map +1 -0
  232. package/dist/voice/asr-deepgram.d.ts +38 -0
  233. package/dist/voice/asr-deepgram.d.ts.map +1 -0
  234. package/dist/voice/asr-deepgram.js +307 -0
  235. package/dist/voice/asr-deepgram.js.map +1 -0
  236. package/dist/voice/asr-webspeech.d.ts +23 -0
  237. package/dist/voice/asr-webspeech.d.ts.map +1 -0
  238. package/dist/voice/asr-webspeech.js +93 -0
  239. package/dist/voice/asr-webspeech.js.map +1 -0
  240. package/dist/voice/use-dictation.d.ts +6 -0
  241. package/dist/voice/use-dictation.d.ts.map +1 -0
  242. package/dist/voice/use-dictation.js +174 -0
  243. package/dist/voice/use-dictation.js.map +1 -0
  244. package/dist/voice/voice-store.d.ts +26 -0
  245. package/dist/voice/voice-store.d.ts.map +1 -0
  246. package/dist/voice/voice-store.js +27 -0
  247. package/dist/voice/voice-store.js.map +1 -0
  248. package/package.json +71 -0
  249. package/src/components/chat/ask-user-card.tsx +451 -0
  250. package/src/components/chat/brain-markdown.tsx +547 -0
  251. package/src/components/chat/chat-page.tsx +820 -0
  252. package/src/components/chat/command-palette.tsx +68 -0
  253. package/src/components/chat/markdown-content.tsx +5 -0
  254. package/src/components/chat/message-bubble.tsx +362 -0
  255. package/src/components/chat/message-share.ts +78 -0
  256. package/src/components/chat/renderers/claude-tools.tsx +53 -0
  257. package/src/components/chat/renderers/generic.tsx +85 -0
  258. package/src/components/chat/renderers/index.ts +19 -0
  259. package/src/components/chat/risk-hints.ts +95 -0
  260. package/src/components/chat/session-drawer.tsx +213 -0
  261. package/src/components/chat/share-block.tsx +128 -0
  262. package/src/components/chat/tool-call-timeline.tsx +322 -0
  263. package/src/components/chat/tool-views.tsx +898 -0
  264. package/src/components/chat/welcome-state.tsx +105 -0
  265. package/src/components/connectivity/connection-gate.tsx +137 -0
  266. package/src/components/connectivity/login-screen.tsx +169 -0
  267. package/src/components/files/file-panel.tsx +116 -0
  268. package/src/components/files/file-tree.tsx +143 -0
  269. package/src/components/files/file-viewer-binary.tsx +63 -0
  270. package/src/components/files/file-viewer-html.tsx +10 -0
  271. package/src/components/files/file-viewer-markdown.tsx +14 -0
  272. package/src/components/files/file-viewer-raw.tsx +44 -0
  273. package/src/components/files/file-viewer.tsx +290 -0
  274. package/src/components/files/frontmatter-panel.tsx +78 -0
  275. package/src/components/layout/app-shell.tsx +25 -0
  276. package/src/components/layout/mobile-tab-bar.tsx +54 -0
  277. package/src/components/layout/side-rail.tsx +128 -0
  278. package/src/components/layout/slide-panel.tsx +64 -0
  279. package/src/components/quick-actions/streaming-modal.tsx +168 -0
  280. package/src/components/quick-actions/whatsup-modal.tsx +149 -0
  281. package/src/components/settings/passkey-panel.tsx +281 -0
  282. package/src/components/share/share-menu.tsx +121 -0
  283. package/src/components/voice/dictation-sheet.tsx +217 -0
  284. package/src/components/voice/mic-button.tsx +31 -0
  285. package/src/components/voice/review-card.tsx +66 -0
  286. package/src/config.ts +27 -0
  287. package/src/hooks/use-vpn-status.ts +75 -0
  288. package/src/hooks/use-websocket.ts +403 -0
  289. package/src/index.ts +46 -0
  290. package/src/lib/api-client.ts +173 -0
  291. package/src/lib/backend.ts +35 -0
  292. package/src/lib/frontmatter.ts +99 -0
  293. package/src/lib/image-attachments.ts +221 -0
  294. package/src/lib/passkeys.ts +50 -0
  295. package/src/lib/share.ts +167 -0
  296. package/src/lib/strip-markdown.ts +38 -0
  297. package/src/lib/tool-names.ts +27 -0
  298. package/src/lib/utils.ts +6 -0
  299. package/src/lib/ws-client.ts +109 -0
  300. package/src/stores/chat-store.ts +619 -0
  301. package/src/stores/connection-store.ts +23 -0
  302. package/src/stores/file-store.ts +344 -0
  303. package/src/stores/provider-store.ts +85 -0
  304. package/src/stores/ui-store.ts +48 -0
  305. package/src/styles.css +4 -0
  306. package/src/theme.css +425 -0
  307. package/src/voice/asr-clients.ts +45 -0
  308. package/src/voice/asr-deepgram.ts +325 -0
  309. package/src/voice/asr-webspeech.ts +135 -0
  310. package/src/voice/use-dictation.ts +187 -0
  311. package/src/voice/voice-store.ts +55 -0
@@ -0,0 +1,376 @@
1
+ import { create } from "zustand";
2
+ import { useProviderStore } from "./provider-store.js";
3
+ /** Retained transcript buffers beyond the active one (LRU-evicted). */
4
+ const MAX_BUFFERS = 8;
5
+ let messageCounter = 0;
6
+ function nextId() {
7
+ return `msg-${++messageCounter}-${Date.now()}`;
8
+ }
9
+ const SESSION_ID_KEY = "brain-sessionId";
10
+ /**
11
+ * Persist the active session id to localStorage when a DOM is present (the
12
+ * browser). A no-op in non-DOM environments (tests, SSR) so creating the store
13
+ * never throws on a missing `localStorage`.
14
+ */
15
+ function persistSessionId(id) {
16
+ if (typeof localStorage === "undefined")
17
+ return;
18
+ if (id)
19
+ localStorage.setItem(SESSION_ID_KEY, id);
20
+ else
21
+ localStorage.removeItem(SESSION_ID_KEY);
22
+ }
23
+ function readPersistedSessionId() {
24
+ if (typeof localStorage === "undefined")
25
+ return null;
26
+ return localStorage.getItem(SESSION_ID_KEY);
27
+ }
28
+ function emptyChat() {
29
+ return { messages: [], isStreaming: false, askUser: null, lastTouched: Date.now() };
30
+ }
31
+ /** Frozen empty buffer for selectors when nothing is in view. */
32
+ const EMPTY_CHAT = Object.freeze({
33
+ messages: Object.freeze([]),
34
+ isStreaming: false,
35
+ askUser: null,
36
+ lastTouched: 0,
37
+ });
38
+ /** The buffer currently in view (draft when no session is bound). */
39
+ export function activeChat(state) {
40
+ if (state.activeSessionId)
41
+ return state.buffers[state.activeSessionId] ?? EMPTY_CHAT;
42
+ return state.draft ?? EMPTY_CHAT;
43
+ }
44
+ /** True when ANY buffer is streaming (service-worker busy check, etc.). */
45
+ export function anyStreaming(state) {
46
+ if (state.draft?.isStreaming)
47
+ return true;
48
+ return Object.values(state.buffers).some((b) => b.isStreaming);
49
+ }
50
+ /** Append text to the last part if it has the same kind, else start a new part. */
51
+ function appendPart(parts, kind, text) {
52
+ const last = parts[parts.length - 1];
53
+ if (last && last.kind === kind) {
54
+ return [...parts.slice(0, -1), { kind, text: last.text + text }];
55
+ }
56
+ return [...parts, { kind, text }];
57
+ }
58
+ /** Free object URLs held by live message previews before dropping them. */
59
+ function revokeAttachmentUrls(messages) {
60
+ for (const m of messages) {
61
+ for (const a of m.attachments ?? []) {
62
+ if (a.previewUrl.startsWith("blob:"))
63
+ URL.revokeObjectURL(a.previewUrl);
64
+ }
65
+ }
66
+ }
67
+ /** Evict least-recently-touched non-active buffers beyond MAX_BUFFERS. */
68
+ function evictStale(buffers, activeSessionId) {
69
+ const ids = Object.keys(buffers);
70
+ if (ids.length <= MAX_BUFFERS)
71
+ return buffers;
72
+ const evictable = ids
73
+ .filter((id) => id !== activeSessionId && !buffers[id].isStreaming)
74
+ .sort((a, b) => buffers[a].lastTouched - buffers[b].lastTouched);
75
+ const next = { ...buffers };
76
+ for (const id of evictable.slice(0, ids.length - MAX_BUFFERS)) {
77
+ revokeAttachmentUrls(next[id].messages);
78
+ delete next[id];
79
+ }
80
+ return next;
81
+ }
82
+ export const useChatStore = create((set, get) => {
83
+ /**
84
+ * Immutably update one buffer. Draft mutations (key null) create the draft
85
+ * on demand; session mutations require an existing buffer — a frame for an
86
+ * evicted/never-opened session must not materialize a partial transcript
87
+ * (the view heals via session_resume instead).
88
+ */
89
+ function mutateBuffer(key, fn, createIfMissing = false) {
90
+ set((state) => {
91
+ if (key === null) {
92
+ const draft = state.draft ?? emptyChat();
93
+ return { draft: { ...draft, ...fn(draft), lastTouched: Date.now() } };
94
+ }
95
+ const existing = state.buffers[key] ?? (createIfMissing ? emptyChat() : undefined);
96
+ if (!existing)
97
+ return state;
98
+ return {
99
+ buffers: {
100
+ ...state.buffers,
101
+ [key]: { ...existing, ...fn(existing), lastTouched: Date.now() },
102
+ },
103
+ };
104
+ });
105
+ }
106
+ /** Update the last message of a buffer when it is an assistant message. */
107
+ function mutateLastAssistant(key, fn, extra) {
108
+ mutateBuffer(key, (chat) => {
109
+ const msgs = [...chat.messages];
110
+ const last = msgs[msgs.length - 1];
111
+ let out = {};
112
+ if (last?.role === "assistant") {
113
+ msgs[msgs.length - 1] = fn(last);
114
+ out = { messages: msgs };
115
+ }
116
+ return extra ? { ...out, ...extra(chat) } : out;
117
+ });
118
+ }
119
+ return {
120
+ buffers: {},
121
+ draft: null,
122
+ // localStorage (not sessionStorage) so the active session id survives the
123
+ // PWA process being killed on mobile — that durability is what lets a cold
124
+ // relaunch re-request the full transcript instead of showing nothing.
125
+ activeSessionId: readPersistedSessionId(),
126
+ runStates: {},
127
+ // createIfMissing: a user-initiated send must never be dropped, even when
128
+ // the active session's buffer hasn't been materialized yet (cold start
129
+ // racing the history replay).
130
+ addUserMessage: (key, text, source, attachments) => mutateBuffer(key, (chat) => ({
131
+ messages: [
132
+ ...chat.messages,
133
+ {
134
+ id: nextId(),
135
+ role: "user",
136
+ content: text,
137
+ toolCalls: [],
138
+ parts: [],
139
+ isStreaming: false,
140
+ timestamp: Date.now(),
141
+ source: source ?? "typed",
142
+ ...(attachments && attachments.length > 0
143
+ ? { attachments, attachmentCount: attachments.length }
144
+ : {}),
145
+ },
146
+ ],
147
+ }), true),
148
+ startAssistantMessage: (key) => mutateBuffer(key, (chat) => ({
149
+ messages: [
150
+ ...chat.messages,
151
+ {
152
+ id: nextId(),
153
+ role: "assistant",
154
+ content: "",
155
+ thinking: "",
156
+ toolCalls: [],
157
+ parts: [],
158
+ isStreaming: true,
159
+ timestamp: Date.now(),
160
+ },
161
+ ],
162
+ isStreaming: true,
163
+ })),
164
+ appendText: (key, text) => mutateLastAssistant(key, (last) => ({
165
+ ...last,
166
+ content: last.content + text,
167
+ parts: appendPart(last.parts, "text", text),
168
+ })),
169
+ appendThinking: (key, text) => mutateLastAssistant(key, (last) => ({
170
+ ...last,
171
+ thinking: (last.thinking || "") + text,
172
+ parts: appendPart(last.parts, "thinking", text),
173
+ })),
174
+ startToolCall: (key, toolUseId, toolName) => mutateLastAssistant(key, (last) => ({
175
+ ...last,
176
+ parts: [...last.parts, { kind: "tool", toolIndex: last.toolCalls.length }],
177
+ toolCalls: [
178
+ ...last.toolCalls,
179
+ {
180
+ id: toolUseId,
181
+ name: toolName,
182
+ input: {},
183
+ inputJson: "",
184
+ status: "streaming",
185
+ startedAt: Date.now(),
186
+ },
187
+ ],
188
+ })),
189
+ appendToolInput: (key, partialJson) => mutateLastAssistant(key, (last) => {
190
+ if (last.toolCalls.length === 0)
191
+ return last;
192
+ const tools = [...last.toolCalls];
193
+ const lastTool = tools[tools.length - 1];
194
+ tools[tools.length - 1] = {
195
+ ...lastTool,
196
+ inputJson: lastTool.inputJson + partialJson,
197
+ };
198
+ return { ...last, toolCalls: tools };
199
+ }),
200
+ completeToolCall: (key, toolUseId, toolName, input) => mutateLastAssistant(key, (last) => ({
201
+ ...last,
202
+ toolCalls: last.toolCalls.map((t) => t.id === toolUseId || (t.name === toolName && t.status === "streaming")
203
+ ? {
204
+ ...t,
205
+ id: toolUseId,
206
+ input,
207
+ status: "complete",
208
+ // Input finished streaming — execution starts about now
209
+ startedAt: Date.now(),
210
+ }
211
+ : t),
212
+ })),
213
+ requestToolApproval: (key, toolUseId, toolName, input, description) => mutateLastAssistant(key, (last) => {
214
+ // Check if tool call already exists (from streaming)
215
+ const existingIdx = last.toolCalls.findIndex((t) => t.id === toolUseId || (t.name === toolName && t.status === "streaming"));
216
+ const tools = [...last.toolCalls];
217
+ const toolCall = {
218
+ id: toolUseId,
219
+ name: toolName,
220
+ input,
221
+ inputJson: JSON.stringify(input, null, 2),
222
+ status: "pending_approval",
223
+ };
224
+ let parts = last.parts;
225
+ if (existingIdx >= 0) {
226
+ tools[existingIdx] = toolCall;
227
+ }
228
+ else {
229
+ // Approval request for a tool that never streamed a start event —
230
+ // give it a chronological slot too.
231
+ parts = [...parts, { kind: "tool", toolIndex: tools.length }];
232
+ tools.push(toolCall);
233
+ }
234
+ return { ...last, toolCalls: tools, parts };
235
+ }),
236
+ resolveToolApproval: (key, toolUseId, approved) => mutateLastAssistant(key, (last) => ({
237
+ ...last,
238
+ toolCalls: last.toolCalls.map((t) => t.id === toolUseId
239
+ ? {
240
+ ...t,
241
+ status: approved ? "approved" : "denied",
242
+ // Don't let approval wait time inflate the duration badge
243
+ ...(approved ? { startedAt: Date.now() } : {}),
244
+ }
245
+ : t),
246
+ })),
247
+ setToolResult: (key, toolUseId, output, isError) => mutateLastAssistant(key, (last) => ({
248
+ ...last,
249
+ toolCalls: last.toolCalls.map((t) => t.id === toolUseId
250
+ ? {
251
+ ...t,
252
+ output,
253
+ isError,
254
+ status: "complete",
255
+ endedAt: Date.now(),
256
+ }
257
+ : t),
258
+ })),
259
+ setAskUserRequest: (key, requestId, questions) => mutateBuffer(key, (chat) => {
260
+ const exchange = { requestId, questions };
261
+ const msgs = [...chat.messages];
262
+ const lastIdx = msgs.length - 1;
263
+ const last = msgs[lastIdx];
264
+ if (last?.role === "assistant") {
265
+ msgs[lastIdx] = {
266
+ ...last,
267
+ askUserExchanges: [...(last.askUserExchanges ?? []), exchange],
268
+ };
269
+ }
270
+ return { messages: msgs, askUser: exchange };
271
+ }),
272
+ submitAskUserAnswers: (key, requestId, answers, annotations) => mutateBuffer(key, (chat) => {
273
+ const update = (e) => e.requestId === requestId ? { ...e, answers, annotations } : e;
274
+ const msgs = chat.messages.map((m) => m.askUserExchanges?.some((e) => e.requestId === requestId)
275
+ ? { ...m, askUserExchanges: m.askUserExchanges.map(update) }
276
+ : m);
277
+ const askUser = chat.askUser?.requestId === requestId ? update(chat.askUser) : chat.askUser;
278
+ return { messages: msgs, askUser };
279
+ }),
280
+ cancelAskUser: (key, requestId) => mutateBuffer(key, (chat) => {
281
+ const update = (e) => e.requestId === requestId ? { ...e, cancelled: true } : e;
282
+ const msgs = chat.messages.map((m) => m.askUserExchanges?.some((e) => e.requestId === requestId)
283
+ ? { ...m, askUserExchanges: m.askUserExchanges.map(update) }
284
+ : m);
285
+ const askUser = chat.askUser?.requestId === requestId ? update(chat.askUser) : chat.askUser;
286
+ return { messages: msgs, askUser };
287
+ }),
288
+ clearAskUser: (key) => mutateBuffer(key, () => ({ askUser: null })),
289
+ finishAssistantMessage: (key) => mutateLastAssistant(key, (last) => ({ ...last, isStreaming: false }), () => ({ isStreaming: false })),
290
+ setStreaming: (key, streaming) => mutateBuffer(key, () => ({ isStreaming: streaming })),
291
+ setMessages: (key, messages) => set((state) => {
292
+ if (key === null) {
293
+ if (state.draft)
294
+ revokeAttachmentUrls(state.draft.messages);
295
+ return {
296
+ draft: { ...emptyChat(), messages },
297
+ };
298
+ }
299
+ const existing = state.buffers[key];
300
+ if (existing)
301
+ revokeAttachmentUrls(existing.messages);
302
+ const buffers = {
303
+ ...state.buffers,
304
+ [key]: { ...emptyChat(), messages },
305
+ };
306
+ return { buffers: evictStale(buffers, state.activeSessionId) };
307
+ }),
308
+ appendMessages: (key, messages) => set((state) => {
309
+ if (key === null) {
310
+ const draft = state.draft ?? emptyChat();
311
+ return { draft: { ...draft, messages: [...draft.messages, ...messages] } };
312
+ }
313
+ const existing = state.buffers[key] ?? emptyChat();
314
+ return {
315
+ buffers: {
316
+ ...state.buffers,
317
+ [key]: {
318
+ ...existing,
319
+ messages: [...existing.messages, ...messages],
320
+ lastTouched: Date.now(),
321
+ },
322
+ },
323
+ };
324
+ }),
325
+ bindDraftSession: (sessionId) => set((state) => {
326
+ const adopted = state.buffers[sessionId] ?? state.draft ?? emptyChat();
327
+ const buffers = evictStale({ ...state.buffers, [sessionId]: { ...adopted, lastTouched: Date.now() } }, sessionId);
328
+ const followView = state.activeSessionId === null;
329
+ if (followView)
330
+ persistSessionId(sessionId);
331
+ return {
332
+ buffers,
333
+ draft: null,
334
+ ...(followView ? { activeSessionId: sessionId } : {}),
335
+ };
336
+ }),
337
+ setActiveSession: (sessionId) => set((state) => {
338
+ persistSessionId(sessionId);
339
+ if (sessionId === null)
340
+ return { activeSessionId: null };
341
+ const existing = state.buffers[sessionId];
342
+ const buffers = existing
343
+ ? state.buffers
344
+ : evictStale({ ...state.buffers, [sessionId]: emptyChat() }, sessionId);
345
+ return { activeSessionId: sessionId, buffers };
346
+ }),
347
+ setRunState: (sessionId, runState) => set((state) => {
348
+ if (state.runStates[sessionId] === runState)
349
+ return state;
350
+ const runStates = { ...state.runStates };
351
+ if (runState === "idle")
352
+ delete runStates[sessionId];
353
+ else
354
+ runStates[sessionId] = runState;
355
+ return { runStates };
356
+ }),
357
+ clearMessages: () => {
358
+ const state = get();
359
+ if (state.draft)
360
+ revokeAttachmentUrls(state.draft.messages);
361
+ persistSessionId(null);
362
+ // Starting fresh: unpin the provider so the picker unlocks.
363
+ useProviderStore.getState().setPinned(null);
364
+ set({ draft: null, activeSessionId: null });
365
+ },
366
+ };
367
+ });
368
+ // Dev-only handle so browser automation / manual debugging can inject
369
+ // fixture messages without a live Claude session. The env read is defensive:
370
+ // outside a Vite build `import.meta.env` does not exist.
371
+ const devEnv = import.meta.env;
372
+ if (typeof window !== "undefined" && devEnv?.DEV) {
373
+ window.__chatStore =
374
+ useChatStore;
375
+ }
376
+ //# sourceMappingURL=chat-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chat-store.js","sourceRoot":"","sources":["../../src/stores/chat-store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ type WsStatus = "connecting" | "connected" | "disconnected";
2
+ type VpnStatus = "connected" | "forbidden" | "unauthorized" | "unreachable" | "checking";
3
+ interface ConnectionState {
4
+ wsStatus: WsStatus;
5
+ vpnStatus: VpnStatus;
6
+ setWsStatus: (status: WsStatus) => void;
7
+ setVpnStatus: (status: VpnStatus) => void;
8
+ }
9
+ export declare const useConnectionStore: import("zustand").UseBoundStore<import("zustand").StoreApi<ConnectionState>>;
10
+ export {};
11
+ //# sourceMappingURL=connection-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connection-store.d.ts","sourceRoot":"","sources":["../../src/stores/connection-store.ts"],"names":[],"mappings":"AAEA,KAAK,QAAQ,GAAG,YAAY,GAAG,WAAW,GAAG,cAAc,CAAC;AAC5D,KAAK,SAAS,GACV,WAAW,GACX,WAAW,GACX,cAAc,GACd,aAAa,GACb,UAAU,CAAC;AAEf,UAAU,eAAe;IACvB,QAAQ,EAAE,QAAQ,CAAC;IACnB,SAAS,EAAE,SAAS,CAAC;IACrB,WAAW,EAAE,CAAC,MAAM,EAAE,QAAQ,KAAK,IAAI,CAAC;IACxC,YAAY,EAAE,CAAC,MAAM,EAAE,SAAS,KAAK,IAAI,CAAC;CAC3C;AAED,eAAO,MAAM,kBAAkB,8EAK5B,CAAC"}
@@ -0,0 +1,8 @@
1
+ import { create } from "zustand";
2
+ export const useConnectionStore = create((set) => ({
3
+ wsStatus: "disconnected",
4
+ vpnStatus: "checking",
5
+ setWsStatus: (wsStatus) => set({ wsStatus }),
6
+ setVpnStatus: (vpnStatus) => set({ vpnStatus }),
7
+ }));
8
+ //# sourceMappingURL=connection-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connection-store.js","sourceRoot":"","sources":["../../src/stores/connection-store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAiBjC,MAAM,CAAC,MAAM,kBAAkB,GAAG,MAAM,CAAkB,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;IAClE,QAAQ,EAAE,cAAc;IACxB,SAAS,EAAE,UAAU;IACrB,WAAW,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC,GAAG,CAAC,EAAE,QAAQ,EAAE,CAAC;IAC5C,YAAY,EAAE,CAAC,SAAS,EAAE,EAAE,CAAC,GAAG,CAAC,EAAE,SAAS,EAAE,CAAC;CAChD,CAAC,CAAC,CAAC"}
@@ -0,0 +1,53 @@
1
+ import type { FileEntry, FileContentResponse } from "@schlessera/brain-ui-sdk/protocol";
2
+ export type ViewMode = "preview" | "raw";
3
+ interface FileState {
4
+ dirCache: Record<string, FileEntry[]>;
5
+ loadingDirs: Set<string>;
6
+ dirErrors: Record<string, string>;
7
+ expandedDirs: Set<string>;
8
+ currentPath: string | null;
9
+ currentContent: FileContentResponse | null;
10
+ contentLoading: boolean;
11
+ contentError: string | null;
12
+ viewMode: ViewMode;
13
+ treeExpanded: boolean;
14
+ /**
15
+ * Whether the frontmatter table at the top of markdown files is collapsed.
16
+ * Persisted in localStorage so the preference carries across files.
17
+ */
18
+ frontmatterCollapsed: boolean;
19
+ /**
20
+ * Directory most recently navigated to via openDir. Used by the tree to
21
+ * apply a brief highlight + scroll the node into view. Cleared shortly
22
+ * after by openDir itself.
23
+ */
24
+ highlightedDir: string | null;
25
+ /**
26
+ * Lowercase slug -> repo-relative .md path. Lazily loaded the first
27
+ * time a markdown surface needs to resolve a [[wikilink]].
28
+ */
29
+ wikilinkMap: Record<string, string>;
30
+ wikilinkLoaded: boolean;
31
+ wikilinkLoading: boolean;
32
+ loadDir: (path: string) => Promise<void>;
33
+ toggleDir: (path: string) => Promise<void>;
34
+ setExpanded: (path: string, expanded: boolean) => void;
35
+ openFile: (path: string) => Promise<void>;
36
+ openDir: (path: string) => Promise<void>;
37
+ closeFile: () => void;
38
+ setViewMode: (mode: ViewMode) => void;
39
+ setTreeExpanded: (expanded: boolean) => void;
40
+ toggleFrontmatter: () => void;
41
+ setHighlightedDir: (path: string | null) => void;
42
+ ensureWikilinks: () => Promise<void>;
43
+ reset: () => void;
44
+ }
45
+ export declare const useFileStore: import("zustand").UseBoundStore<import("zustand").StoreApi<FileState>>;
46
+ export declare function isInternalRepoPath(href: string | undefined): href is string;
47
+ export declare function isInternalRepoDir(href: string | undefined): href is string;
48
+ export type RepoPathKind = "file" | "dir";
49
+ export declare function classifyRepoPath(href: string | undefined): RepoPathKind | null;
50
+ /** Normalize a directory ref by trimming the trailing slash. */
51
+ export declare function normalizeDirPath(path: string): string;
52
+ export {};
53
+ //# sourceMappingURL=file-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-store.d.ts","sourceRoot":"","sources":["../../src/stores/file-store.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,SAAS,EACT,mBAAmB,EAGpB,MAAM,mCAAmC,CAAC;AAI3C,MAAM,MAAM,QAAQ,GAAG,SAAS,GAAG,KAAK,CAAC;AASzC,UAAU,SAAS;IAEjB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC;IACtC,WAAW,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC,YAAY,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAG1B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,cAAc,EAAE,mBAAmB,GAAG,IAAI,CAAC;IAC3C,cAAc,EAAE,OAAO,CAAC;IACxB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,QAAQ,EAAE,QAAQ,CAAC;IACnB,YAAY,EAAE,OAAO,CAAC;IACtB;;;OAGG;IACH,oBAAoB,EAAE,OAAO,CAAC;IAC9B;;;;OAIG;IACH,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B;;;OAGG;IACH,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC,cAAc,EAAE,OAAO,CAAC;IACxB,eAAe,EAAE,OAAO,CAAC;IAGzB,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACzC,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3C,WAAW,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,KAAK,IAAI,CAAC;IACvD,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1C,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACzC,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,WAAW,EAAE,CAAC,IAAI,EAAE,QAAQ,KAAK,IAAI,CAAC;IACtC,eAAe,EAAE,CAAC,QAAQ,EAAE,OAAO,KAAK,IAAI,CAAC;IAC7C,iBAAiB,EAAE,MAAM,IAAI,CAAC;IAC9B,iBAAiB,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IACjD,eAAe,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACrC,KAAK,EAAE,MAAM,IAAI,CAAC;CACnB;AA2CD,eAAO,MAAM,YAAY,wEA6LtB,CAAC;AAqBJ,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,IAAI,MAAM,CAI3E;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,IAAI,MAAM,CAI1E;AAED,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,KAAK,CAAC;AAE1C,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,MAAM,GAAG,SAAS,GACvB,YAAY,GAAG,IAAI,CAIrB;AAED,gEAAgE;AAChE,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAErD"}