@circuitwall/jarela 2.3.0 → 2.5.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 (290) hide show
  1. package/.next/standalone/.next/BUILD_ID +1 -1
  2. package/.next/standalone/.next/app-path-routes-manifest.json +5 -5
  3. package/.next/standalone/.next/build-manifest.json +2 -2
  4. package/.next/standalone/.next/prerender-manifest.json +4 -4
  5. package/.next/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  6. package/.next/standalone/.next/server/app/_global-error.html +1 -1
  7. package/.next/standalone/.next/server/app/_global-error.rsc +1 -1
  8. package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  9. package/.next/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  10. package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  11. package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  12. package/.next/standalone/.next/server/app/_not-found.html +14 -2
  13. package/.next/standalone/.next/server/app/_not-found.rsc +16 -4
  14. package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +16 -4
  15. package/.next/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +16 -4
  16. package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  17. package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  18. package/.next/standalone/.next/server/app/api/v1/access/[identity]/route.js +7 -0
  19. package/.next/standalone/.next/server/app/api/v1/access/route.js +7 -0
  20. package/.next/standalone/.next/server/app/api/v1/agents/[id]/compact/route.js +7 -0
  21. package/.next/standalone/.next/server/app/api/v1/agents/[id]/display-filters/route.js +17 -5
  22. package/.next/standalone/.next/server/app/api/v1/agents/[id]/route.js +7 -0
  23. package/.next/standalone/.next/server/app/api/v1/agents/[id]/thread/route.js +17 -5
  24. package/.next/standalone/.next/server/app/api/v1/agents/route.js +7 -0
  25. package/.next/standalone/.next/server/app/api/v1/allowed-sites/[hostname]/route.js +7 -0
  26. package/.next/standalone/.next/server/app/api/v1/allowed-sites/route.js +7 -0
  27. package/.next/standalone/.next/server/app/api/v1/artifacts/lifecycle/route.js +7 -0
  28. package/.next/standalone/.next/server/app/api/v1/bridges/[id]/chats/route.js +26 -32
  29. package/.next/standalone/.next/server/app/api/v1/bridges/[id]/chats/route.js.nft.json +1 -1
  30. package/.next/standalone/.next/server/app/api/v1/bridges/[id]/ignores/[remote_jid]/route.js +18 -7
  31. package/.next/standalone/.next/server/app/api/v1/bridges/[id]/ignores/route.js +18 -7
  32. package/.next/standalone/.next/server/app/api/v1/bridges/[id]/lookup/route.js +26 -32
  33. package/.next/standalone/.next/server/app/api/v1/bridges/[id]/lookup/route.js.nft.json +1 -1
  34. package/.next/standalone/.next/server/app/api/v1/bridges/[id]/pair/route.js +27 -33
  35. package/.next/standalone/.next/server/app/api/v1/bridges/[id]/pair/route.js.nft.json +1 -1
  36. package/.next/standalone/.next/server/app/api/v1/bridges/[id]/route.js +26 -32
  37. package/.next/standalone/.next/server/app/api/v1/bridges/[id]/route.js.nft.json +1 -1
  38. package/.next/standalone/.next/server/app/api/v1/bridges/[id]/routes/[route_id]/route.js +28 -12
  39. package/.next/standalone/.next/server/app/api/v1/bridges/[id]/routes/route.js +28 -12
  40. package/.next/standalone/.next/server/app/api/v1/bridges/[id]/status/route.js +26 -32
  41. package/.next/standalone/.next/server/app/api/v1/bridges/[id]/status/route.js.nft.json +1 -1
  42. package/.next/standalone/.next/server/app/api/v1/bridges/kinds/route.js +9 -2
  43. package/.next/standalone/.next/server/app/api/v1/bridges/kinds/route.js.nft.json +1 -1
  44. package/.next/standalone/.next/server/app/api/v1/bridges/route.js +19 -7
  45. package/.next/standalone/.next/server/app/api/v1/bridges/route.js.nft.json +1 -1
  46. package/.next/standalone/.next/server/app/api/v1/dashboard/metrics/route.js +17 -5
  47. package/.next/standalone/.next/server/app/api/v1/dashboard/pricing/route.js +7 -0
  48. package/.next/standalone/.next/server/app/api/v1/dashboard/pricing-task/route.js +1 -1
  49. package/.next/standalone/.next/server/app/api/v1/documents/search/route.js +7 -0
  50. package/.next/standalone/.next/server/app/api/v1/documents/settings/route.js +7 -0
  51. package/.next/standalone/.next/server/app/api/v1/documents/sources/[id]/route.js +1 -1
  52. package/.next/standalone/.next/server/app/api/v1/documents/sources/route.js +1 -1
  53. package/.next/standalone/.next/server/app/api/v1/env-sync/allowlist/route.js +7 -0
  54. package/.next/standalone/.next/server/app/api/v1/env-sync/route.js +7 -0
  55. package/.next/standalone/.next/server/app/api/v1/events/route.js +26 -32
  56. package/.next/standalone/.next/server/app/api/v1/events/route.js.nft.json +1 -1
  57. package/.next/standalone/.next/server/app/api/v1/extension/agents/route.js +1 -1
  58. package/.next/standalone/.next/server/app/api/v1/extension/browser/activate/route.js +7 -0
  59. package/.next/standalone/.next/server/app/api/v1/extension/browser/foreground/route.js +7 -0
  60. package/.next/standalone/.next/server/app/api/v1/extension/browser/history/route.js +7 -0
  61. package/.next/standalone/.next/server/app/api/v1/extension/browser/poll/route.js +7 -0
  62. package/.next/standalone/.next/server/app/api/v1/extension/browser/progress/route.js +7 -0
  63. package/.next/standalone/.next/server/app/api/v1/extension/browser/result/route.js +7 -0
  64. package/.next/standalone/.next/server/app/api/v1/extension/browser/retry/route.js +7 -0
  65. package/.next/standalone/.next/server/app/api/v1/extension/browser/status/route.js +7 -0
  66. package/.next/standalone/.next/server/app/api/v1/extension/browser/tabs/route.js +7 -0
  67. package/.next/standalone/.next/server/app/api/v1/extension/fill/route.js +1 -1
  68. package/.next/standalone/.next/server/app/api/v1/extension/refine/route.js +1 -1
  69. package/.next/standalone/.next/server/app/api/v1/extension/turn/route.js +1 -1
  70. package/.next/standalone/.next/server/app/api/v1/extensions/route.js +1 -1
  71. package/.next/standalone/.next/server/app/api/v1/extensions/tools/[name]/config/route.js +1 -1
  72. package/.next/standalone/.next/server/app/api/v1/extensions/tools/[name]/route.js +1 -1
  73. package/.next/standalone/.next/server/app/api/v1/extensions/tools/[name]/secrets/route.js +1 -1
  74. package/.next/standalone/.next/server/app/api/v1/harnesses/[id]/route.js +7 -0
  75. package/.next/standalone/.next/server/app/api/v1/harnesses/default/route.js +7 -0
  76. package/.next/standalone/.next/server/app/api/v1/harnesses/route.js +7 -0
  77. package/.next/standalone/.next/server/app/api/v1/health/route.js +17 -5
  78. package/.next/standalone/.next/server/app/api/v1/integrations/[name]/route.js +7 -0
  79. package/.next/standalone/.next/server/app/api/v1/integrations/gmail/oauth/callback/route.js +7 -0
  80. package/.next/standalone/.next/server/app/api/v1/integrations/gmail/oauth/start/route.js +7 -0
  81. package/.next/standalone/.next/server/app/api/v1/integrations/gmail/oauth/status/route.js +7 -0
  82. package/.next/standalone/.next/server/app/api/v1/integrations/outlook/oauth/callback/route.js +7 -0
  83. package/.next/standalone/.next/server/app/api/v1/integrations/outlook/oauth/start/route.js +7 -0
  84. package/.next/standalone/.next/server/app/api/v1/integrations/outlook/oauth/status/route.js +7 -0
  85. package/.next/standalone/.next/server/app/api/v1/integrations/route.js +7 -0
  86. package/.next/standalone/.next/server/app/api/v1/lifecycle/adoption/route.js +17 -5
  87. package/.next/standalone/.next/server/app/api/v1/maps/embed/route.js +7 -0
  88. package/.next/standalone/.next/server/app/api/v1/mcp-servers/[name]/route.js +17 -5
  89. package/.next/standalone/.next/server/app/api/v1/mcp-servers/route.js +17 -5
  90. package/.next/standalone/.next/server/app/api/v1/memory/[namespace]/[key]/route.js +7 -0
  91. package/.next/standalone/.next/server/app/api/v1/memory/policy/route.js +7 -0
  92. package/.next/standalone/.next/server/app/api/v1/memory/route.js +7 -0
  93. package/.next/standalone/.next/server/app/api/v1/memory/search/route.js +7 -0
  94. package/.next/standalone/.next/server/app/api/v1/models/[name]/compact-threads/route.js +7 -0
  95. package/.next/standalone/.next/server/app/api/v1/models/[name]/route.js +7 -0
  96. package/.next/standalone/.next/server/app/api/v1/models/route.js +7 -0
  97. package/.next/standalone/.next/server/app/api/v1/packages/defaults/[id]/route.js +28 -4
  98. package/.next/standalone/.next/server/app/api/v1/packages/reload/route.js +28 -4
  99. package/.next/standalone/.next/server/app/api/v1/packages/route.js +28 -4
  100. package/.next/standalone/.next/server/app/api/v1/page-capture/route.js +1 -1
  101. package/.next/standalone/.next/server/app/api/v1/pending-actions/[id]/approve/route.js +27 -12
  102. package/.next/standalone/.next/server/app/api/v1/profile/location/route.js +7 -0
  103. package/.next/standalone/.next/server/app/api/v1/profile/route.js +7 -0
  104. package/.next/standalone/.next/server/app/api/v1/providers/[provider]/models/route.js +585 -58
  105. package/.next/standalone/.next/server/app/api/v1/providers/[provider]/probe/route.js +7 -0
  106. package/.next/standalone/.next/server/app/api/v1/providers/github-copilot/auth/route.js +7 -0
  107. package/.next/standalone/.next/server/app/api/v1/providers/route.js +7 -0
  108. package/.next/standalone/.next/server/app/api/v1/proxy-config/route.js +7 -0
  109. package/.next/standalone/.next/server/app/api/v1/redaction/init/route.js +7 -0
  110. package/.next/standalone/.next/server/app/api/v1/redaction/route.js +7 -0
  111. package/.next/standalone/.next/server/app/api/v1/scheduled-tasks/[id]/route.js +17 -5
  112. package/.next/standalone/.next/server/app/api/v1/scheduled-tasks/[id]/run/route.js +1 -1
  113. package/.next/standalone/.next/server/app/api/v1/scheduled-tasks/route.js +7 -0
  114. package/.next/standalone/.next/server/app/api/v1/security/idle-timeout/route.js +7 -0
  115. package/.next/standalone/.next/server/app/api/v1/security/pin/route.js +7 -0
  116. package/.next/standalone/.next/server/app/api/v1/security/state/route.js +7 -0
  117. package/.next/standalone/.next/server/app/api/v1/security/unlock/route.js +7 -0
  118. package/.next/standalone/.next/server/app/api/v1/security/verify-pin/route.js +7 -0
  119. package/.next/standalone/.next/server/app/api/v1/skills/[id]/route.js +7 -0
  120. package/.next/standalone/.next/server/app/api/v1/skills/repos/[id]/route.js +7 -0
  121. package/.next/standalone/.next/server/app/api/v1/skills/repos/route.js +7 -0
  122. package/.next/standalone/.next/server/app/api/v1/skills/route.js +7 -0
  123. package/.next/standalone/.next/server/app/api/v1/tasks/[agent_id]/route.js +7 -0
  124. package/.next/standalone/.next/server/app/api/v1/tasks/route.js +7 -0
  125. package/.next/standalone/.next/server/app/api/v1/threads/[thread_id]/activity/route.js +7 -0
  126. package/.next/standalone/.next/server/app/api/v1/threads/[thread_id]/context-pin/route.js +12 -6
  127. package/.next/standalone/.next/server/app/api/v1/threads/[thread_id]/route.js +125 -26
  128. package/.next/standalone/.next/server/app/api/v1/threads/[thread_id]/run/route.js +1 -2
  129. package/.next/standalone/.next/server/app/api/v1/threads/route.js +17 -5
  130. package/.next/standalone/.next/server/app/api/v1/tools/route.js +1 -1
  131. package/.next/standalone/.next/server/app/api/v1/update/apply/route.js.nft.json +1 -1
  132. package/.next/standalone/.next/server/app/api/v1/voice/transcribe/route.js +17 -5
  133. package/.next/standalone/.next/server/app/api/v1/voice/tts/route.js +17 -5
  134. package/.next/standalone/.next/server/app/api/v1/watchers/[id]/route.js +17 -5
  135. package/.next/standalone/.next/server/app/api/v1/watchers/[id]/run/route.js +1 -1
  136. package/.next/standalone/.next/server/app/api/v1/watchers/route.js +1 -1
  137. package/.next/standalone/.next/server/app/page.js +27323 -27034
  138. package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  139. package/.next/standalone/.next/server/app/setup/page.js +8 -0
  140. package/.next/standalone/.next/server/app/setup/page_client-reference-manifest.js +1 -1
  141. package/.next/standalone/.next/server/app-paths-manifest.json +5 -5
  142. package/.next/standalone/.next/server/chunks/1388.js +106 -36
  143. package/.next/standalone/.next/server/chunks/2068.js +47 -10
  144. package/.next/standalone/.next/server/chunks/210.js +6 -6
  145. package/.next/standalone/.next/server/chunks/2447.js +10 -5
  146. package/.next/standalone/.next/server/chunks/2653.js +80 -1
  147. package/.next/standalone/.next/server/chunks/3042.js +10 -8
  148. package/.next/standalone/.next/server/chunks/{4540.js → 309.js} +104 -38
  149. package/.next/standalone/.next/server/chunks/{2350.js → 3272.js} +104 -37
  150. package/.next/standalone/.next/server/chunks/3524.js +150 -67
  151. package/.next/standalone/.next/server/chunks/3566.js +1 -1
  152. package/.next/standalone/.next/server/chunks/4189.js +1 -1
  153. package/.next/standalone/.next/server/chunks/4596.js +28 -4
  154. package/.next/standalone/.next/server/chunks/46.js +91 -31
  155. package/.next/standalone/.next/server/chunks/466.js +53 -7
  156. package/.next/standalone/.next/server/chunks/4955.js +30 -3
  157. package/.next/standalone/.next/server/chunks/5585.js +28 -4
  158. package/.next/standalone/.next/server/chunks/5908.js +63 -42
  159. package/.next/standalone/.next/server/chunks/6142.js +10 -2
  160. package/.next/standalone/.next/server/chunks/8461.js +10 -8
  161. package/.next/standalone/.next/server/chunks/9032.js +5 -5
  162. package/.next/standalone/.next/server/chunks/9164.js +487 -177
  163. package/.next/standalone/.next/server/chunks/9304.js +51 -12
  164. package/.next/standalone/.next/server/chunks/{423.js → 9590.js} +84 -24
  165. package/.next/standalone/.next/server/middleware-build-manifest.js +2 -2
  166. package/.next/standalone/.next/server/middleware.js +89 -21
  167. package/.next/standalone/.next/server/pages/404.html +14 -2
  168. package/.next/standalone/.next/server/pages/500.html +1 -1
  169. package/.next/standalone/.next/server/preview-props.json +3 -3
  170. package/.next/standalone/.next/server/server-reference-manifest.json +1 -1
  171. package/.next/standalone/.next/static/chunks/{1395-e4a99912b8f83044.js → 1395-bfe1f3ef760c0f50.js} +54 -8
  172. package/.next/standalone/.next/static/chunks/app/{layout-9bc0b10127cb7d42.js → layout-7b24ad13faa3944b.js} +69 -2
  173. package/.next/standalone/.next/static/chunks/app/{page-213a623b37226452.js → page-2ef8d75d40eb4311.js} +10643 -10295
  174. package/.next/standalone/.next/static/css/c160ea862133acd2.css +5 -0
  175. package/.next/standalone/docs/adoption/changesets.json +2805 -0
  176. package/.next/standalone/package.json +1 -1
  177. package/CHANGELOG.md +52 -0
  178. package/api/client.models.test.ts +10 -0
  179. package/api/client.startup.test.ts +129 -0
  180. package/api/client.ts +51 -9
  181. package/api/thread-metadata.test.ts +72 -0
  182. package/api/types.ts +6 -3
  183. package/app/api/v1/providers/[provider]/models/route.test.ts +216 -6
  184. package/app/api/v1/providers/[provider]/models/route.ts +259 -40
  185. package/app/api/v1/threads/[thread_id]/route.ts +26 -23
  186. package/app/api/v1/threads/[thread_id]/run/route.ts +0 -1
  187. package/app/globals.css +119 -29
  188. package/app/layout.tsx +12 -0
  189. package/components/agents/AgentsPanel.tsx +5 -13
  190. package/components/chat/ChatView.tsx +9 -18
  191. package/components/chat/InputBar.tsx +1 -1
  192. package/components/chat/MessageBubble.tsx +13 -1
  193. package/components/chat/MessageList.test.tsx +45 -4
  194. package/components/chat/MessageList.tsx +123 -89
  195. package/components/chat/ToolList.tsx +88 -84
  196. package/components/chat/useThreadActivity.test.tsx +2 -2
  197. package/components/chat/useThreadActivity.ts +2 -2
  198. package/components/chat/useThreadData.ts +1 -30
  199. package/components/chat/useThreadMetadataPolling.test.tsx +128 -0
  200. package/components/chat/useThreadMetadataPolling.ts +50 -0
  201. package/components/chat/useUserProfileAndAgent.test.tsx +31 -0
  202. package/components/chat/useUserProfileAndAgent.ts +13 -2
  203. package/components/dashboard/DashboardPanel.tsx +1 -1
  204. package/components/dashboard/Series.tsx +34 -21
  205. package/components/dashboard/SummaryCards.tsx +1 -1
  206. package/components/integrations/NetworkSection.tsx +2 -2
  207. package/components/layout/AppShell.tsx +22 -7
  208. package/components/layout/MenuPanel.tsx +14 -24
  209. package/components/profile/ProfilePanel.tsx +2 -2
  210. package/components/settings/AppearancePanel.tsx +70 -3
  211. package/components/settings/SettingsPanel.tsx +2 -2
  212. package/components/tools/ToolsPanel.tsx +2 -7
  213. package/components/ui/AppearancePreferences.test.tsx +68 -0
  214. package/components/ui/BootScreen.test.tsx +44 -0
  215. package/components/ui/BootScreen.tsx +24 -11
  216. package/components/ui/NotificationStatus.test.tsx +2 -2
  217. package/components/ui/NotificationStatus.tsx +5 -5
  218. package/components/ui/SubTabBar.tsx +2 -3
  219. package/contexts/ThemeContext.tsx +84 -1
  220. package/hooks/useAgentSession.test.ts +12 -1
  221. package/hooks/useAgentSession.ts +6 -4
  222. package/hooks/useUrlSync.test.ts +13 -0
  223. package/hooks/useUrlSync.ts +0 -4
  224. package/lib/agents/citation-checker.test.ts +40 -2
  225. package/lib/agents/citation-checker.ts +56 -11
  226. package/lib/agents/context-boundary.ts +5 -6
  227. package/lib/agents/instruction-edits.test.ts +120 -0
  228. package/lib/agents/instruction-edits.ts +65 -42
  229. package/lib/agents/prepare/request.ts +0 -2
  230. package/lib/agents/prepare/system-prompt.test.ts +10 -0
  231. package/lib/agents/prepare/system-prompt.ts +8 -2
  232. package/lib/agents/proposals.test.ts +76 -0
  233. package/lib/agents/proposals.ts +13 -5
  234. package/lib/agents/run-thread.auto-boundary.test.ts +125 -5
  235. package/lib/agents/run-thread.ts +24 -9
  236. package/lib/agents/sqlite-checkpoint-saver.test.ts +91 -0
  237. package/lib/agents/warm-summary-background.ts +22 -2
  238. package/lib/agents/warm-topics.test.ts +155 -1
  239. package/lib/agents/warm-topics.ts +27 -7
  240. package/lib/bridges/dispatcher.ts +1 -0
  241. package/lib/bridges/message-role.test.ts +81 -0
  242. package/lib/bridges/message-role.ts +23 -10
  243. package/lib/bridges/types.ts +6 -0
  244. package/lib/bridges/whatsapp-link.test.ts +32 -0
  245. package/lib/bridges/whatsapp-link.ts +21 -0
  246. package/lib/bridges/whatsapp.inbound.test.ts +239 -0
  247. package/lib/bridges/whatsapp.sender.test.ts +80 -1
  248. package/lib/bridges/whatsapp.ts +76 -38
  249. package/lib/db/migrations.test.ts +61 -0
  250. package/lib/db/migrations.ts +13 -0
  251. package/lib/embeddings/performance.test.ts +114 -0
  252. package/lib/pricing/snapshot.test.ts +70 -0
  253. package/lib/pricing/snapshot.ts +10 -2
  254. package/lib/proxy/dispatcher.test.ts +119 -1
  255. package/lib/proxy/dispatcher.ts +22 -9
  256. package/lib/stores/agent-configs.ts +10 -5
  257. package/lib/stores/bridges.test.ts +81 -0
  258. package/lib/stores/bridges.ts +9 -8
  259. package/lib/stores/dashboard-metrics-cache.test.ts +99 -0
  260. package/lib/stores/dashboard-metrics.ts +30 -4
  261. package/lib/stores/message-embedding-jobs.test.ts +27 -0
  262. package/lib/stores/message-embedding-jobs.ts +5 -3
  263. package/lib/stores/message-usage.test.ts +21 -1
  264. package/lib/stores/pricing-cache.test.ts +31 -0
  265. package/lib/stores/pricing.ts +3 -0
  266. package/lib/stores/proxy-config.test.ts +120 -0
  267. package/lib/stores/proxy-config.ts +22 -4
  268. package/lib/stores/threads.ts +12 -8
  269. package/lib/tools/communications/calendar.test.ts +43 -2
  270. package/lib/tools/communications/calendar.ts +2 -0
  271. package/lib/tools/communications/gmail.test.ts +51 -1
  272. package/lib/tools/communications/gmail.ts +44 -2
  273. package/lib/tools/communications/outlook-calendar.ts +2 -0
  274. package/lib/tools/communications/outlook.test.ts +33 -2
  275. package/lib/tools/communications/outlook.ts +2 -0
  276. package/lib/tools/filesystem/edit-match.test.ts +133 -0
  277. package/lib/tools/filesystem/edit-match.ts +7 -2
  278. package/lib/tools/packages/default-packages.test.ts +21 -0
  279. package/lib/tools/packages/optional-package.test.ts +72 -0
  280. package/lib/tools/packages/optional-package.ts +33 -4
  281. package/lib/tools/support/result-refs.test.ts +131 -0
  282. package/lib/tools/support/result-refs.ts +41 -9
  283. package/lib/ui/navigate.test.ts +13 -0
  284. package/lib/ui/navigate.ts +10 -2
  285. package/lib/utils/source-link.test.ts +51 -0
  286. package/lib/utils/source-link.ts +45 -0
  287. package/package.json +1 -1
  288. package/.next/standalone/.next/static/css/312542a5725ba0d5.css +0 -5
  289. /package/.next/standalone/.next/static/{bMRK5y3ruT7c3WtBfCQOG → 544OFJV-q0RC6Gjgje4LT}/_buildManifest.js +0 -0
  290. /package/.next/standalone/.next/static/{bMRK5y3ruT7c3WtBfCQOG → 544OFJV-q0RC6Gjgje4LT}/_ssgManifest.js +0 -0
@@ -1,4 +1,4 @@
1
- <!DOCTYPE html><html lang="en" data-theme="system"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, viewport-fit=cover, interactive-widget=resizes-content"/><link rel="stylesheet" href="/_next/static/css/312542a5725ba0d5.css" data-precedence="next"/><link rel="preload" as="script" fetchPriority="low" href="/_next/static/chunks/webpack-22f2423f357dd0a1.js"/><script src="/_next/static/chunks/4bd1b696-c054103efb2e5332.js" async=""></script><script src="/_next/static/chunks/5254-bcfacd19ebb8dcce.js" async=""></script><script src="/_next/static/chunks/main-app-395c0576f1cde35e.js" async=""></script><script src="/_next/static/chunks/app/layout-9bc0b10127cb7d42.js" async=""></script><meta name="robots" content="noindex"/><meta name="theme-color" content="#ffffff" media="(prefers-color-scheme: light)"/><meta name="theme-color" content="#09090b" media="(prefers-color-scheme: dark)"/><title>Jarela</title><meta name="description" content="Jarela — local chat interface for LangGraph agents"/><link rel="manifest" href="/manifest.webmanifest"/><meta name="mobile-web-app-capable" content="yes"/><meta name="apple-mobile-web-app-title" content="Jarela"/><meta name="apple-mobile-web-app-status-bar-style" content="black-translucent"/><link rel="icon" href="/favicon.svg" type="image/svg+xml"/><link rel="icon" href="/favicon.ico" sizes="any"/><link rel="icon" href="/icon-192.png" type="image/png" sizes="192x192"/><link rel="icon" href="/icon-512.png" type="image/png" sizes="512x512"/><link rel="apple-touch-icon" href="/apple-touch-icon.png" sizes="180x180"/><title>404: This page could not be found.</title><script>(() => {
1
+ <!DOCTYPE html><html lang="en" data-theme="system"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, viewport-fit=cover, interactive-widget=resizes-content"/><link rel="stylesheet" href="/_next/static/css/c160ea862133acd2.css" data-precedence="next"/><link rel="preload" as="script" fetchPriority="low" href="/_next/static/chunks/webpack-22f2423f357dd0a1.js"/><script src="/_next/static/chunks/4bd1b696-c054103efb2e5332.js" async=""></script><script src="/_next/static/chunks/5254-bcfacd19ebb8dcce.js" async=""></script><script src="/_next/static/chunks/main-app-395c0576f1cde35e.js" async=""></script><script src="/_next/static/chunks/app/layout-7b24ad13faa3944b.js" async=""></script><meta name="robots" content="noindex"/><meta name="theme-color" content="#ffffff" media="(prefers-color-scheme: light)"/><meta name="theme-color" content="#09090b" media="(prefers-color-scheme: dark)"/><title>Jarela</title><meta name="description" content="Jarela — local chat interface for LangGraph agents"/><link rel="manifest" href="/manifest.webmanifest"/><meta name="mobile-web-app-capable" content="yes"/><meta name="apple-mobile-web-app-title" content="Jarela"/><meta name="apple-mobile-web-app-status-bar-style" content="black-translucent"/><link rel="icon" href="/favicon.svg" type="image/svg+xml"/><link rel="icon" href="/favicon.ico" sizes="any"/><link rel="icon" href="/icon-192.png" type="image/png" sizes="192x192"/><link rel="icon" href="/icon-512.png" type="image/png" sizes="512x512"/><link rel="apple-touch-icon" href="/apple-touch-icon.png" sizes="180x180"/><title>404: This page could not be found.</title><script>(() => {
2
2
  var LIGHT = "#ffffff", DARK = "#09090b";
3
3
  function resolve(t) {
4
4
  if (t === "light") return LIGHT;
@@ -11,6 +11,18 @@
11
11
  var t = localStorage.getItem("jarela-theme");
12
12
  if (t !== "light" && t !== "dark" && t !== "system") t = "system";
13
13
  document.documentElement.setAttribute("data-theme", t);
14
+ var accent = localStorage.getItem("jarela-accent-color");
15
+ if (["blue", "teal", "violet", "rose"].includes(accent)) {
16
+ document.documentElement.setAttribute("data-accent-color", accent);
17
+ } else {
18
+ document.documentElement.removeAttribute("data-accent-color");
19
+ }
20
+ var surface = localStorage.getItem("jarela-surface-style");
21
+ if (surface === "calm" || surface === "ambient" || surface === "liquid") {
22
+ document.documentElement.setAttribute("data-surface-style", surface);
23
+ } else {
24
+ document.documentElement.removeAttribute("data-surface-style");
25
+ }
14
26
  // Collapse any media-scoped theme-color metas Next emits to a single tag
15
27
  // so the PWA window chrome matches the user's explicit choice (not just
16
28
  // prefers-color-scheme). ThemeContext keeps this in sync on change.
@@ -110,4 +122,4 @@
110
122
  if (!document.hidden) { setTimeout(apply, 50); setTimeout(apply, 200); }
111
123
  });
112
124
  } catch (e) { /* non-fatal: falls back to 100dvh */ }
113
- })();</script><script src="/_next/static/chunks/polyfills-42372ed130431b0a.js" noModule=""></script></head><body><div hidden=""><!--$--><!--/$--></div><div style="font-family:system-ui,&quot;Segoe UI&quot;,Roboto,Helvetica,Arial,sans-serif,&quot;Apple Color Emoji&quot;,&quot;Segoe UI Emoji&quot;;height:100vh;text-align:center;display:flex;flex-direction:column;align-items:center;justify-content:center"><div><style>body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}</style><h1 class="next-error-h1" style="display:inline-block;margin:0 20px 0 0;padding:0 23px 0 0;font-size:24px;font-weight:500;vertical-align:top;line-height:49px">404</h1><div style="display:inline-block"><h2 style="font-size:14px;font-weight:400;line-height:49px;margin:0">This page could not be found.</h2></div></div></div><!--$--><!--/$--><script src="/_next/static/chunks/webpack-22f2423f357dd0a1.js" id="_R_" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0])</script><script>self.__next_f.push([1,"1:\"$Sreact.fragment\"\nb:I[27123,[],\"default\",1]\n:HL[\"/_next/static/css/312542a5725ba0d5.css\",\"style\"]\n2:T4b9,(() =\u003e {\n var LIGHT = \"#ffffff\", DARK = \"#09090b\";\n function resolve(t) {\n if (t === \"light\") return LIGHT;\n if (t === \"dark\") return DARK;\n try {\n return window.matchMedia(\"(prefers-color-scheme: dark)\").matches ? DARK : LIGHT;\n } catch (e) { return DARK; }\n }\n try {\n var t = localStorage.getItem(\"jarela-theme\");\n if (t !== \"light\" \u0026\u0026 t !== \"dark\" \u0026\u0026 t !== \"system\") t = \"system\";\n document.documentElement.setAttribute(\"data-theme\", t);\n // Collapse any media-scoped theme-color metas Next emits to a single tag\n // so the PWA window chrome matches the user's explicit choice (not just\n // prefers-color-scheme). ThemeContext keeps this in sync on change.\n var metas = document.querySelectorAll('meta[name=\"theme-color\"]');\n for (var i = 1; i \u003c metas.length; i++) metas[i].parentNode.removeChild(metas[i]);\n var meta = metas[0];\n if (!meta) {\n meta = document.createElement(\"meta\");\n meta.setAttribute(\"name\", \"theme-color\");\n document.head.appendChild(meta);\n }\n meta.removeAttribute(\"media\");\n meta.setAttribute(\"content\", resolve(t));\n } catch (e) {\n document.documentElement.setAttribute(\"data-theme\", \"system\");\n }\n})();3:Tf06,(() =\u003e {\n try {\n var isPWA = window.matchMedia('(display-mode: standalone)').matches\n || window.matchMedia('(display-mode: fullscreen)').matches\n || window.navigator.standalone === true;\n if (!isPWA) return;\n var last = 0;\n function safeTopPx() {\n var v = getComputedStyle(document.documentElement).getPropertyValue('--app-safe-top') || '';\n var n = parseFloat(v);\n return isNaN(n) ? 0 : n;\n }\n function isEditableFocused() {\n var ae = document.activeElement;\n if (!ae) return false;\n var tag = ae.tagName;\n return tag === 'INPUT' || tag === 'TEXTAREA' || ae.isContentEditable === true;\n }\n function apply() {\n var vv = window.visualViewport;\n var vh = (vv \u0026\u0026 vv.height) || window.innerHeight;\n // Keyboard-open detection: when iOS shows the on-screen keyboard,\n // visualViewport.height shrinks but window.innerHeight stays put.\n // Pairing that gap with editable-focus makes it model-agnostic -\n // no need to guess a keyboard height per device (SE ~216, 15 Pro\n // Max ~301, iPad floating ~120). 50px just filters URL-bar jitter.\n var keyboardOpen = isEditableFocused() \u0026\u0026 (window.innerHeight - vh) \u003e 50;\n var isPortrait = window.innerHeight \u003e window.innerWidth;\n // Skip the chin correction while the keyboard is up - otherwise we\n // inflate --actual-vh beyond the visible viewport and the input bar\n // ends up underneath the keyboard.\n if (!keyboardOpen \u0026\u0026 isPortrait) {\n var screenH = Math.max(window.screen.height, window.screen.width);\n if (screenH - vh \u003e 15) {\n var top = safeTopPx();\n if (top \u003e 0) vh += top;\n }\n }\n document.documentElement.style.setProperty('--actual-vh', vh + 'px');\n if (last \u003e 0 \u0026\u0026 Math.abs(vh - last) \u003e 30) {\n setTimeout(function () { window.dispatchEvent(new Event('resize')); }, 50);\n }\n last = vh;\n }\n apply();\n [50, 150, 300, 500, 800, 1200].forEach(function (ms) { setTimeout(apply, ms); });\n window.addEventListener('resize', apply);\n window.addEventListener('orientationchange', function () {\n setTimeout(apply, 100); setTimeout(apply, 300);\n });\n if (window.visualViewport) {\n window.visualViewport.addEventListener('resize', apply);\n window.visualViewport.addEventListener('scroll', apply);\n }\n // focusin/focusout can lead visualViewport.resize by ~100ms on\n // older iOS - recompute immediately so we don't render a bad frame.\n document.addEventListener('focusin', apply, true);\n document.addEventListener('focusout', apply, true);\n // iOS still scrolls the layout viewport up when the keyboard opens\n // to keep the focused input visible, even with html/body overflow:hidden.\n // Aggressive scroll-reset on focus events counteracts it (piclaw PWA.md\n // pattern, validated on iOS 26.x). Staggered timers cover the lag\n // between focus and iOS's scroll-into-view.\n function snapScroll() {\n if (window.scrollY !== 0 || window.pageYOffset !== 0) {\n window.scrollTo(0, 0);\n }\n }\n document.addEventListener('focusin', function () {\n snapScroll();\n [16, 50, 100, 200, 400].forEach(function (ms) { setTimeout(snapScroll, ms); });\n }, true);\n document.addEventListener('focusout', function () {\n [16, 50, 100, 200].forEach(function (ms) { setTimeout(snapScroll, ms); });\n }, true);\n if (window.visualViewport) {\n window.visualViewport.addEventListener('scroll', snapScroll);\n }\n window.addEventListener('scroll', snapScroll, { passive: true });\n document.addEventListener('visibilitychange', function () {\n if (!document.hidden) { setTimeout(apply, 50); setTimeout(apply, 200); }\n });\n } catch (e) { /* non-fatal: falls back to 100dvh */ }\n})();7:X\n8:[[\"children\",{\"s\":\"__PAGE__\",\"h\":512,\"d\":{\"r\":\"$L9\",\"p\":false,\"v\":null}}]]\n5:[[\"children\",{\"s\":\"_not-found\",\"h\":512,\"d\":{\"r\":\"$L6\",\"p\":false,\"v\":\"$7\"},\"c\":\"$Q8\"}]]\n0:{\"P\":null,\"c\":[\"\",\"_not-found\"],\"q\":\"\",\"i\":false,\"t\":{\"t\":{\"s\":\"\",\"h\":528,\"d\":{\"r\":[\"$\",\"$1\",\"c\",{\"children\":[[[\"$\",\"link\",\"0\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/css/312542a5725ba0d5.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\",\"nonce\":\"$undefined\"}]],[\"$\",\"html\",null,{\"lang\":\"en\",\"data-theme\":\"system\",\"suppressHydrationWarning\":true,\"children\":[[\"$\",\"head\",null,{\"children\":[[\"$\",\"script\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"$2\"}}],[\"$\",\"script\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"$3\"}}],null]}],\"$L4\"]}]]}],\"p\":false,\"v\":null},\"c\":\"$Q5\"},\"h\":{\"r\":\"$La\",\"p\":false,\"v\":null}},\"m\":\"$undefined\",\"G\":[\"$b\",[]],\"S\":true,\"r\":\"$undefined\",\"s\":\"$undefined\",\"a\":\"$undefined\",\"l\":\"$undefined\",\"p\":\"$undefined\",\"d\":\"$undefined\",\"b\":\"bMRK5y3ruT7c3WtBfCQOG\"}\nc:\"static/chunks/app/layout-9bc0b10127cb7d42.js\"\nd:I[30737,[\"7177\",\"$c\"],\"ThemeProvider\"]\ne:I[43639,[\"7177\",\"$c\"],\"AppProvider\"]\nf:I[57121,[],\"\"]\n10:I[74581,[],\"\"]\n11:I[94204,[\"7177\",\"$c\"],\"ConfirmHost\"]\n12:\"ServiceWorkerRegistration\"\n13:I[20722,[\"7177\",\"$c\"],\"$12\"]\n14:I[90484,[],\"OutletBoundary\"]\n15:\"$Sreact.suspense\"\n17:\"ViewportBoundary\"\n18:I[90484,[],\"$17\"]\n1a:\"MetadataBoundary\"\n1b:I[90484,[],\"$1a\"]\n4:[\"$\",\"body\",null,{\"children\":[[\"$\",\"$Ld\",null,{\"children\":[[\"$\",\"$Le\",null,{\"children\":[\"$\",\"$Lf\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L10\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]}],[\"$\",\"$L11\",null,{}]]}],[\"$\",\"$L13\",null,{}]]}]\n6:[\"$\",\"$1\",\"c\",{\"children\":[null,[\"$\",\"$Lf\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L10\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]]}]\n9:[\"$\",\"$1\",\"c\",{\"children\":[[[\"$\",\"title\",null,{\"children\":\"404: This page could not be found.\"}],[\"$\",\"div\",null,{\"style\":{\"fontFamily\":\"system-ui,\\\"Segoe UI\\\",Roboto,Helvetica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\"\",\"height\":\"100vh\",\"textAlign\":\"center\",\"display\":\"flex\",\"flexDirection\":\"column\",\"alignItems\":\"center\",\"justifyContent\":\"center\"},\"children\":[\"$\",\"div\",null,{\"children\":[[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}\"}}],[\"$\",\"h1\",null,{\"className\":\"next-error-h1\",\"style\":{\"display\":\"inline-block\",\"margin\":\"0 20px 0 0\",\"padding\":\"0 23px 0 0\",\"fontSize\":24,\"fontWeight\":500,\"verticalAlign\":\"top\",\"lineHeight\":\"49px\"},\"children\":404}],[\"$\",\"div\",null,{\"style\":{\"display\":\"inline-block\"},\"children\":[\"$\",\"h2\",null,{\"style\":{\"fontSize\":14,\"fontWeight\":400,\"lineHeight\":\"49px\",\"margin\":0},\"children\":\"This page could not be found.\"}]}]]}]}]],null,[\"$\",\"$L14\",null,{\"children\":[\"$\",\"$15\",null,{\"name\":\"Next.MetadataOutlet\",\"children\":\"$@16\"}]}]]}]\na:[\"$\",\"$1\",\"h\",{\"children\":[[\"$\",\"meta\",null,{\"name\":\"robots\",\"content\":\"noindex\"}],[\"$\",\"$L18\",null,{\"children\":\"$L19\"}],[\"$\",\"$L1b\",null,{\"children\":[[\"$\",\"div\",null,{\"hidden\":true,\"children\":[\"$\",\"$15\",null,{\"name\":\"Next.Metadata\",\"children\":\"$L1c\"}]}],null]}],null]}]\n7:C\n19:[[\"$\",\"meta\",\"0\",{\"charSet\":\"utf-8\"}],[\"$\",\"meta\",\"1\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1, maximum-scale=1, viewport-fit=cover, interactive-widget=resizes-content\"}],[\"$\",\"meta\",\"2\",{\"name\":\"theme-color\",\"content\":\"#ffffff\",\"media\":\"(prefers-color-scheme: light)\"}],[\"$\",\"meta\",\"3\",{\"name\":\"theme-color\",\"content\":\"#09090b\",\"media\":\"(prefers-color-scheme: dark)\"}]]\n1d:I[86869,[],\"IconMark\"]\n16:null\n1c:[[\"$\",\"title\",\"0\",{\"children\":\"Jarela\"}],[\"$\",\"meta\",\"1\",{\"name\":\"description\",\"content\":\"Jarela — local chat interface for LangGraph agents\"}],[\"$\",\"link\",\"2\",{\"rel\":\"manifest\",\"href\":\"/manifest.webmanifest\",\"crossOrigin\":\"$undefined\"}],[\"$\",\"meta\",\"3\",{\"name\":\"mobile-web-app-capable\",\"content\":\"yes\"}],[\"$\",\"meta\",\"4\",{\"name\":\"apple-mobile-web-app-title\",\"content\":\"Jarela\"}],[\"$\",\"meta\",\"5\",{\"name\":\"apple-mobile-web-app-status-bar-style\",\"content\":\"black-translucent\"}],[\"$\",\"link\",\"6\",{\"rel\":\"icon\",\"href\":\"/favicon.svg\",\"type\":\"image/svg+xml\"}],[\"$\",\"link\",\"7\",{\"rel\":\"icon\",\"href\":\"/favicon.ico\",\"sizes\":\"any\"}],[\"$\",\"link\",\"8\",{\"rel\":\"icon\",\"href\":\"/icon-192.png\",\"type\":\"image/png\",\"sizes\":\"192x192\"}],[\"$\",\"link\",\"9\",{\"rel\":\"icon\",\"href\":\"/icon-512.png\",\"type\":\"image/png\",\"sizes\":\"512x512\"}],[\"$\",\"link\",\"10\",{\"rel\":\"apple-touch-icon\",\"href\":\"/apple-touch-icon.png\",\"sizes\":\"180x180\"}],[\"$\",\"$L1d\",\"11\",{}]]\n"])</script></body></html>
125
+ })();</script><script src="/_next/static/chunks/polyfills-42372ed130431b0a.js" noModule=""></script></head><body><div hidden=""><!--$--><!--/$--></div><div style="font-family:system-ui,&quot;Segoe UI&quot;,Roboto,Helvetica,Arial,sans-serif,&quot;Apple Color Emoji&quot;,&quot;Segoe UI Emoji&quot;;height:100vh;text-align:center;display:flex;flex-direction:column;align-items:center;justify-content:center"><div><style>body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}</style><h1 class="next-error-h1" style="display:inline-block;margin:0 20px 0 0;padding:0 23px 0 0;font-size:24px;font-weight:500;vertical-align:top;line-height:49px">404</h1><div style="display:inline-block"><h2 style="font-size:14px;font-weight:400;line-height:49px;margin:0">This page could not be found.</h2></div></div></div><!--$--><!--/$--><script src="/_next/static/chunks/webpack-22f2423f357dd0a1.js" id="_R_" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0])</script><script>self.__next_f.push([1,"1:\"$Sreact.fragment\"\nb:I[27123,[],\"default\",1]\n:HL[\"/_next/static/css/c160ea862133acd2.css\",\"style\"]\n2:T70c,(() =\u003e {\n var LIGHT = \"#ffffff\", DARK = \"#09090b\";\n function resolve(t) {\n if (t === \"light\") return LIGHT;\n if (t === \"dark\") return DARK;\n try {\n return window.matchMedia(\"(prefers-color-scheme: dark)\").matches ? DARK : LIGHT;\n } catch (e) { return DARK; }\n }\n try {\n var t = localStorage.getItem(\"jarela-theme\");\n if (t !== \"light\" \u0026\u0026 t !== \"dark\" \u0026\u0026 t !== \"system\") t = \"system\";\n document.documentElement.setAttribute(\"data-theme\", t);\n var accent = localStorage.getItem(\"jarela-accent-color\");\n if ([\"blue\", \"teal\", \"violet\", \"rose\"].includes(accent)) {\n document.documentElement.setAttribute(\"data-accent-color\", accent);\n } else {\n document.documentElement.removeAttribute(\"data-accent-color\");\n }\n var surface = localStorage.getItem(\"jarela-surface-style\");\n if (surface === \"calm\" || surface === \"ambient\" || surface === \"liquid\") {\n document.documentElement.setAttribute(\"data-surface-style\", surface);\n } else {\n document.documentElement.removeAttribute(\"data-surface-style\");\n }\n // Collapse any media-scoped theme-color metas Next emits to a single tag\n // so the PWA window chrome matches the user's explicit choice (not just\n // prefers-color-scheme). ThemeContext keeps this in sync on change.\n var metas = document.querySelectorAll('meta[name=\"theme-color\"]');\n for (var i = 1; i \u003c metas.length; i++) metas[i].parentNode.removeChild(metas[i]);\n var meta = metas[0];\n if (!meta) {\n meta = document.createElement(\"meta\");\n meta.setAttribute(\"name\", \"theme-color\");\n document.head.appendChild(meta);\n }\n meta.removeAttribute(\"media\");\n meta.setAttribute(\"content\", resolve(t));\n } catch (e) {\n document.documentElement.setAttribute(\"data-theme\", \"system\");\n }\n})();3:Tf06,(() =\u003e {\n try {\n var isPWA = window.matchMedia('(display-mode: standalone)').matches\n || window.matchMedia('(display-mode: fullscreen)').matches\n || window.navigator.standalone === true;\n if (!isPWA) return;\n var last = 0;\n function safeTopPx() {\n var v = getComputedStyle(document.documentElement).getPropertyValue('--app-safe-top') || '';\n var n = parseFloat(v);\n return isNaN(n) ? 0 : n;\n }\n function isEditableFocused() {\n var ae = document.activeElement;\n if (!ae) return false;\n var tag = ae.tagName;\n return tag === 'INPUT' || tag === 'TEXTAREA' || ae.isContentEditable === true;\n }\n function apply() {\n var vv = window.visualViewport;\n var vh = (vv \u0026\u0026 vv.height) || window.innerHeight;\n // Keyboard-open detection: when iOS shows the on-screen keyboard,\n // visualViewport.height shrinks but window.innerHeight stays put.\n // Pairing that gap with editable-focus makes it model-agnostic -\n // no need to guess a keyboard height per device (SE ~216, 15 Pro\n // Max ~301, iPad floating ~120). 50px just filters URL-bar jitter.\n var keyboardOpen = isEditableFocused() \u0026\u0026 (window.innerHeight - vh) \u003e 50;\n var isPortrait = window.innerHeight \u003e window.innerWidth;\n // Skip the chin correction while the keyboard is up - otherwise we\n // inflate --actual-vh beyond the visible viewport and the input bar\n // ends up underneath the keyboard.\n if (!keyboardOpen \u0026\u0026 isPortrait) {\n var screenH = Math.max(window.screen.height, window.screen.width);\n if (screenH - vh \u003e 15) {\n var top = safeTopPx();\n if (top \u003e 0) vh += top;\n }\n }\n document.documentElement.style.setProperty('--actual-vh', vh + 'px');\n if (last \u003e 0 \u0026\u0026 Math.abs(vh - last) \u003e 30) {\n setTimeout(function () { window.dispatchEvent(new Event('resize')); }, 50);\n }\n last = vh;\n }\n apply();\n [50, 150, 300, 500, 800, 1200].forEach(function (ms) { setTimeout(apply, ms); });\n window.addEventListener('resize', apply);\n window.addEventListener('orientationchange', function () {\n setTimeout(apply, 100); setTimeout(apply, 300);\n });\n if (window.visualViewport) {\n window.visualViewport.addEventListener('resize', apply);\n window.visualViewport.addEventListener('scroll', apply);\n }\n // focusin/focusout can lead visualViewport.resize by ~100ms on\n // older iOS - recompute immediately so we don't render a bad frame.\n document.addEventListener('focusin', apply, true);\n document.addEventListener('focusout', apply, true);\n // iOS still scrolls the layout viewport up when the keyboard opens\n // to keep the focused input visible, even with html/body overflow:hidden.\n // Aggressive scroll-reset on focus events counteracts it (piclaw PWA.md\n // pattern, validated on iOS 26.x). Staggered timers cover the lag\n // between focus and iOS's scroll-into-view.\n function snapScroll() {\n if (window.scrollY !== 0 || window.pageYOffset !== 0) {\n window.scrollTo(0, 0);\n }\n }\n document.addEventListener('focusin', function () {\n snapScroll();\n [16, 50, 100, 200, 400].forEach(function (ms) { setTimeout(snapScroll, ms); });\n }, true);\n document.addEventListener('focusout', function () {\n [16, 50, 100, 200].forEach(function (ms) { setTimeout(snapScroll, ms); });\n }, true);\n if (window.visualViewport) {\n window.visualViewport.addEventListener('scroll', snapScroll);\n }\n window.addEventListener('scroll', snapScroll, { passive: true });\n document.addEventListener('visibilitychange', function () {\n if (!document.hidden) { setTimeout(apply, 50); setTimeout(apply, 200); }\n });\n } catch (e) { /* non-fatal: falls back to 100dvh */ }\n})();7:X\n8:[[\"children\",{\"s\":\"__PAGE__\",\"h\":512,\"d\":{\"r\":\"$L9\",\"p\":false,\"v\":null}}]]\n5:[[\"children\",{\"s\":\"_not-found\",\"h\":512,\"d\":{\"r\":\"$L6\",\"p\":false,\"v\":\"$7\"},\"c\":\"$Q8\"}]]\n0:{\"P\":null,\"c\":[\"\",\"_not-found\"],\"q\":\"\",\"i\":false,\"t\":{\"t\":{\"s\":\"\",\"h\":528,\"d\":{\"r\":[\"$\",\"$1\",\"c\",{\"children\":[[[\"$\",\"link\",\"0\",{\"rel\":\"stylesheet\",\"href\":\"/_next/static/css/c160ea862133acd2.css\",\"precedence\":\"next\",\"crossOrigin\":\"$undefined\",\"nonce\":\"$undefined\"}]],[\"$\",\"html\",null,{\"lang\":\"en\",\"data-theme\":\"system\",\"suppressHydrationWarning\":true,\"children\":[[\"$\",\"head\",null,{\"children\":[[\"$\",\"script\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"$2\"}}],[\"$\",\"script\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"$3\"}}],null]}],\"$L4\"]}]]}],\"p\":false,\"v\":null},\"c\":\"$Q5\"},\"h\":{\"r\":\"$La\",\"p\":false,\"v\":null}},\"m\":\"$undefined\",\"G\":[\"$b\",[]],\"S\":true,\"r\":\"$undefined\",\"s\":\"$undefined\",\"a\":\"$undefined\",\"l\":\"$undefined\",\"p\":\"$undefined\",\"d\":\"$undefined\",\"b\":\"544OFJV-q0RC6Gjgje4LT\"}\nc:\"static/chunks/app/layout-7b24ad13faa3944b.js\"\nd:I[30737,[\"7177\",\"$c\"],\"ThemeProvider\"]\ne:I[43639,[\"7177\",\"$c\"],\"AppProvider\"]\nf:I[57121,[],\"\"]\n10:I[74581,[],\"\"]\n11:I[94204,[\"7177\",\"$c\"],\"ConfirmHost\"]\n12:\"ServiceWorkerRegistration\"\n13:I[20722,[\"7177\",\"$c\"],\"$12\"]\n14:I[90484,[],\"OutletBoundary\"]\n15:\"$Sreact.suspense\"\n17:\"ViewportBoundary\"\n18:I[90484,[],\"$17\"]\n1a:\"MetadataBoundary\"\n1b:I[90484,[],\"$1a\"]\n4:[\"$\",\"body\",null,{\"children\":[[\"$\",\"$Ld\",null,{\"children\":[[\"$\",\"$Le\",null,{\"children\":[\"$\",\"$Lf\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L10\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]}],[\"$\",\"$L11\",null,{}]]}],[\"$\",\"$L13\",null,{}]]}]\n6:[\"$\",\"$1\",\"c\",{\"children\":[null,[\"$\",\"$Lf\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L10\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]]}]\n9:[\"$\",\"$1\",\"c\",{\"children\":[[[\"$\",\"title\",null,{\"children\":\"404: This page could not be found.\"}],[\"$\",\"div\",null,{\"style\":{\"fontFamily\":\"system-ui,\\\"Segoe UI\\\",Roboto,Helvetica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\"\",\"height\":\"100vh\",\"textAlign\":\"center\",\"display\":\"flex\",\"flexDirection\":\"column\",\"alignItems\":\"center\",\"justifyContent\":\"center\"},\"children\":[\"$\",\"div\",null,{\"children\":[[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}\"}}],[\"$\",\"h1\",null,{\"className\":\"next-error-h1\",\"style\":{\"display\":\"inline-block\",\"margin\":\"0 20px 0 0\",\"padding\":\"0 23px 0 0\",\"fontSize\":24,\"fontWeight\":500,\"verticalAlign\":\"top\",\"lineHeight\":\"49px\"},\"children\":404}],[\"$\",\"div\",null,{\"style\":{\"display\":\"inline-block\"},\"children\":[\"$\",\"h2\",null,{\"style\":{\"fontSize\":14,\"fontWeight\":400,\"lineHeight\":\"49px\",\"margin\":0},\"children\":\"This page could not be found.\"}]}]]}]}]],null,[\"$\",\"$L14\",null,{\"children\":[\"$\",\"$15\",null,{\"name\":\"Next.MetadataOutlet\",\"children\":\"$@16\"}]}]]}]\na:[\"$\",\"$1\",\"h\",{\"children\":[[\"$\",\"meta\",null,{\"name\":\"robots\",\"content\":\"noindex\"}],[\"$\",\"$L18\",null,{\"children\":\"$L19\"}],[\"$\",\"$L1b\",null,{\"children\":[[\"$\",\"div\",null,{\"hidden\":true,\"children\":[\"$\",\"$15\",null,{\"name\":\"Next.Metadata\",\"children\":\"$L1c\"}]}],null]}],null]}]\n7:C\n19:[[\"$\",\"meta\",\"0\",{\"charSet\":\"utf-8\"}],[\"$\",\"meta\",\"1\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1, maximum-scale=1, viewport-fit=cover, interactive-widget=resizes-content\"}],[\"$\",\"meta\",\"2\",{\"name\":\"theme-color\",\"content\":\"#ffffff\",\"media\":\"(prefers-color-scheme: light)\"}],[\"$\",\"meta\",\"3\",{\"name\":\"theme-color\",\"content\":\"#09090b\",\"media\":\"(prefers-color-scheme: dark)\"}]]\n1d:I[86869,[],\"IconMark\"]\n16:null\n1c:[[\"$\",\"title\",\"0\",{\"children\":\"Jarela\"}],[\"$\",\"meta\",\"1\",{\"name\":\"description\",\"content\":\"Jarela — local chat interface for LangGraph agents\"}],[\"$\",\"link\",\"2\",{\"rel\":\"manifest\",\"href\":\"/manifest.webmanifest\",\"crossOrigin\":\"$undefined\"}],[\"$\",\"meta\",\"3\",{\"name\":\"mobile-web-app-capable\",\"content\":\"yes\"}],[\"$\",\"meta\",\"4\",{\"name\":\"apple-mobile-web-app-title\",\"content\":\"Jarela\"}],[\"$\",\"meta\",\"5\",{\"name\":\"apple-mobile-web-app-status-bar-style\",\"content\":\"black-translucent\"}],[\"$\",\"link\",\"6\",{\"rel\":\"icon\",\"href\":\"/favicon.svg\",\"type\":\"image/svg+xml\"}],[\"$\",\"link\",\"7\",{\"rel\":\"icon\",\"href\":\"/favicon.ico\",\"sizes\":\"any\"}],[\"$\",\"link\",\"8\",{\"rel\":\"icon\",\"href\":\"/icon-192.png\",\"type\":\"image/png\",\"sizes\":\"192x192\"}],[\"$\",\"link\",\"9\",{\"rel\":\"icon\",\"href\":\"/icon-512.png\",\"type\":\"image/png\",\"sizes\":\"512x512\"}],[\"$\",\"link\",\"10\",{\"rel\":\"apple-touch-icon\",\"href\":\"/apple-touch-icon.png\",\"sizes\":\"180x180\"}],[\"$\",\"$L1d\",\"11\",{}]]\n"])</script></body></html>
@@ -1 +1 @@
1
- <!DOCTYPE html><html id="__next_error__"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="preload" as="script" fetchPriority="low" href="/_next/static/chunks/webpack-22f2423f357dd0a1.js"/><script src="/_next/static/chunks/4bd1b696-c054103efb2e5332.js" async=""></script><script src="/_next/static/chunks/5254-bcfacd19ebb8dcce.js" async=""></script><script src="/_next/static/chunks/main-app-395c0576f1cde35e.js" async=""></script><title>500: This page couldn’t load</title><style>:root {--next-error-bg: #fff;--next-error-text: #171717;--next-error-title: #171717;--next-error-message: #171717;--next-error-digest: #666666;--next-error-btn-text: #fff;--next-error-btn-bg: #171717;--next-error-btn-border: none;--next-error-btn-secondary-text: #171717;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(0,0,0,0.08);}@media (prefers-color-scheme: dark) {:root {--next-error-bg: #0a0a0a;--next-error-text: #ededed;--next-error-title: #ededed;--next-error-message: #ededed;--next-error-digest: #a0a0a0;--next-error-btn-text: #0a0a0a;--next-error-btn-bg: #ededed;--next-error-btn-border: none;--next-error-btn-secondary-text: #ededed;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(255,255,255,0.14);}}body { margin: 0; color: var(--next-error-text); background: var(--next-error-bg); }</style><script src="/_next/static/chunks/polyfills-42372ed130431b0a.js" noModule=""></script></head><body><div hidden=""><!--$--><!--/$--></div><div style="font-family:system-ui,&quot;Segoe UI&quot;,Roboto,Helvetica,Arial,sans-serif,&quot;Apple Color Emoji&quot;,&quot;Segoe UI Emoji&quot;;height:100vh;display:flex;align-items:center;justify-content:center"><div style="margin-top:-32px;max-width:325px;padding:32px 28px;text-align:left"><svg width="32" height="32" viewBox="-0.2 -1.5 32 32" fill="none" style="margin-bottom:24px"><path d="M16.9328 0C18.0839 0.000116771 19.1334 0.658832 19.634 1.69531L31.4299 26.1309C32.0708 27.4588 31.1036 28.9999 29.6291 29H2.00215C0.527541 29 -0.439628 27.4588 0.201371 26.1309L11.9973 1.69531C12.4979 0.658823 13.5474 7.75066e-05 14.6984 0H16.9328ZM3.59493 26H28.0363L16.9328 3H14.6984L3.59493 26ZM15.8156 19C16.9202 19.0001 17.8156 19.8955 17.8156 21C17.8156 22.1045 16.9202 22.9999 15.8156 23C14.7111 23 13.8156 22.1046 13.8156 21C13.8156 19.8954 14.7111 19 15.8156 19ZM17.3156 16.5H14.3156V8.5H17.3156V16.5Z" fill="var(--next-error-title)"></path></svg><h1 style="font-size:24px;font-weight:500;letter-spacing:-0.02em;line-height:32px;margin:0 0 12px 0;color:var(--next-error-title)">This page couldn’t load</h1><p style="font-size:14px;font-weight:400;line-height:21px;margin:0 0 20px 0;color:var(--next-error-message)">A server error occurred. Reload to try again.</p><form style="margin:0"><button type="submit" style="display:inline-flex;align-items:center;justify-content:center;height:32px;padding:0 12px;font-size:14px;font-weight:500;line-height:20px;border-radius:6px;cursor:pointer;color:var(--next-error-btn-text);background:var(--next-error-btn-bg);border:var(--next-error-btn-border)">Reload</button></form></div></div><!--$--><!--/$--><script src="/_next/static/chunks/webpack-22f2423f357dd0a1.js" id="_R_" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0])</script><script>self.__next_f.push([1,"1:\"$Sreact.fragment\"\n2:I[57121,[],\"\"]\n3:I[74581,[],\"\"]\n7:I[90484,[],\"OutletBoundary\"]\n8:\"$Sreact.suspense\"\na:\"ViewportBoundary\"\nb:I[90484,[],\"$a\"]\nd:\"MetadataBoundary\"\ne:I[90484,[],\"$d\"]\n10:I[27123,[],\"default\",1]\n4:X\n6:[[\"children\",{\"s\":\"__PAGE__\",\"h\":528,\"d\":{\"r\":[\"$\",\"$1\",\"c\",{\"children\":[[\"$\",\"html\",null,{\"id\":\"__next_error__\",\"children\":[[\"$\",\"head\",null,{\"children\":[[\"$\",\"title\",null,{\"children\":\"500: This page couldn’t load\"}],[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\":root {--next-error-bg: #fff;--next-error-text: #171717;--next-error-title: #171717;--next-error-message: #171717;--next-error-digest: #666666;--next-error-btn-text: #fff;--next-error-btn-bg: #171717;--next-error-btn-border: none;--next-error-btn-secondary-text: #171717;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(0,0,0,0.08);}@media (prefers-color-scheme: dark) {:root {--next-error-bg: #0a0a0a;--next-error-text: #ededed;--next-error-title: #ededed;--next-error-message: #ededed;--next-error-digest: #a0a0a0;--next-error-btn-text: #0a0a0a;--next-error-btn-bg: #ededed;--next-error-btn-border: none;--next-error-btn-secondary-text: #ededed;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(255,255,255,0.14);}}body { margin: 0; color: var(--next-error-text); background: var(--next-error-bg); }\"}}]]}],[\"$\",\"body\",null,{\"children\":[\"$\",\"div\",null,{\"style\":{\"fontFamily\":\"system-ui,\\\"Segoe UI\\\",Roboto,Helvetica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\"\",\"height\":\"100vh\",\"display\":\"flex\",\"alignItems\":\"center\",\"justifyContent\":\"center\"},\"children\":[\"$\",\"div\",null,{\"style\":{\"marginTop\":\"-32px\",\"maxWidth\":\"325px\",\"padding\":\"32px 28px\",\"textAlign\":\"left\"},\"children\":[[\"$\",\"svg\",null,{\"width\":\"32\",\"height\":\"32\",\"viewBox\":\"-0.2 -1.5 32 32\",\"fill\":\"none\",\"style\":{\"marginBottom\":\"24px\"},\"children\":[\"$\",\"path\",null,{\"d\":\"M16.9328 0C18.0839 0.000116771 19.1334 0.658832 19.634 1.69531L31.4299 26.1309C32.0708 27.4588 31.1036 28.9999 29.6291 29H2.00215C0.527541 29 -0.439628 27.4588 0.201371 26.1309L11.9973 1.69531C12.4979 0.658823 13.5474 7.75066e-05 14.6984 0H16.9328ZM3.59493 26H28.0363L16.9328 3H14.6984L3.59493 26ZM15.8156 19C16.9202 19.0001 17.8156 19.8955 17.8156 21C17.8156 22.1045 16.9202 22.9999 15.8156 23C14.7111 23 13.8156 22.1046 13.8156 21C13.8156 19.8954 14.7111 19 15.8156 19ZM17.3156 16.5H14.3156V8.5H17.3156V16.5Z\",\"fill\":\"var(--next-error-title)\"}]}],[\"$\",\"h1\",null,{\"style\":{\"fontSize\":\"24px\",\"fontWeight\":500,\"letterSpacing\":\"-0.02em\",\"lineHeight\":\"32px\",\"margin\":\"0 0 12px 0\",\"color\":\"var(--next-error-title)\"},\"children\":\"This page couldn’t load\"}],[\"$\",\"p\",null,{\"style\":{\"fontSize\":\"14px\",\"fontWeight\":400,\"lineHeight\":\"21px\",\"margin\":\"0 0 20px 0\",\"color\":\"var(--next-error-message)\"},\"children\":\"A server error occurred. Reload to try again.\"}],[\"$\",\"form\",null,{\"style\":{\"margin\":0},\"children\":[\"$\",\"button\",null,{\"type\":\"submit\",\"style\":{\"display\":\"inline-flex\",\"alignItems\":\"center\",\"justifyContent\":\"center\",\"height\":\"32px\",\"padding\":\"0 12px\",\"fontSize\":\"14px\",\"fontWeight\":500,\"lineHeight\":\"20px\",\"borderRadius\":\"6px\",\"cursor\":\"pointer\",\"color\":\"var(--next-error-btn-text)\",\"background\":\"var(--next-error-btn-bg)\",\"border\":\"var(--next-error-btn-border)\"},\"children\":\"Reload\"}]}]]}]}]}]]}],null,[\"$\",\"$L7\",null,{\"children\":[\"$\",\"$8\",null,{\"name\":\"Next.MetadataOutlet\",\"children\":\"$@9\"}]}]]}],\"p\":false,\"v\":null}}]]\n5:[[\"children\",{\"s\":\"_global-error\",\"h\":528,\"d\":{\"r\":[\"$\",\"$1\",\"c\",{\"children\":[null,[\"$\",\"$L2\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L3\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]]}],\"p\":false,\"v\":\"$4\"},\"c\":\"$Q6\"}]]\n0:{\"P\":null,\"c\":[\"\",\"_global-error\"],\"q\":\"\",\"i\":false,\"t\":{\"t\":{\"s\":\"\",\"h\":528,\"d\":{\"r\":[\"$\",\"$1\",\"c\",{\"children\":[null,[\"$\",\"$L2\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L3\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]]}],\"p\":false,\"v\":\"$4\"},\"c\":\"$Q5\"},\"h\":{\"r\":[\"$\",\"$1\",\"h\",{\"children\":[null,[\"$\",\"$Lb\",null,{\"children\":\"$Lc\"}],[\"$\",\"$Le\",null,{\"children\":[[\"$\",\"div\",null,{\"hidden\":true,\"children\":[\"$\",\"$8\",null,{\"name\":\"Next.Metadata\",\"children\":\"$Lf\"}]}],null]}],null]}],\"p\":false,\"v\":null}},\"m\":\"$undefined\",\"G\":[\"$10\",[]],\"S\":true,\"r\":\"$undefined\",\"s\":\"$undefined\",\"a\":\"$undefined\",\"l\":\"$undefined\",\"p\":\"$undefined\",\"d\":\"$undefined\",\"b\":\"bMRK5y3ruT7c3WtBfCQOG\"}\n4:C\nc:[[\"$\",\"meta\",\"0\",{\"charSet\":\"utf-8\"}],[\"$\",\"meta\",\"1\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1\"}]]\n9:null\nf:[]\n"])</script></body></html>
1
+ <!DOCTYPE html><html id="__next_error__"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="preload" as="script" fetchPriority="low" href="/_next/static/chunks/webpack-22f2423f357dd0a1.js"/><script src="/_next/static/chunks/4bd1b696-c054103efb2e5332.js" async=""></script><script src="/_next/static/chunks/5254-bcfacd19ebb8dcce.js" async=""></script><script src="/_next/static/chunks/main-app-395c0576f1cde35e.js" async=""></script><title>500: This page couldn’t load</title><style>:root {--next-error-bg: #fff;--next-error-text: #171717;--next-error-title: #171717;--next-error-message: #171717;--next-error-digest: #666666;--next-error-btn-text: #fff;--next-error-btn-bg: #171717;--next-error-btn-border: none;--next-error-btn-secondary-text: #171717;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(0,0,0,0.08);}@media (prefers-color-scheme: dark) {:root {--next-error-bg: #0a0a0a;--next-error-text: #ededed;--next-error-title: #ededed;--next-error-message: #ededed;--next-error-digest: #a0a0a0;--next-error-btn-text: #0a0a0a;--next-error-btn-bg: #ededed;--next-error-btn-border: none;--next-error-btn-secondary-text: #ededed;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(255,255,255,0.14);}}body { margin: 0; color: var(--next-error-text); background: var(--next-error-bg); }</style><script src="/_next/static/chunks/polyfills-42372ed130431b0a.js" noModule=""></script></head><body><div hidden=""><!--$--><!--/$--></div><div style="font-family:system-ui,&quot;Segoe UI&quot;,Roboto,Helvetica,Arial,sans-serif,&quot;Apple Color Emoji&quot;,&quot;Segoe UI Emoji&quot;;height:100vh;display:flex;align-items:center;justify-content:center"><div style="margin-top:-32px;max-width:325px;padding:32px 28px;text-align:left"><svg width="32" height="32" viewBox="-0.2 -1.5 32 32" fill="none" style="margin-bottom:24px"><path d="M16.9328 0C18.0839 0.000116771 19.1334 0.658832 19.634 1.69531L31.4299 26.1309C32.0708 27.4588 31.1036 28.9999 29.6291 29H2.00215C0.527541 29 -0.439628 27.4588 0.201371 26.1309L11.9973 1.69531C12.4979 0.658823 13.5474 7.75066e-05 14.6984 0H16.9328ZM3.59493 26H28.0363L16.9328 3H14.6984L3.59493 26ZM15.8156 19C16.9202 19.0001 17.8156 19.8955 17.8156 21C17.8156 22.1045 16.9202 22.9999 15.8156 23C14.7111 23 13.8156 22.1046 13.8156 21C13.8156 19.8954 14.7111 19 15.8156 19ZM17.3156 16.5H14.3156V8.5H17.3156V16.5Z" fill="var(--next-error-title)"></path></svg><h1 style="font-size:24px;font-weight:500;letter-spacing:-0.02em;line-height:32px;margin:0 0 12px 0;color:var(--next-error-title)">This page couldn’t load</h1><p style="font-size:14px;font-weight:400;line-height:21px;margin:0 0 20px 0;color:var(--next-error-message)">A server error occurred. Reload to try again.</p><form style="margin:0"><button type="submit" style="display:inline-flex;align-items:center;justify-content:center;height:32px;padding:0 12px;font-size:14px;font-weight:500;line-height:20px;border-radius:6px;cursor:pointer;color:var(--next-error-btn-text);background:var(--next-error-btn-bg);border:var(--next-error-btn-border)">Reload</button></form></div></div><!--$--><!--/$--><script src="/_next/static/chunks/webpack-22f2423f357dd0a1.js" id="_R_" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0])</script><script>self.__next_f.push([1,"1:\"$Sreact.fragment\"\n2:I[57121,[],\"\"]\n3:I[74581,[],\"\"]\n7:I[90484,[],\"OutletBoundary\"]\n8:\"$Sreact.suspense\"\na:\"ViewportBoundary\"\nb:I[90484,[],\"$a\"]\nd:\"MetadataBoundary\"\ne:I[90484,[],\"$d\"]\n10:I[27123,[],\"default\",1]\n4:X\n6:[[\"children\",{\"s\":\"__PAGE__\",\"h\":528,\"d\":{\"r\":[\"$\",\"$1\",\"c\",{\"children\":[[\"$\",\"html\",null,{\"id\":\"__next_error__\",\"children\":[[\"$\",\"head\",null,{\"children\":[[\"$\",\"title\",null,{\"children\":\"500: This page couldn’t load\"}],[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\":root {--next-error-bg: #fff;--next-error-text: #171717;--next-error-title: #171717;--next-error-message: #171717;--next-error-digest: #666666;--next-error-btn-text: #fff;--next-error-btn-bg: #171717;--next-error-btn-border: none;--next-error-btn-secondary-text: #171717;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(0,0,0,0.08);}@media (prefers-color-scheme: dark) {:root {--next-error-bg: #0a0a0a;--next-error-text: #ededed;--next-error-title: #ededed;--next-error-message: #ededed;--next-error-digest: #a0a0a0;--next-error-btn-text: #0a0a0a;--next-error-btn-bg: #ededed;--next-error-btn-border: none;--next-error-btn-secondary-text: #ededed;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(255,255,255,0.14);}}body { margin: 0; color: var(--next-error-text); background: var(--next-error-bg); }\"}}]]}],[\"$\",\"body\",null,{\"children\":[\"$\",\"div\",null,{\"style\":{\"fontFamily\":\"system-ui,\\\"Segoe UI\\\",Roboto,Helvetica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\"\",\"height\":\"100vh\",\"display\":\"flex\",\"alignItems\":\"center\",\"justifyContent\":\"center\"},\"children\":[\"$\",\"div\",null,{\"style\":{\"marginTop\":\"-32px\",\"maxWidth\":\"325px\",\"padding\":\"32px 28px\",\"textAlign\":\"left\"},\"children\":[[\"$\",\"svg\",null,{\"width\":\"32\",\"height\":\"32\",\"viewBox\":\"-0.2 -1.5 32 32\",\"fill\":\"none\",\"style\":{\"marginBottom\":\"24px\"},\"children\":[\"$\",\"path\",null,{\"d\":\"M16.9328 0C18.0839 0.000116771 19.1334 0.658832 19.634 1.69531L31.4299 26.1309C32.0708 27.4588 31.1036 28.9999 29.6291 29H2.00215C0.527541 29 -0.439628 27.4588 0.201371 26.1309L11.9973 1.69531C12.4979 0.658823 13.5474 7.75066e-05 14.6984 0H16.9328ZM3.59493 26H28.0363L16.9328 3H14.6984L3.59493 26ZM15.8156 19C16.9202 19.0001 17.8156 19.8955 17.8156 21C17.8156 22.1045 16.9202 22.9999 15.8156 23C14.7111 23 13.8156 22.1046 13.8156 21C13.8156 19.8954 14.7111 19 15.8156 19ZM17.3156 16.5H14.3156V8.5H17.3156V16.5Z\",\"fill\":\"var(--next-error-title)\"}]}],[\"$\",\"h1\",null,{\"style\":{\"fontSize\":\"24px\",\"fontWeight\":500,\"letterSpacing\":\"-0.02em\",\"lineHeight\":\"32px\",\"margin\":\"0 0 12px 0\",\"color\":\"var(--next-error-title)\"},\"children\":\"This page couldn’t load\"}],[\"$\",\"p\",null,{\"style\":{\"fontSize\":\"14px\",\"fontWeight\":400,\"lineHeight\":\"21px\",\"margin\":\"0 0 20px 0\",\"color\":\"var(--next-error-message)\"},\"children\":\"A server error occurred. Reload to try again.\"}],[\"$\",\"form\",null,{\"style\":{\"margin\":0},\"children\":[\"$\",\"button\",null,{\"type\":\"submit\",\"style\":{\"display\":\"inline-flex\",\"alignItems\":\"center\",\"justifyContent\":\"center\",\"height\":\"32px\",\"padding\":\"0 12px\",\"fontSize\":\"14px\",\"fontWeight\":500,\"lineHeight\":\"20px\",\"borderRadius\":\"6px\",\"cursor\":\"pointer\",\"color\":\"var(--next-error-btn-text)\",\"background\":\"var(--next-error-btn-bg)\",\"border\":\"var(--next-error-btn-border)\"},\"children\":\"Reload\"}]}]]}]}]}]]}],null,[\"$\",\"$L7\",null,{\"children\":[\"$\",\"$8\",null,{\"name\":\"Next.MetadataOutlet\",\"children\":\"$@9\"}]}]]}],\"p\":false,\"v\":null}}]]\n5:[[\"children\",{\"s\":\"_global-error\",\"h\":528,\"d\":{\"r\":[\"$\",\"$1\",\"c\",{\"children\":[null,[\"$\",\"$L2\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L3\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]]}],\"p\":false,\"v\":\"$4\"},\"c\":\"$Q6\"}]]\n0:{\"P\":null,\"c\":[\"\",\"_global-error\"],\"q\":\"\",\"i\":false,\"t\":{\"t\":{\"s\":\"\",\"h\":528,\"d\":{\"r\":[\"$\",\"$1\",\"c\",{\"children\":[null,[\"$\",\"$L2\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L3\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]]}],\"p\":false,\"v\":\"$4\"},\"c\":\"$Q5\"},\"h\":{\"r\":[\"$\",\"$1\",\"h\",{\"children\":[null,[\"$\",\"$Lb\",null,{\"children\":\"$Lc\"}],[\"$\",\"$Le\",null,{\"children\":[[\"$\",\"div\",null,{\"hidden\":true,\"children\":[\"$\",\"$8\",null,{\"name\":\"Next.Metadata\",\"children\":\"$Lf\"}]}],null]}],null]}],\"p\":false,\"v\":null}},\"m\":\"$undefined\",\"G\":[\"$10\",[]],\"S\":true,\"r\":\"$undefined\",\"s\":\"$undefined\",\"a\":\"$undefined\",\"l\":\"$undefined\",\"p\":\"$undefined\",\"d\":\"$undefined\",\"b\":\"544OFJV-q0RC6Gjgje4LT\"}\n4:C\nc:[[\"$\",\"meta\",\"0\",{\"charSet\":\"utf-8\"}],[\"$\",\"meta\",\"1\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1\"}]]\n9:null\nf:[]\n"])</script></body></html>
@@ -1,5 +1,5 @@
1
1
  {
2
- "previewModeId": "e68b06f6be07b42946dc6c86bf5d1a3e",
3
- "previewModeSigningKey": "73e7b77f5ec476d7ae72d77660fe5db72d1aac0d01fcb8b85b7da570cd20fc56",
4
- "previewModeEncryptionKey": "1989fa6eb09ee2002b498b6133e93a3dfa2544e08a2838a7095824ce944070ab"
2
+ "previewModeId": "5d20030d2cc3715319c07a144493fb87",
3
+ "previewModeSigningKey": "0fa2e145f6703519809f6a27bb8ddca6ea4c7c5ca72b60d4791c8d3b912fb169",
4
+ "previewModeEncryptionKey": "0904535dd7dee2d744de0e2e5cc06a7162a9c5940911f22ca29c52d67e59eb81"
5
5
  }
@@ -1 +1 @@
1
- {"node":{},"edge":{},"encryptionKey":"xLxzukyNV8A0JmjW62Zs0jCnndoPuIg45Pfkb+dvsuk="}
1
+ {"node":{},"edge":{},"encryptionKey":"zjaewHulsJBPGElTIwNBffDdQjhuNWh48IgFX3V/d1g="}
@@ -9033,6 +9033,7 @@ function ProviderLogo({ name, size = 16, className = "" }) {
9033
9033
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
9034
9034
 
9035
9035
  /* harmony export */ __webpack_require__.d(__webpack_exports__, {
9036
+ /* harmony export */ Dg: () => (/* binding */ getAppAccentColor),
9036
9037
  /* harmony export */ E2: () => (/* binding */ UPSTREAM_URL),
9037
9038
  /* harmony export */ SN: () => (/* binding */ getAppIssueUrl),
9038
9039
  /* harmony export */ YC: () => (/* binding */ UPSTREAM_NAME),
@@ -9041,7 +9042,7 @@ function ProviderLogo({ name, size = 16, className = "" }) {
9041
9042
  /* harmony export */ lE: () => (/* binding */ getAppLogoDark),
9042
9043
  /* harmony export */ qc: () => (/* binding */ getAppIcons)
9043
9044
  /* harmony export */ });
9044
- /* unused harmony exports getAppShortName, getAppDescription, getAppAccentColor, getAppAccentHoverColor */
9045
+ /* unused harmony exports getAppShortName, getAppDescription, getAppAccentHoverColor */
9045
9046
  /* provided dependency */ var process = __webpack_require__(87358);
9046
9047
  // Branding knobs sourced from NEXT_PUBLIC_* env vars so forks can rebrand
9047
9048
  // the app without patching source. NEXT_PUBLIC_* is the right
@@ -9431,11 +9432,44 @@ async function parseJsonResponse(res) {
9431
9432
  const stream = source.pipeThrough(new DecompressionStream("gzip"));
9432
9433
  return JSON.parse(await new Response(stream).text());
9433
9434
  }
9435
+ const STARTUP_TTL_MS = 5000;
9436
+ const startupReads = new Map();
9437
+ function startupRead(path) {
9438
+ const now = Date.now();
9439
+ for (const [key, entry] of startupReads){
9440
+ if (entry.settledAt !== null && (now < entry.settledAt || now - entry.settledAt >= STARTUP_TTL_MS)) {
9441
+ startupReads.delete(key);
9442
+ }
9443
+ }
9444
+ const cached = startupReads.get(path);
9445
+ if (cached) return cached.promise.then((value)=>structuredClone(value));
9446
+ // Bound retained startup data when agents are switched rapidly.
9447
+ const oldestKey = startupReads.keys().next().value;
9448
+ if (startupReads.size >= 16 && oldestKey !== undefined) startupReads.delete(oldestKey);
9449
+ const entry = {
9450
+ promise: Promise.resolve(undefined),
9451
+ settledAt: null
9452
+ };
9453
+ entry.promise = request(path, {
9454
+ startup: true
9455
+ }).then((value)=>{
9456
+ entry.settledAt = Date.now();
9457
+ return value;
9458
+ }).catch((error)=>{
9459
+ if (startupReads.get(path) === entry) startupReads.delete(path);
9460
+ throw error;
9461
+ });
9462
+ startupReads.set(path, entry);
9463
+ return entry.promise.then((value)=>structuredClone(value));
9464
+ }
9434
9465
  async function request(path, init) {
9466
+ const mutation = !!init?.method && init.method !== "GET";
9467
+ if (mutation) startupReads.clear();
9468
+ else if (!init?.startup) startupReads.delete(path);
9435
9469
  const cfg = (0,_runtime_config__WEBPACK_IMPORTED_MODULE_0__/* .runtimeConfig */ .Z)();
9436
9470
  const maxAttempts = Math.max(1, cfg.httpMaxAttempts);
9437
9471
  const timeoutMs = init?.timeoutMs ?? cfg.httpRequestTimeoutMs;
9438
- const { timeoutMs: _ignoreTimeoutMs, ...fetchInit } = init ?? {};
9472
+ const { timeoutMs: _ignoreTimeoutMs, startup: _ignoreStartup, ...fetchInit } = init ?? {};
9439
9473
  const callerSignal = fetchInit.signal ?? null;
9440
9474
  let lastErr = null;
9441
9475
  for(let attempt = 1; attempt <= maxAttempts; attempt++){
@@ -9495,6 +9529,7 @@ async function request(path, init) {
9495
9529
  if (attempt < maxAttempts && isRetryable(err)) continue;
9496
9530
  throw err;
9497
9531
  } finally{
9532
+ if (mutation) startupReads.clear();
9498
9533
  clearTimeout(timer);
9499
9534
  callerSignal?.removeEventListener("abort", onCallerAbort);
9500
9535
  }
@@ -9505,7 +9540,10 @@ async function request(path, init) {
9505
9540
  const api = {
9506
9541
  agents: {
9507
9542
  list: (opts)=>cachedList(agentListCache, ()=>request("/agents"), setAgentListCache, opts?.force === true),
9508
- get: (id)=>request(`/agents/${encodeURIComponent(id)}`),
9543
+ get: (id, opts)=>{
9544
+ const path = `/agents/${encodeURIComponent(id)}`;
9545
+ return opts?.startup ? startupRead(path) : request(path);
9546
+ },
9509
9547
  create: async (data)=>{
9510
9548
  const created = await request("/agents", {
9511
9549
  method: "POST",
@@ -9537,7 +9575,10 @@ const api = {
9537
9575
  }
9538
9576
  return res;
9539
9577
  },
9540
- getThread: (id)=>request(`/agents/${encodeURIComponent(id)}/thread`),
9578
+ getThread: (id, opts)=>{
9579
+ const path = `/agents/${encodeURIComponent(id)}/thread`;
9580
+ return opts?.startup ? startupRead(path) : request(path);
9581
+ },
9541
9582
  compact: (id, options)=>request(`/agents/${encodeURIComponent(id)}/compact`, // Conversation summarization can take longer than normal API calls,
9542
9583
  // so avoid tripping the default HTTP timeout for large threads.
9543
9584
  {
@@ -9756,8 +9797,12 @@ const api = {
9756
9797
  // user+assistant pair instead of re-pulling the whole most-recent page.
9757
9798
  if (opts?.after !== undefined) p.set("after", String(opts.after));
9758
9799
  const qs = p.toString() ? `?${p}` : "";
9759
- return request(`/threads/${thread_id}${qs}`);
9800
+ const path = `/threads/${thread_id}${qs}`;
9801
+ return opts?.startup ? startupRead(path) : request(path);
9760
9802
  },
9803
+ metadata: (thread_id, signal)=>request(`/threads/${thread_id}?view=metadata`, {
9804
+ signal
9805
+ }),
9761
9806
  delete: (thread_id)=>request(`/threads/${thread_id}`, {
9762
9807
  method: "DELETE"
9763
9808
  }),
@@ -9959,7 +10004,7 @@ const api = {
9959
10004
  }
9960
10005
  },
9961
10006
  profile: {
9962
- get: ()=>request("/profile"),
10007
+ get: (opts)=>opts?.startup ? startupRead("/profile") : request("/profile"),
9963
10008
  update: (data)=>request("/profile", {
9964
10009
  method: "PUT",
9965
10010
  body: JSON.stringify(data)
@@ -10445,6 +10490,7 @@ const api = {
10445
10490
  * caller is expected to follow up with `subscribeRun()` to receive the
10446
10491
  * chunk stream. Idempotent in the sense that two simultaneous submissions
10447
10492
  * for the same thread will see one 202 and one 409 (`run_in_flight`). */ async function submitRun(thread_id, message, signal, stream_options, attachments, channels, hot_since_seq) {
10493
+ startupReads.clear();
10448
10494
  const payload = {
10449
10495
  message,
10450
10496
  stream_options,
@@ -10460,7 +10506,7 @@ const api = {
10460
10506
  },
10461
10507
  body: JSON.stringify(runPayload),
10462
10508
  signal
10463
- });
10509
+ }).finally(()=>startupReads.clear());
10464
10510
  // 2xx = accepted (currently always 202); 409 = already running. We treat
10465
10511
  // every other status as a hard error so the consumer's catch fires.
10466
10512
  if (res.status === 202) {
@@ -12255,4 +12301,4 @@ function useActiveConfirm() {
12255
12301
  /***/ })
12256
12302
 
12257
12303
  }]);
12258
- //# sourceMappingURL=1395-e4a99912b8f83044.js.map
12304
+ //# sourceMappingURL=1395-bfe1f3ef760c0f50.js.map
@@ -421,9 +421,17 @@ function createLucideIcon(iconDataOrName, iconNode = [], aliases = []) {
421
421
  /* __next_internal_client_entry_do_not_use__ ThemeProvider,useTheme auto */
422
422
 
423
423
  const STORAGE_KEY = "jarela-theme";
424
+ const ACCENT_STORAGE_KEY = "jarela-accent-color";
425
+ const SURFACE_STORAGE_KEY = "jarela-surface-style";
424
426
  function isTheme(v) {
425
427
  return v === "light" || v === "dark" || v === "system";
426
428
  }
429
+ function isAccentColor(v) {
430
+ return v === "default" || v === "blue" || v === "teal" || v === "violet" || v === "rose";
431
+ }
432
+ function isSurfaceStyle(v) {
433
+ return v === "ambient" || v === "calm" || v === "liquid";
434
+ }
427
435
  function readStored() {
428
436
  if (false) {}
429
437
  try {
@@ -433,6 +441,24 @@ function readStored() {
433
441
  return "system";
434
442
  }
435
443
  }
444
+ function readStoredAccent() {
445
+ if (false) {}
446
+ try {
447
+ const value = window.localStorage.getItem(ACCENT_STORAGE_KEY);
448
+ return isAccentColor(value) ? value : "default";
449
+ } catch {
450
+ return "default";
451
+ }
452
+ }
453
+ function readStoredSurface() {
454
+ if (false) {}
455
+ try {
456
+ const value = window.localStorage.getItem(SURFACE_STORAGE_KEY);
457
+ return isSurfaceStyle(value) ? value : "ambient";
458
+ } catch {
459
+ return "ambient";
460
+ }
461
+ }
436
462
  const LIGHT_CHROME = "#ffffff";
437
463
  const DARK_CHROME = "#09090b";
438
464
  function resolveChrome(theme) {
@@ -454,15 +480,35 @@ function apply(theme) {
454
480
  document.documentElement.setAttribute("data-theme", theme);
455
481
  syncChrome(theme);
456
482
  }
483
+ function applyAccentColor(accentColor) {
484
+ if (typeof document === "undefined") return;
485
+ if (accentColor === "default") {
486
+ document.documentElement.removeAttribute("data-accent-color");
487
+ return;
488
+ }
489
+ document.documentElement.setAttribute("data-accent-color", accentColor);
490
+ }
491
+ function applySurfaceStyle(surfaceStyle) {
492
+ if (typeof document === "undefined") return;
493
+ document.documentElement.setAttribute("data-surface-style", surfaceStyle);
494
+ }
457
495
  const ThemeContext = /*#__PURE__*/ (0,react__WEBPACK_IMPORTED_MODULE_1__.createContext)(null);
458
496
  function ThemeProvider({ children }) {
459
497
  // Initial state stays "system" on the server to match the pre-paint script,
460
498
  // which writes data-theme before React hydrates. The effect below syncs the
461
499
  // React state to whatever the script (or localStorage) decided.
462
500
  const [theme, setThemeState] = (0,react__WEBPACK_IMPORTED_MODULE_1__.useState)("system");
501
+ const [accentColor, setAccentColorState] = (0,react__WEBPACK_IMPORTED_MODULE_1__.useState)("blue");
502
+ const [surfaceStyle, setSurfaceStyleState] = (0,react__WEBPACK_IMPORTED_MODULE_1__.useState)("ambient");
463
503
  (0,react__WEBPACK_IMPORTED_MODULE_1__.useEffect)(()=>{
464
504
  const stored = readStored();
505
+ const storedAccent = readStoredAccent();
506
+ const storedSurface = readStoredSurface();
465
507
  setThemeState(stored);
508
+ setAccentColorState(storedAccent);
509
+ setSurfaceStyleState(storedSurface);
510
+ applyAccentColor(storedAccent);
511
+ applySurfaceStyle(storedSurface);
466
512
  // When in "system" mode, mirror OS-level changes into the PWA chrome.
467
513
  if (false) {}
468
514
  const mq = window.matchMedia("(prefers-color-scheme: dark)");
@@ -480,10 +526,31 @@ function ThemeProvider({ children }) {
480
526
  } catch {
481
527
  /* ignore quota / private-mode errors */ }
482
528
  }, []);
529
+ const setAccentColor = (0,react__WEBPACK_IMPORTED_MODULE_1__.useCallback)((color)=>{
530
+ setAccentColorState(color);
531
+ applyAccentColor(color);
532
+ try {
533
+ if (color === "default") window.localStorage.removeItem(ACCENT_STORAGE_KEY);
534
+ else window.localStorage.setItem(ACCENT_STORAGE_KEY, color);
535
+ } catch {
536
+ /* ignore quota / private-mode errors */ }
537
+ }, []);
538
+ const setSurfaceStyle = (0,react__WEBPACK_IMPORTED_MODULE_1__.useCallback)((style)=>{
539
+ setSurfaceStyleState(style);
540
+ applySurfaceStyle(style);
541
+ try {
542
+ window.localStorage.setItem(SURFACE_STORAGE_KEY, style);
543
+ } catch {
544
+ /* ignore quota / private-mode errors */ }
545
+ }, []);
483
546
  return /*#__PURE__*/ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(ThemeContext.Provider, {
484
547
  value: {
485
548
  theme,
486
- setTheme
549
+ setTheme,
550
+ accentColor,
551
+ setAccentColor,
552
+ surfaceStyle,
553
+ setSurfaceStyle
487
554
  },
488
555
  children: children
489
556
  });
@@ -958,4 +1025,4 @@ function useActiveConfirm() {
958
1025
  /******/ _N_E = __webpack_exports__;
959
1026
  /******/ }
960
1027
  ]);
961
- //# sourceMappingURL=layout-9bc0b10127cb7d42.js.map
1028
+ //# sourceMappingURL=layout-7b24ad13faa3944b.js.map