@agent-native/core 0.30.6 → 0.31.1

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 (391) hide show
  1. package/dist/a2a/client.d.ts +2 -0
  2. package/dist/a2a/client.d.ts.map +1 -1
  3. package/dist/a2a/client.js +7 -5
  4. package/dist/a2a/client.js.map +1 -1
  5. package/dist/a2a/handlers.d.ts.map +1 -1
  6. package/dist/a2a/handlers.js +3 -0
  7. package/dist/a2a/handlers.js.map +1 -1
  8. package/dist/a2a/server.d.ts.map +1 -1
  9. package/dist/a2a/server.js.map +1 -1
  10. package/dist/a2a/task-store.d.ts.map +1 -1
  11. package/dist/a2a/task-store.js +5 -1
  12. package/dist/a2a/task-store.js.map +1 -1
  13. package/dist/action.js +22 -4
  14. package/dist/action.js.map +1 -1
  15. package/dist/agent/engine/ai-sdk-engine.d.ts.map +1 -1
  16. package/dist/agent/engine/ai-sdk-engine.js +5 -0
  17. package/dist/agent/engine/ai-sdk-engine.js.map +1 -1
  18. package/dist/agent/engine/anthropic-engine.d.ts.map +1 -1
  19. package/dist/agent/engine/anthropic-engine.js +0 -7
  20. package/dist/agent/engine/anthropic-engine.js.map +1 -1
  21. package/dist/agent/engine/builder-engine.d.ts.map +1 -1
  22. package/dist/agent/engine/builder-engine.js +4 -0
  23. package/dist/agent/engine/builder-engine.js.map +1 -1
  24. package/dist/agent/engine/registry.d.ts.map +1 -1
  25. package/dist/agent/engine/registry.js.map +1 -1
  26. package/dist/agent/engine/translate-ai-sdk.d.ts.map +1 -1
  27. package/dist/agent/engine/translate-ai-sdk.js +5 -3
  28. package/dist/agent/engine/translate-ai-sdk.js.map +1 -1
  29. package/dist/agent/production-agent.d.ts.map +1 -1
  30. package/dist/agent/production-agent.js +31 -4
  31. package/dist/agent/production-agent.js.map +1 -1
  32. package/dist/agent/run-manager.d.ts.map +1 -1
  33. package/dist/agent/run-manager.js +21 -8
  34. package/dist/agent/run-manager.js.map +1 -1
  35. package/dist/agent/run-store.d.ts.map +1 -1
  36. package/dist/agent/run-store.js +5 -1
  37. package/dist/agent/run-store.js.map +1 -1
  38. package/dist/agent/tool-search.js.map +1 -1
  39. package/dist/application-state/store.d.ts.map +1 -1
  40. package/dist/application-state/store.js +18 -7
  41. package/dist/application-state/store.js.map +1 -1
  42. package/dist/brand-kit/brand-signals.d.ts +31 -0
  43. package/dist/brand-kit/brand-signals.d.ts.map +1 -0
  44. package/dist/brand-kit/brand-signals.js +101 -0
  45. package/dist/brand-kit/brand-signals.js.map +1 -0
  46. package/dist/brand-kit/index.d.ts +21 -0
  47. package/dist/brand-kit/index.d.ts.map +1 -0
  48. package/dist/brand-kit/index.js +34 -0
  49. package/dist/brand-kit/index.js.map +1 -0
  50. package/dist/brand-kit/types.d.ts +103 -0
  51. package/dist/brand-kit/types.d.ts.map +1 -0
  52. package/dist/brand-kit/types.js +17 -0
  53. package/dist/brand-kit/types.js.map +1 -0
  54. package/dist/browser-sessions/store.d.ts.map +1 -1
  55. package/dist/browser-sessions/store.js +6 -1
  56. package/dist/browser-sessions/store.js.map +1 -1
  57. package/dist/chat-threads/store.d.ts.map +1 -1
  58. package/dist/chat-threads/store.js +6 -2
  59. package/dist/chat-threads/store.js.map +1 -1
  60. package/dist/checkpoints/store.d.ts.map +1 -1
  61. package/dist/checkpoints/store.js +5 -1
  62. package/dist/checkpoints/store.js.map +1 -1
  63. package/dist/cli/code-agent-executor.d.ts.map +1 -1
  64. package/dist/cli/code-agent-executor.js.map +1 -1
  65. package/dist/cli/create.d.ts.map +1 -1
  66. package/dist/cli/create.js +0 -1
  67. package/dist/cli/create.js.map +1 -1
  68. package/dist/client/AgentNative.js.map +1 -1
  69. package/dist/client/AgentPanel.d.ts.map +1 -1
  70. package/dist/client/AgentPanel.js +18 -20
  71. package/dist/client/AgentPanel.js.map +1 -1
  72. package/dist/client/AssistantChat.d.ts.map +1 -1
  73. package/dist/client/AssistantChat.js +69 -17
  74. package/dist/client/AssistantChat.js.map +1 -1
  75. package/dist/client/IframeEmbed.d.ts.map +1 -1
  76. package/dist/client/IframeEmbed.js.map +1 -1
  77. package/dist/client/MultiTabAssistantChat.d.ts.map +1 -1
  78. package/dist/client/MultiTabAssistantChat.js +1 -1
  79. package/dist/client/MultiTabAssistantChat.js.map +1 -1
  80. package/dist/client/RunStuckBanner.js.map +1 -1
  81. package/dist/client/agent-chat.d.ts +0 -3
  82. package/dist/client/agent-chat.d.ts.map +1 -1
  83. package/dist/client/agent-chat.js +0 -3
  84. package/dist/client/agent-chat.js.map +1 -1
  85. package/dist/client/builder-mark.d.ts.map +1 -1
  86. package/dist/client/builder-mark.js.map +1 -1
  87. package/dist/client/components/CodeRequiredDialog.js +0 -7
  88. package/dist/client/components/CodeRequiredDialog.js.map +1 -1
  89. package/dist/client/components/MissingKeyCard.d.ts.map +1 -1
  90. package/dist/client/components/MissingKeyCard.js.map +1 -1
  91. package/dist/client/composer/PromptComposer.d.ts.map +1 -1
  92. package/dist/client/composer/PromptComposer.js +6 -3
  93. package/dist/client/composer/PromptComposer.js.map +1 -1
  94. package/dist/client/composer/TiptapComposer.d.ts.map +1 -1
  95. package/dist/client/composer/TiptapComposer.js +5 -0
  96. package/dist/client/composer/TiptapComposer.js.map +1 -1
  97. package/dist/client/composer/VoiceButton.d.ts.map +1 -1
  98. package/dist/client/composer/VoiceButton.js +9 -0
  99. package/dist/client/composer/VoiceButton.js.map +1 -1
  100. package/dist/client/composer/extensions/FileReference.d.ts.map +1 -1
  101. package/dist/client/composer/extensions/FileReference.js.map +1 -1
  102. package/dist/client/composer/extensions/MentionReference.d.ts.map +1 -1
  103. package/dist/client/composer/extensions/MentionReference.js.map +1 -1
  104. package/dist/client/composer/extensions/SkillReference.d.ts.map +1 -1
  105. package/dist/client/composer/extensions/SkillReference.js.map +1 -1
  106. package/dist/client/composer/use-file-search.d.ts.map +1 -1
  107. package/dist/client/composer/use-file-search.js +14 -3
  108. package/dist/client/composer/use-file-search.js.map +1 -1
  109. package/dist/client/conversation/AgentConversation.js +8 -6
  110. package/dist/client/conversation/AgentConversation.js.map +1 -1
  111. package/dist/client/conversation/use-near-bottom-autoscroll.d.ts.map +1 -1
  112. package/dist/client/conversation/use-near-bottom-autoscroll.js +133 -35
  113. package/dist/client/conversation/use-near-bottom-autoscroll.js.map +1 -1
  114. package/dist/client/db-admin/DbAdminPage.js.map +1 -1
  115. package/dist/client/db-admin/EditableCell.js +1 -1
  116. package/dist/client/db-admin/EditableCell.js.map +1 -1
  117. package/dist/client/dev-overlay/DevOverlay.d.ts +0 -2
  118. package/dist/client/dev-overlay/DevOverlay.d.ts.map +1 -1
  119. package/dist/client/dev-overlay/DevOverlay.js +1 -2
  120. package/dist/client/dev-overlay/DevOverlay.js.map +1 -1
  121. package/dist/client/extensions/EmbeddedExtension.d.ts.map +1 -1
  122. package/dist/client/extensions/EmbeddedExtension.js +19 -0
  123. package/dist/client/extensions/EmbeddedExtension.js.map +1 -1
  124. package/dist/client/extensions/ExtensionViewer.d.ts.map +1 -1
  125. package/dist/client/extensions/ExtensionViewer.js +11 -3
  126. package/dist/client/extensions/ExtensionViewer.js.map +1 -1
  127. package/dist/client/integrations/IntegrationsPanel.d.ts.map +1 -1
  128. package/dist/client/integrations/IntegrationsPanel.js.map +1 -1
  129. package/dist/client/mcp-app-host.d.ts.map +1 -1
  130. package/dist/client/mcp-app-host.js +25 -3
  131. package/dist/client/mcp-app-host.js.map +1 -1
  132. package/dist/client/mcp-apps/McpAppRenderer.d.ts.map +1 -1
  133. package/dist/client/mcp-apps/McpAppRenderer.js +1 -1
  134. package/dist/client/mcp-apps/McpAppRenderer.js.map +1 -1
  135. package/dist/client/notifications/NotificationsBell.js.map +1 -1
  136. package/dist/client/onboarding/SetupButton.d.ts.map +1 -1
  137. package/dist/client/onboarding/SetupButton.js +6 -0
  138. package/dist/client/onboarding/SetupButton.js.map +1 -1
  139. package/dist/client/progress/RunsTray.js.map +1 -1
  140. package/dist/client/resources/McpServerDetail.d.ts.map +1 -1
  141. package/dist/client/resources/McpServerDetail.js.map +1 -1
  142. package/dist/client/resources/ResourcesPanel.d.ts.map +1 -1
  143. package/dist/client/resources/ResourcesPanel.js +0 -1
  144. package/dist/client/resources/ResourcesPanel.js.map +1 -1
  145. package/dist/client/settings/AgentsSection.d.ts.map +1 -1
  146. package/dist/client/settings/AgentsSection.js +1 -1
  147. package/dist/client/settings/AgentsSection.js.map +1 -1
  148. package/dist/client/settings/AutomationsSection.js.map +1 -1
  149. package/dist/client/settings/SettingsPanel.js +2 -2
  150. package/dist/client/settings/SettingsPanel.js.map +1 -1
  151. package/dist/client/sharing/ShareButton.d.ts.map +1 -1
  152. package/dist/client/sharing/ShareButton.js +0 -4
  153. package/dist/client/sharing/ShareButton.js.map +1 -1
  154. package/dist/client/sse-event-processor.d.ts.map +1 -1
  155. package/dist/client/sse-event-processor.js +13 -3
  156. package/dist/client/sse-event-processor.js.map +1 -1
  157. package/dist/client/terminal/AgentTerminal.d.ts.map +1 -1
  158. package/dist/client/terminal/AgentTerminal.js +1 -1
  159. package/dist/client/terminal/AgentTerminal.js.map +1 -1
  160. package/dist/client/use-agent-chat.d.ts.map +1 -1
  161. package/dist/client/use-agent-chat.js +20 -4
  162. package/dist/client/use-agent-chat.js.map +1 -1
  163. package/dist/client/use-chat-threads.d.ts.map +1 -1
  164. package/dist/client/use-chat-threads.js +39 -25
  165. package/dist/client/use-chat-threads.js.map +1 -1
  166. package/dist/client/use-db-sync.d.ts.map +1 -1
  167. package/dist/client/use-db-sync.js +24 -0
  168. package/dist/client/use-db-sync.js.map +1 -1
  169. package/dist/client/use-dev-mode.d.ts.map +1 -1
  170. package/dist/client/use-dev-mode.js +25 -9
  171. package/dist/client/use-dev-mode.js.map +1 -1
  172. package/dist/client/use-run-stuck-detection.d.ts.map +1 -1
  173. package/dist/client/use-run-stuck-detection.js +7 -1
  174. package/dist/client/use-run-stuck-detection.js.map +1 -1
  175. package/dist/client/useProductionAgent.d.ts.map +1 -1
  176. package/dist/client/useProductionAgent.js +6 -2
  177. package/dist/client/useProductionAgent.js.map +1 -1
  178. package/dist/collab/agent-presence.d.ts +0 -3
  179. package/dist/collab/agent-presence.d.ts.map +1 -1
  180. package/dist/collab/agent-presence.js +3 -5
  181. package/dist/collab/agent-presence.js.map +1 -1
  182. package/dist/collab/awareness.d.ts.map +1 -1
  183. package/dist/collab/awareness.js +11 -1
  184. package/dist/collab/awareness.js.map +1 -1
  185. package/dist/collab/client-struct.js.map +1 -1
  186. package/dist/collab/storage.d.ts.map +1 -1
  187. package/dist/collab/storage.js +5 -1
  188. package/dist/collab/storage.js.map +1 -1
  189. package/dist/collab/ydoc-manager.d.ts.map +1 -1
  190. package/dist/collab/ydoc-manager.js +35 -8
  191. package/dist/collab/ydoc-manager.js.map +1 -1
  192. package/dist/deploy/build.js +0 -5
  193. package/dist/deploy/build.js.map +1 -1
  194. package/dist/extensions/content-patch.js +1 -1
  195. package/dist/extensions/content-patch.js.map +1 -1
  196. package/dist/extensions/fetch-tool.d.ts.map +1 -1
  197. package/dist/extensions/fetch-tool.js +4 -1
  198. package/dist/extensions/fetch-tool.js.map +1 -1
  199. package/dist/extensions/routes.js +12 -12
  200. package/dist/extensions/routes.js.map +1 -1
  201. package/dist/extensions/slots/store.d.ts.map +1 -1
  202. package/dist/extensions/slots/store.js +5 -1
  203. package/dist/extensions/slots/store.js.map +1 -1
  204. package/dist/file-upload/actions/upload-image.d.ts.map +1 -1
  205. package/dist/file-upload/actions/upload-image.js +39 -4
  206. package/dist/file-upload/actions/upload-image.js.map +1 -1
  207. package/dist/integrations/a2a-continuations-store.d.ts.map +1 -1
  208. package/dist/integrations/a2a-continuations-store.js +5 -1
  209. package/dist/integrations/a2a-continuations-store.js.map +1 -1
  210. package/dist/integrations/adapters/email.d.ts.map +1 -1
  211. package/dist/integrations/adapters/email.js +5 -2
  212. package/dist/integrations/adapters/email.js.map +1 -1
  213. package/dist/integrations/adapters/slack.d.ts.map +1 -1
  214. package/dist/integrations/adapters/slack.js.map +1 -1
  215. package/dist/integrations/google-docs-poller.d.ts.map +1 -1
  216. package/dist/integrations/google-docs-poller.js +16 -5
  217. package/dist/integrations/google-docs-poller.js.map +1 -1
  218. package/dist/integrations/pending-tasks-retry-job.d.ts.map +1 -1
  219. package/dist/integrations/pending-tasks-retry-job.js +6 -2
  220. package/dist/integrations/pending-tasks-retry-job.js.map +1 -1
  221. package/dist/integrations/pending-tasks-store.d.ts.map +1 -1
  222. package/dist/integrations/pending-tasks-store.js +5 -1
  223. package/dist/integrations/pending-tasks-store.js.map +1 -1
  224. package/dist/integrations/plugin.d.ts.map +1 -1
  225. package/dist/integrations/plugin.js +14 -3
  226. package/dist/integrations/plugin.js.map +1 -1
  227. package/dist/integrations/remote-commands-store.d.ts.map +1 -1
  228. package/dist/integrations/remote-commands-store.js +5 -1
  229. package/dist/integrations/remote-commands-store.js.map +1 -1
  230. package/dist/integrations/remote-devices-store.d.ts.map +1 -1
  231. package/dist/integrations/remote-devices-store.js +5 -1
  232. package/dist/integrations/remote-devices-store.js.map +1 -1
  233. package/dist/integrations/remote-push-store.d.ts.map +1 -1
  234. package/dist/integrations/remote-push-store.js +5 -1
  235. package/dist/integrations/remote-push-store.js.map +1 -1
  236. package/dist/integrations/remote-retry-job.js +1 -1
  237. package/dist/integrations/remote-retry-job.js.map +1 -1
  238. package/dist/integrations/remote-run-events-store.d.ts.map +1 -1
  239. package/dist/integrations/remote-run-events-store.js +5 -1
  240. package/dist/integrations/remote-run-events-store.js.map +1 -1
  241. package/dist/integrations/thread-mapping-store.d.ts.map +1 -1
  242. package/dist/integrations/thread-mapping-store.js +5 -1
  243. package/dist/integrations/thread-mapping-store.js.map +1 -1
  244. package/dist/integrations/webhook-handler.d.ts.map +1 -1
  245. package/dist/integrations/webhook-handler.js +10 -1
  246. package/dist/integrations/webhook-handler.js.map +1 -1
  247. package/dist/jobs/scheduler.d.ts.map +1 -1
  248. package/dist/jobs/scheduler.js +31 -15
  249. package/dist/jobs/scheduler.js.map +1 -1
  250. package/dist/jobs/tools.d.ts.map +1 -1
  251. package/dist/jobs/tools.js +4 -1
  252. package/dist/jobs/tools.js.map +1 -1
  253. package/dist/mcp/build-server.d.ts.map +1 -1
  254. package/dist/mcp/build-server.js +24 -9
  255. package/dist/mcp/build-server.js.map +1 -1
  256. package/dist/mcp/connect-store.d.ts +3 -4
  257. package/dist/mcp/connect-store.d.ts.map +1 -1
  258. package/dist/mcp/connect-store.js +5 -5
  259. package/dist/mcp/connect-store.js.map +1 -1
  260. package/dist/mcp-client/routes.js +6 -1
  261. package/dist/mcp-client/routes.js.map +1 -1
  262. package/dist/notifications/channels.d.ts.map +1 -1
  263. package/dist/notifications/channels.js +3 -2
  264. package/dist/notifications/channels.js.map +1 -1
  265. package/dist/oauth-tokens/store.d.ts.map +1 -1
  266. package/dist/oauth-tokens/store.js +5 -1
  267. package/dist/oauth-tokens/store.js.map +1 -1
  268. package/dist/observability/evals.d.ts.map +1 -1
  269. package/dist/observability/evals.js +7 -7
  270. package/dist/observability/evals.js.map +1 -1
  271. package/dist/observability/traces.d.ts.map +1 -1
  272. package/dist/observability/traces.js +15 -5
  273. package/dist/observability/traces.js.map +1 -1
  274. package/dist/org/accept-pending.js +1 -1
  275. package/dist/org/accept-pending.js.map +1 -1
  276. package/dist/org/handlers.d.ts.map +1 -1
  277. package/dist/org/handlers.js +3 -2
  278. package/dist/org/handlers.js.map +1 -1
  279. package/dist/progress/store.d.ts.map +1 -1
  280. package/dist/progress/store.js +11 -1
  281. package/dist/progress/store.js.map +1 -1
  282. package/dist/resources/handlers.d.ts +5 -5
  283. package/dist/resources/handlers.d.ts.map +1 -1
  284. package/dist/resources/handlers.js +0 -2
  285. package/dist/resources/handlers.js.map +1 -1
  286. package/dist/resources/store.d.ts.map +1 -1
  287. package/dist/resources/store.js +23 -13
  288. package/dist/resources/store.js.map +1 -1
  289. package/dist/scripts/db/query.d.ts.map +1 -1
  290. package/dist/scripts/db/query.js +1 -2
  291. package/dist/scripts/db/query.js.map +1 -1
  292. package/dist/scripts/db/schema.js.map +1 -1
  293. package/dist/server/action-discovery.d.ts.map +1 -1
  294. package/dist/server/action-discovery.js +10 -3
  295. package/dist/server/action-discovery.js.map +1 -1
  296. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  297. package/dist/server/agent-chat-plugin.js +3 -6
  298. package/dist/server/agent-chat-plugin.js.map +1 -1
  299. package/dist/server/auth.d.ts.map +1 -1
  300. package/dist/server/auth.js +13 -9
  301. package/dist/server/auth.js.map +1 -1
  302. package/dist/server/better-auth-instance.d.ts.map +1 -1
  303. package/dist/server/better-auth-instance.js +0 -3
  304. package/dist/server/better-auth-instance.js.map +1 -1
  305. package/dist/server/core-routes-plugin.d.ts.map +1 -1
  306. package/dist/server/core-routes-plugin.js +1 -2
  307. package/dist/server/core-routes-plugin.js.map +1 -1
  308. package/dist/server/create-server.d.ts.map +1 -1
  309. package/dist/server/create-server.js +0 -23
  310. package/dist/server/create-server.js.map +1 -1
  311. package/dist/server/google-oauth.d.ts.map +1 -1
  312. package/dist/server/google-oauth.js +0 -3
  313. package/dist/server/google-oauth.js.map +1 -1
  314. package/dist/server/identity-sso-store.d.ts.map +1 -1
  315. package/dist/server/identity-sso-store.js +14 -3
  316. package/dist/server/identity-sso-store.js.map +1 -1
  317. package/dist/server/poll.d.ts.map +1 -1
  318. package/dist/server/poll.js +67 -18
  319. package/dist/server/poll.js.map +1 -1
  320. package/dist/server/schema-prompt.js +1 -1
  321. package/dist/server/schema-prompt.js.map +1 -1
  322. package/dist/server/security-headers.d.ts +5 -4
  323. package/dist/server/security-headers.d.ts.map +1 -1
  324. package/dist/server/security-headers.js +5 -4
  325. package/dist/server/security-headers.js.map +1 -1
  326. package/dist/settings/store.d.ts.map +1 -1
  327. package/dist/settings/store.js +5 -1
  328. package/dist/settings/store.js.map +1 -1
  329. package/dist/sharing/access.d.ts.map +1 -1
  330. package/dist/sharing/access.js +25 -4
  331. package/dist/sharing/access.js.map +1 -1
  332. package/dist/sharing/actions/set-resource-visibility.d.ts.map +1 -1
  333. package/dist/sharing/actions/set-resource-visibility.js +8 -1
  334. package/dist/sharing/actions/set-resource-visibility.js.map +1 -1
  335. package/dist/triggers/actions.d.ts.map +1 -1
  336. package/dist/triggers/actions.js +1 -2
  337. package/dist/triggers/actions.js.map +1 -1
  338. package/dist/triggers/dispatcher.d.ts.map +1 -1
  339. package/dist/triggers/dispatcher.js +36 -8
  340. package/dist/triggers/dispatcher.js.map +1 -1
  341. package/dist/usage/store.d.ts.map +1 -1
  342. package/dist/usage/store.js +5 -1
  343. package/dist/usage/store.js.map +1 -1
  344. package/dist/vite/client.d.ts.map +1 -1
  345. package/dist/vite/client.js +7 -5
  346. package/dist/vite/client.js.map +1 -1
  347. package/package.json +3 -2
  348. package/dist/client/conversation/AgentConversation.spec.d.ts +0 -2
  349. package/dist/client/conversation/AgentConversation.spec.d.ts.map +0 -1
  350. package/dist/client/conversation/AgentConversation.spec.js +0 -69
  351. package/dist/client/conversation/AgentConversation.spec.js.map +0 -1
  352. package/dist/client/extensions/AgentNativeExtensionFrame.e2e-host.d.ts +0 -2
  353. package/dist/client/extensions/AgentNativeExtensionFrame.e2e-host.d.ts.map +0 -1
  354. package/dist/client/extensions/AgentNativeExtensionFrame.e2e-host.js +0 -110
  355. package/dist/client/extensions/AgentNativeExtensionFrame.e2e-host.js.map +0 -1
  356. package/dist/client/extensions/AgentNativeExtensionFrame.spec.d.ts +0 -2
  357. package/dist/client/extensions/AgentNativeExtensionFrame.spec.d.ts.map +0 -1
  358. package/dist/client/extensions/AgentNativeExtensionFrame.spec.js +0 -68
  359. package/dist/client/extensions/AgentNativeExtensionFrame.spec.js.map +0 -1
  360. package/dist/client/extensions/ExtensionViewer.spec.d.ts +0 -2
  361. package/dist/client/extensions/ExtensionViewer.spec.d.ts.map +0 -1
  362. package/dist/client/extensions/ExtensionViewer.spec.js +0 -94
  363. package/dist/client/extensions/ExtensionViewer.spec.js.map +0 -1
  364. package/dist/client/guided-questions.flow.spec.d.ts +0 -2
  365. package/dist/client/guided-questions.flow.spec.d.ts.map +0 -1
  366. package/dist/client/guided-questions.flow.spec.js +0 -147
  367. package/dist/client/guided-questions.flow.spec.js.map +0 -1
  368. package/dist/client/settings/useBuilderStatus.spec.d.ts +0 -2
  369. package/dist/client/settings/useBuilderStatus.spec.d.ts.map +0 -1
  370. package/dist/client/settings/useBuilderStatus.spec.js +0 -487
  371. package/dist/client/settings/useBuilderStatus.spec.js.map +0 -1
  372. package/dist/client/sharing/ShareButton.spec.d.ts +0 -2
  373. package/dist/client/sharing/ShareButton.spec.d.ts.map +0 -1
  374. package/dist/client/sharing/ShareButton.spec.js +0 -196
  375. package/dist/client/sharing/ShareButton.spec.js.map +0 -1
  376. package/dist/client/use-chat-models.spec.d.ts +0 -2
  377. package/dist/client/use-chat-models.spec.d.ts.map +0 -1
  378. package/dist/client/use-chat-models.spec.js +0 -39
  379. package/dist/client/use-chat-models.spec.js.map +0 -1
  380. package/dist/client/use-chat-threads.spec.d.ts +0 -2
  381. package/dist/client/use-chat-threads.spec.d.ts.map +0 -1
  382. package/dist/client/use-chat-threads.spec.js +0 -760
  383. package/dist/client/use-chat-threads.spec.js.map +0 -1
  384. package/dist/client/use-db-sync.spec.d.ts +0 -2
  385. package/dist/client/use-db-sync.spec.d.ts.map +0 -1
  386. package/dist/client/use-db-sync.spec.js +0 -107
  387. package/dist/client/use-db-sync.spec.js.map +0 -1
  388. package/dist/server/script-discovery.d.ts +0 -6
  389. package/dist/server/script-discovery.d.ts.map +0 -1
  390. package/dist/server/script-discovery.js +0 -6
  391. package/dist/server/script-discovery.js.map +0 -1
@@ -1,62 +1,161 @@
1
1
  import { useCallback, useEffect, useRef, useState } from "react";
2
- export function useNearBottomAutoscroll({ followKey, streaming = false, threshold = 40, enabled = true, }) {
2
+ export function useNearBottomAutoscroll({ followKey, streaming = false, threshold = 4, enabled = true, }) {
3
3
  const scrollRef = useRef(null);
4
4
  const isNearBottomRef = useRef(true);
5
+ const followGenerationRef = useRef(0);
6
+ const lastScrollTopRef = useRef(0);
7
+ const lastTouchYRef = useRef(null);
5
8
  const [showScrollToBottom, setShowScrollToBottom] = useState(false);
6
- const updateNearBottom = useCallback(() => {
9
+ const isAtBottom = useCallback((el) => el.scrollHeight - el.scrollTop - el.clientHeight <= threshold, [threshold]);
10
+ const setFollowingBottom = useCallback((following, forceGeneration = false, el) => {
11
+ if (forceGeneration || isNearBottomRef.current !== following) {
12
+ followGenerationRef.current += 1;
13
+ }
14
+ isNearBottomRef.current = following;
15
+ const canScroll = !el || el.scrollHeight > el.clientHeight + threshold;
16
+ setShowScrollToBottom(!following && canScroll);
17
+ }, [threshold]);
18
+ const detachFromBottom = useCallback(() => {
19
+ setFollowingBottom(false, true, scrollRef.current ?? undefined);
20
+ }, [setFollowingBottom]);
21
+ const updateBottomState = useCallback(() => {
7
22
  const el = scrollRef.current;
8
23
  if (!el)
9
24
  return;
10
- const nearBottom = el.scrollHeight - el.scrollTop - el.clientHeight < threshold;
11
- isNearBottomRef.current = nearBottom;
12
- setShowScrollToBottom(!nearBottom);
13
- }, [threshold]);
25
+ if (isAtBottom(el))
26
+ setFollowingBottom(true, false, el);
27
+ else if (!isNearBottomRef.current) {
28
+ setShowScrollToBottom(el.scrollHeight > el.clientHeight + threshold);
29
+ }
30
+ }, [isAtBottom, setFollowingBottom, threshold]);
31
+ const scrollToBottomIfFollowing = useCallback((generation) => {
32
+ if (followGenerationRef.current !== generation ||
33
+ !isNearBottomRef.current) {
34
+ return;
35
+ }
36
+ const el = scrollRef.current;
37
+ if (!el)
38
+ return;
39
+ el.scrollTop = Math.max(0, el.scrollHeight - el.clientHeight);
40
+ lastScrollTopRef.current = el.scrollTop;
41
+ setFollowingBottom(true, false, el);
42
+ }, [setFollowingBottom]);
14
43
  const scrollToBottom = useCallback(() => {
15
44
  const el = scrollRef.current;
16
45
  if (!el)
17
46
  return;
18
- el.scrollTop = el.scrollHeight;
19
- isNearBottomRef.current = true;
20
- setShowScrollToBottom(false);
21
- }, []);
47
+ setFollowingBottom(true, true, el);
48
+ el.scrollTop = Math.max(0, el.scrollHeight - el.clientHeight);
49
+ lastScrollTopRef.current = el.scrollTop;
50
+ }, [setFollowingBottom]);
22
51
  useEffect(() => {
23
52
  const el = scrollRef.current;
24
53
  if (!el || !enabled)
25
54
  return;
26
- const onScroll = () => updateNearBottom();
55
+ lastScrollTopRef.current = el.scrollTop;
56
+ const onWheel = (event) => {
57
+ if (event.deltaY < 0)
58
+ detachFromBottom();
59
+ };
60
+ const onTouchStart = (event) => {
61
+ lastTouchYRef.current = event.touches[0]?.clientY ?? null;
62
+ };
63
+ const onTouchMove = (event) => {
64
+ const nextTouchY = event.touches[0]?.clientY;
65
+ if (nextTouchY == null)
66
+ return;
67
+ const lastTouchY = lastTouchYRef.current;
68
+ if (lastTouchY != null && nextTouchY > lastTouchY) {
69
+ detachFromBottom();
70
+ }
71
+ lastTouchYRef.current = nextTouchY;
72
+ };
73
+ const onTouchEnd = () => {
74
+ lastTouchYRef.current = null;
75
+ };
76
+ const onScroll = () => {
77
+ const previousScrollTop = lastScrollTopRef.current;
78
+ const nextScrollTop = el.scrollTop;
79
+ lastScrollTopRef.current = nextScrollTop;
80
+ if (nextScrollTop < previousScrollTop) {
81
+ detachFromBottom();
82
+ return;
83
+ }
84
+ updateBottomState();
85
+ };
86
+ const onKeyDown = (event) => {
87
+ if (event.key === "ArrowUp" ||
88
+ event.key === "PageUp" ||
89
+ event.key === "Home" ||
90
+ (event.key === " " && event.shiftKey)) {
91
+ detachFromBottom();
92
+ }
93
+ };
94
+ el.addEventListener("wheel", onWheel, { passive: true });
95
+ el.addEventListener("touchstart", onTouchStart, { passive: true });
96
+ el.addEventListener("touchmove", onTouchMove, { passive: true });
97
+ el.addEventListener("touchend", onTouchEnd, { passive: true });
98
+ el.addEventListener("touchcancel", onTouchEnd, { passive: true });
27
99
  el.addEventListener("scroll", onScroll, { passive: true });
28
- updateNearBottom();
100
+ el.addEventListener("keydown", onKeyDown);
101
+ updateBottomState();
29
102
  // Re-check near-bottom whenever the scroll container's content grows
30
103
  // (e.g. new messages appended, images loaded, tool-call details expanded).
31
104
  // Without this the "near bottom" flag can get stuck as `false` even though
32
105
  // the user never scrolled away — the container just grew taller.
33
- const ro = new ResizeObserver(() => {
34
- if (isNearBottomRef.current)
35
- scrollToBottom();
36
- else
37
- updateNearBottom();
38
- });
39
- ro.observe(el);
40
- // Also watch direct children so inline content changes are caught.
41
- for (const child of Array.from(el.children))
42
- ro.observe(child);
106
+ let ro = null;
107
+ let mo = null;
108
+ if (typeof ResizeObserver !== "undefined") {
109
+ const observeResizeTargets = () => {
110
+ ro?.disconnect();
111
+ ro = new ResizeObserver(() => {
112
+ if (isNearBottomRef.current) {
113
+ scrollToBottomIfFollowing(followGenerationRef.current);
114
+ }
115
+ else {
116
+ updateBottomState();
117
+ }
118
+ });
119
+ ro.observe(el);
120
+ // Also watch direct children so inline content changes are caught.
121
+ for (const child of Array.from(el.children))
122
+ ro.observe(child);
123
+ };
124
+ observeResizeTargets();
125
+ if (typeof MutationObserver !== "undefined") {
126
+ mo = new MutationObserver(() => {
127
+ observeResizeTargets();
128
+ if (isNearBottomRef.current) {
129
+ scrollToBottomIfFollowing(followGenerationRef.current);
130
+ }
131
+ });
132
+ mo.observe(el, { childList: true });
133
+ }
134
+ }
43
135
  return () => {
136
+ el.removeEventListener("wheel", onWheel);
137
+ el.removeEventListener("touchstart", onTouchStart);
138
+ el.removeEventListener("touchmove", onTouchMove);
139
+ el.removeEventListener("touchend", onTouchEnd);
140
+ el.removeEventListener("touchcancel", onTouchEnd);
44
141
  el.removeEventListener("scroll", onScroll);
45
- ro.disconnect();
142
+ el.removeEventListener("keydown", onKeyDown);
143
+ ro?.disconnect();
144
+ mo?.disconnect();
46
145
  };
47
- }, [enabled, updateNearBottom, scrollToBottom]);
146
+ }, [detachFromBottom, enabled, scrollToBottomIfFollowing, updateBottomState]);
48
147
  const scrollToBottomAfterPaint = useCallback(() => {
49
- scrollToBottom();
148
+ const generation = followGenerationRef.current;
149
+ scrollToBottomIfFollowing(generation);
50
150
  requestAnimationFrame(() => {
51
- scrollToBottom();
52
- requestAnimationFrame(scrollToBottom);
151
+ scrollToBottomIfFollowing(generation);
152
+ requestAnimationFrame(() => scrollToBottomIfFollowing(generation));
53
153
  });
54
- window.setTimeout(scrollToBottom, 80);
55
- }, [scrollToBottom]);
154
+ window.setTimeout(() => scrollToBottomIfFollowing(generation), 80);
155
+ }, [scrollToBottomIfFollowing]);
56
156
  const markNearBottom = useCallback(() => {
57
- isNearBottomRef.current = true;
58
- setShowScrollToBottom(false);
59
- }, []);
157
+ setFollowingBottom(true, true, scrollRef.current ?? undefined);
158
+ }, [setFollowingBottom]);
60
159
  useEffect(() => {
61
160
  if (!enabled || !isNearBottomRef.current)
62
161
  return;
@@ -66,11 +165,10 @@ export function useNearBottomAutoscroll({ followKey, streaming = false, threshol
66
165
  if (!enabled || !streaming)
67
166
  return;
68
167
  const id = window.setInterval(() => {
69
- if (isNearBottomRef.current)
70
- scrollToBottom();
168
+ scrollToBottomIfFollowing(followGenerationRef.current);
71
169
  }, 100);
72
170
  return () => window.clearInterval(id);
73
- }, [enabled, scrollToBottom, streaming]);
171
+ }, [enabled, scrollToBottomIfFollowing, streaming]);
74
172
  return {
75
173
  scrollRef,
76
174
  isNearBottomRef,
@@ -1 +1 @@
1
- {"version":3,"file":"use-near-bottom-autoscroll.js","sourceRoot":"","sources":["../../../src/client/conversation/use-near-bottom-autoscroll.ts"],"names":[],"mappings":"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","sourcesContent":["import { useCallback, useEffect, useRef, useState } from \"react\";\n\nexport interface UseNearBottomAutoscrollOptions {\n followKey: unknown;\n streaming?: boolean;\n threshold?: number;\n enabled?: boolean;\n}\n\nexport function useNearBottomAutoscroll<TElement extends HTMLElement>({\n followKey,\n streaming = false,\n threshold = 40,\n enabled = true,\n}: UseNearBottomAutoscrollOptions) {\n const scrollRef = useRef<TElement | null>(null);\n const isNearBottomRef = useRef(true);\n const [showScrollToBottom, setShowScrollToBottom] = useState(false);\n\n const updateNearBottom = useCallback(() => {\n const el = scrollRef.current;\n if (!el) return;\n const nearBottom =\n el.scrollHeight - el.scrollTop - el.clientHeight < threshold;\n isNearBottomRef.current = nearBottom;\n setShowScrollToBottom(!nearBottom);\n }, [threshold]);\n\n const scrollToBottom = useCallback(() => {\n const el = scrollRef.current;\n if (!el) return;\n el.scrollTop = el.scrollHeight;\n isNearBottomRef.current = true;\n setShowScrollToBottom(false);\n }, []);\n\n useEffect(() => {\n const el = scrollRef.current;\n if (!el || !enabled) return;\n const onScroll = () => updateNearBottom();\n el.addEventListener(\"scroll\", onScroll, { passive: true });\n updateNearBottom();\n\n // Re-check near-bottom whenever the scroll container's content grows\n // (e.g. new messages appended, images loaded, tool-call details expanded).\n // Without this the \"near bottom\" flag can get stuck as `false` even though\n // the user never scrolled away — the container just grew taller.\n const ro = new ResizeObserver(() => {\n if (isNearBottomRef.current) scrollToBottom();\n else updateNearBottom();\n });\n ro.observe(el);\n // Also watch direct children so inline content changes are caught.\n for (const child of Array.from(el.children)) ro.observe(child);\n\n return () => {\n el.removeEventListener(\"scroll\", onScroll);\n ro.disconnect();\n };\n }, [enabled, updateNearBottom, scrollToBottom]);\n\n const scrollToBottomAfterPaint = useCallback(() => {\n scrollToBottom();\n requestAnimationFrame(() => {\n scrollToBottom();\n requestAnimationFrame(scrollToBottom);\n });\n window.setTimeout(scrollToBottom, 80);\n }, [scrollToBottom]);\n\n const markNearBottom = useCallback(() => {\n isNearBottomRef.current = true;\n setShowScrollToBottom(false);\n }, []);\n\n useEffect(() => {\n if (!enabled || !isNearBottomRef.current) return;\n scrollToBottomAfterPaint();\n }, [enabled, followKey, scrollToBottomAfterPaint]);\n\n useEffect(() => {\n if (!enabled || !streaming) return;\n const id = window.setInterval(() => {\n if (isNearBottomRef.current) scrollToBottom();\n }, 100);\n return () => window.clearInterval(id);\n }, [enabled, scrollToBottom, streaming]);\n\n return {\n scrollRef,\n isNearBottomRef,\n showScrollToBottom,\n markNearBottom,\n scrollToBottom,\n scrollToBottomAfterPaint,\n };\n}\n"]}
1
+ {"version":3,"file":"use-near-bottom-autoscroll.js","sourceRoot":"","sources":["../../../src/client/conversation/use-near-bottom-autoscroll.ts"],"names":[],"mappings":"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","sourcesContent":["import { useCallback, useEffect, useRef, useState } from \"react\";\n\nexport interface UseNearBottomAutoscrollOptions {\n followKey: unknown;\n streaming?: boolean;\n threshold?: number;\n enabled?: boolean;\n}\n\nexport function useNearBottomAutoscroll<TElement extends HTMLElement>({\n followKey,\n streaming = false,\n threshold = 4,\n enabled = true,\n}: UseNearBottomAutoscrollOptions) {\n const scrollRef = useRef<TElement | null>(null);\n const isNearBottomRef = useRef(true);\n const followGenerationRef = useRef(0);\n const lastScrollTopRef = useRef(0);\n const lastTouchYRef = useRef<number | null>(null);\n const [showScrollToBottom, setShowScrollToBottom] = useState(false);\n\n const isAtBottom = useCallback(\n (el: HTMLElement) =>\n el.scrollHeight - el.scrollTop - el.clientHeight <= threshold,\n [threshold],\n );\n\n const setFollowingBottom = useCallback(\n (following: boolean, forceGeneration = false, el?: HTMLElement) => {\n if (forceGeneration || isNearBottomRef.current !== following) {\n followGenerationRef.current += 1;\n }\n isNearBottomRef.current = following;\n const canScroll = !el || el.scrollHeight > el.clientHeight + threshold;\n setShowScrollToBottom(!following && canScroll);\n },\n [threshold],\n );\n\n const detachFromBottom = useCallback(() => {\n setFollowingBottom(false, true, scrollRef.current ?? undefined);\n }, [setFollowingBottom]);\n\n const updateBottomState = useCallback(() => {\n const el = scrollRef.current;\n if (!el) return;\n if (isAtBottom(el)) setFollowingBottom(true, false, el);\n else if (!isNearBottomRef.current) {\n setShowScrollToBottom(el.scrollHeight > el.clientHeight + threshold);\n }\n }, [isAtBottom, setFollowingBottom, threshold]);\n\n const scrollToBottomIfFollowing = useCallback(\n (generation: number) => {\n if (\n followGenerationRef.current !== generation ||\n !isNearBottomRef.current\n ) {\n return;\n }\n const el = scrollRef.current;\n if (!el) return;\n el.scrollTop = Math.max(0, el.scrollHeight - el.clientHeight);\n lastScrollTopRef.current = el.scrollTop;\n setFollowingBottom(true, false, el);\n },\n [setFollowingBottom],\n );\n\n const scrollToBottom = useCallback(() => {\n const el = scrollRef.current;\n if (!el) return;\n setFollowingBottom(true, true, el);\n el.scrollTop = Math.max(0, el.scrollHeight - el.clientHeight);\n lastScrollTopRef.current = el.scrollTop;\n }, [setFollowingBottom]);\n\n useEffect(() => {\n const el = scrollRef.current;\n if (!el || !enabled) return;\n lastScrollTopRef.current = el.scrollTop;\n\n const onWheel = (event: WheelEvent) => {\n if (event.deltaY < 0) detachFromBottom();\n };\n\n const onTouchStart = (event: TouchEvent) => {\n lastTouchYRef.current = event.touches[0]?.clientY ?? null;\n };\n\n const onTouchMove = (event: TouchEvent) => {\n const nextTouchY = event.touches[0]?.clientY;\n if (nextTouchY == null) return;\n const lastTouchY = lastTouchYRef.current;\n if (lastTouchY != null && nextTouchY > lastTouchY) {\n detachFromBottom();\n }\n lastTouchYRef.current = nextTouchY;\n };\n\n const onTouchEnd = () => {\n lastTouchYRef.current = null;\n };\n\n const onScroll = () => {\n const previousScrollTop = lastScrollTopRef.current;\n const nextScrollTop = el.scrollTop;\n lastScrollTopRef.current = nextScrollTop;\n if (nextScrollTop < previousScrollTop) {\n detachFromBottom();\n return;\n }\n updateBottomState();\n };\n const onKeyDown = (event: KeyboardEvent) => {\n if (\n event.key === \"ArrowUp\" ||\n event.key === \"PageUp\" ||\n event.key === \"Home\" ||\n (event.key === \" \" && event.shiftKey)\n ) {\n detachFromBottom();\n }\n };\n el.addEventListener(\"wheel\", onWheel, { passive: true });\n el.addEventListener(\"touchstart\", onTouchStart, { passive: true });\n el.addEventListener(\"touchmove\", onTouchMove, { passive: true });\n el.addEventListener(\"touchend\", onTouchEnd, { passive: true });\n el.addEventListener(\"touchcancel\", onTouchEnd, { passive: true });\n el.addEventListener(\"scroll\", onScroll, { passive: true });\n el.addEventListener(\"keydown\", onKeyDown);\n updateBottomState();\n\n // Re-check near-bottom whenever the scroll container's content grows\n // (e.g. new messages appended, images loaded, tool-call details expanded).\n // Without this the \"near bottom\" flag can get stuck as `false` even though\n // the user never scrolled away — the container just grew taller.\n let ro: ResizeObserver | null = null;\n let mo: MutationObserver | null = null;\n if (typeof ResizeObserver !== \"undefined\") {\n const observeResizeTargets = () => {\n ro?.disconnect();\n ro = new ResizeObserver(() => {\n if (isNearBottomRef.current) {\n scrollToBottomIfFollowing(followGenerationRef.current);\n } else {\n updateBottomState();\n }\n });\n ro.observe(el);\n // Also watch direct children so inline content changes are caught.\n for (const child of Array.from(el.children)) ro.observe(child);\n };\n observeResizeTargets();\n if (typeof MutationObserver !== \"undefined\") {\n mo = new MutationObserver(() => {\n observeResizeTargets();\n if (isNearBottomRef.current) {\n scrollToBottomIfFollowing(followGenerationRef.current);\n }\n });\n mo.observe(el, { childList: true });\n }\n }\n\n return () => {\n el.removeEventListener(\"wheel\", onWheel);\n el.removeEventListener(\"touchstart\", onTouchStart);\n el.removeEventListener(\"touchmove\", onTouchMove);\n el.removeEventListener(\"touchend\", onTouchEnd);\n el.removeEventListener(\"touchcancel\", onTouchEnd);\n el.removeEventListener(\"scroll\", onScroll);\n el.removeEventListener(\"keydown\", onKeyDown);\n ro?.disconnect();\n mo?.disconnect();\n };\n }, [detachFromBottom, enabled, scrollToBottomIfFollowing, updateBottomState]);\n\n const scrollToBottomAfterPaint = useCallback(() => {\n const generation = followGenerationRef.current;\n scrollToBottomIfFollowing(generation);\n requestAnimationFrame(() => {\n scrollToBottomIfFollowing(generation);\n requestAnimationFrame(() => scrollToBottomIfFollowing(generation));\n });\n window.setTimeout(() => scrollToBottomIfFollowing(generation), 80);\n }, [scrollToBottomIfFollowing]);\n\n const markNearBottom = useCallback(() => {\n setFollowingBottom(true, true, scrollRef.current ?? undefined);\n }, [setFollowingBottom]);\n\n useEffect(() => {\n if (!enabled || !isNearBottomRef.current) return;\n scrollToBottomAfterPaint();\n }, [enabled, followKey, scrollToBottomAfterPaint]);\n\n useEffect(() => {\n if (!enabled || !streaming) return;\n const id = window.setInterval(() => {\n scrollToBottomIfFollowing(followGenerationRef.current);\n }, 100);\n return () => window.clearInterval(id);\n }, [enabled, scrollToBottomIfFollowing, streaming]);\n\n return {\n scrollRef,\n isNearBottomRef,\n showScrollToBottom,\n markNearBottom,\n scrollToBottom,\n scrollToBottomAfterPaint,\n };\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"DbAdminPage.js","sourceRoot":"","sources":["../../../src/client/db-admin/DbAdminPage.tsx"],"names":[],"mappings":"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","sourcesContent":["/**\n * Code-mode database admin page — the shell that hosts the table browser, the\n * table editor, and the SQL editor.\n *\n * Gated to Code mode: when the app cannot toggle into Code mode\n * (`canToggle` is false) we render a clean notice instead of the tool. The\n * backend also enforces this with a 403, so this is purely a friendlier UX.\n */\nimport { useEffect, useMemo, useState } from \"react\";\nimport { IconDatabase, IconLoader2 } from \"@tabler/icons-react\";\nimport { cn } from \"../utils.js\";\nimport { useCodeMode } from \"../use-dev-mode.js\";\nimport type { DbAdminFilter, DbAdminColumn } from \"../../db-admin/types.js\";\nimport { useOverview } from \"./useDbAdmin.js\";\nimport { TableBrowser } from \"./TableBrowser.js\";\nimport { useDbAdminAgentSync, useNavigateConsumer } from \"./useAgentSync.js\";\nimport { TableEditor } from \"./TableEditor.js\";\nimport { SqlEditor } from \"./SqlEditor.js\";\n\nconst DIALECT_LABEL: Record<string, string> = {\n postgres: \"Postgres\",\n sqlite: \"SQLite\",\n d1: \"Cloudflare D1\",\n};\n\nexport function DbAdminPage() {\n const { canToggle, isLoading: devLoading } = useCodeMode();\n const { data: overview, isLoading: overviewLoading } = useOverview();\n\n const [selectedTable, setSelectedTable] = useState<string | null>(null);\n const [mode, setMode] = useState<\"table\" | \"sql\">(\"table\");\n const [fkFilters, setFkFilters] = useState<DbAdminFilter[] | undefined>(\n undefined,\n );\n\n const tables = overview?.tables ?? [];\n const dialect = overview?.dialect ?? \"sqlite\";\n\n // Default selection to the first table once the overview loads.\n useEffect(() => {\n if (selectedTable === null && tables.length > 0) {\n setSelectedTable(tables[0].name);\n }\n }, [selectedTable, tables]);\n\n // Keep the agent's <current-screen> in sync, and let it drive navigation.\n useDbAdminAgentSync({ table: selectedTable, mode });\n useNavigateConsumer((table) => {\n setSelectedTable(table);\n setMode(\"table\");\n setFkFilters(undefined);\n });\n\n const tableNames = useMemo(() => tables.map((t) => t.name), [tables]);\n // SqlEditor degrades gracefully without per-table columns; pass an empty map.\n // (Table-name autocomplete still works; column autocomplete fills in lazily.)\n const columnsByTable = useMemo<Record<string, string[]>>(() => ({}), []);\n\n // ─── Code mode gate ──────────────────────────────────────────────────────\n if (!devLoading && !canToggle) {\n return (\n <div className=\"flex h-full w-full items-center justify-center bg-background p-6\">\n <div className=\"flex max-w-md flex-col items-center rounded-lg border bg-card p-8 text-center shadow-sm\">\n <div className=\"mb-4 flex h-12 w-12 items-center justify-center rounded-full bg-muted\">\n <IconDatabase\n className=\"h-6 w-6 text-muted-foreground\"\n stroke={1.75}\n />\n </div>\n <h2 className=\"text-base font-semibold text-foreground\">\n Code mode only\n </h2>\n <p className=\"mt-1.5 text-sm text-muted-foreground\">\n Database admin is available in Code mode only.\n </p>\n </div>\n </div>\n );\n }\n\n const showInitialLoading = (devLoading || overviewLoading) && !overview;\n\n return (\n <div className=\"flex h-full w-full flex-col bg-background text-foreground\">\n {/* Header */}\n <header className=\"flex h-12 shrink-0 items-center gap-3 border-b px-4\">\n <IconDatabase className=\"h-5 w-5 text-muted-foreground\" stroke={1.75} />\n <span className=\"text-sm font-semibold\">Database</span>\n <span className=\"inline-flex items-center rounded-full border bg-muted px-2 py-0.5 text-xs font-medium text-muted-foreground\">\n {DIALECT_LABEL[dialect] ?? dialect}\n </span>\n <span className=\"text-xs text-muted-foreground\">\n {tables.length} {tables.length === 1 ? \"table\" : \"tables\"}\n </span>\n </header>\n\n {/* Body: fixed sidebar + flexible main */}\n <div className=\"flex min-h-0 flex-1\">\n <aside className=\"w-[260px] shrink-0 border-r\">\n {showInitialLoading ? (\n <SidebarSkeleton />\n ) : (\n <TableBrowser\n tables={tables}\n selected={selectedTable}\n onSelect={(t) => {\n setSelectedTable(t);\n setFkFilters(undefined);\n }}\n mode={mode}\n onModeChange={setMode}\n />\n )}\n </aside>\n\n <main className=\"min-w-0 flex-1 overflow-hidden\">\n {showInitialLoading ? (\n <MainLoading />\n ) : mode === \"sql\" ? (\n <SqlEditor\n dialect={dialect}\n tableNames={tableNames}\n columnsByTable={columnsByTable}\n />\n ) : selectedTable ? (\n <TableEditor\n key={selectedTable}\n table={selectedTable}\n dialect={dialect}\n initialFilters={fkFilters}\n onNavigateToRow={(t, filters) => {\n setSelectedTable(t);\n setMode(\"table\");\n setFkFilters(filters);\n }}\n />\n ) : (\n <NoTableSelected />\n )}\n </main>\n </div>\n </div>\n );\n}\n\nfunction SidebarSkeleton() {\n return (\n <div className=\"flex h-full flex-col bg-card p-2\">\n <div className=\"mb-2 h-9 animate-pulse rounded-md bg-muted\" />\n <div className=\"mb-3 h-9 animate-pulse rounded-md bg-muted\" />\n <div className=\"space-y-1.5\">\n {Array.from({ length: 8 }).map((_, i) => (\n <div\n key={i}\n className=\"h-8 animate-pulse rounded-md bg-muted\"\n style={{ opacity: 1 - i * 0.08 }}\n />\n ))}\n </div>\n </div>\n );\n}\n\nfunction MainLoading() {\n return (\n <div className=\"flex h-full w-full items-center justify-center\">\n <IconLoader2\n className={cn(\"h-5 w-5 animate-spin text-muted-foreground\")}\n />\n </div>\n );\n}\n\nfunction NoTableSelected() {\n return (\n <div className=\"flex h-full w-full items-center justify-center p-6 text-center\">\n <div className=\"flex flex-col items-center\">\n <IconDatabase\n className=\"mb-3 h-8 w-8 text-muted-foreground/50\"\n stroke={1.5}\n />\n <p className=\"text-sm font-medium text-foreground\">No table selected</p>\n <p className=\"mt-1 text-sm text-muted-foreground\">\n Pick a table from the sidebar to browse and edit its rows.\n </p>\n </div>\n </div>\n );\n}\n"]}
1
+ {"version":3,"file":"DbAdminPage.js","sourceRoot":"","sources":["../../../src/client/db-admin/DbAdminPage.tsx"],"names":[],"mappings":"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","sourcesContent":["/**\n * Code-mode database admin page — the shell that hosts the table browser, the\n * table editor, and the SQL editor.\n *\n * Gated to Code mode: when the app cannot toggle into Code mode\n * (`canToggle` is false) we render a clean notice instead of the tool. The\n * backend also enforces this with a 403, so this is purely a friendlier UX.\n */\nimport { useEffect, useMemo, useState } from \"react\";\nimport { IconDatabase, IconLoader2 } from \"@tabler/icons-react\";\nimport { cn } from \"../utils.js\";\nimport { useCodeMode } from \"../use-dev-mode.js\";\nimport type { DbAdminFilter } from \"../../db-admin/types.js\";\nimport { useOverview } from \"./useDbAdmin.js\";\nimport { TableBrowser } from \"./TableBrowser.js\";\nimport { useDbAdminAgentSync, useNavigateConsumer } from \"./useAgentSync.js\";\nimport { TableEditor } from \"./TableEditor.js\";\nimport { SqlEditor } from \"./SqlEditor.js\";\n\nconst DIALECT_LABEL: Record<string, string> = {\n postgres: \"Postgres\",\n sqlite: \"SQLite\",\n d1: \"Cloudflare D1\",\n};\n\nexport function DbAdminPage() {\n const { canToggle, isLoading: devLoading } = useCodeMode();\n const { data: overview, isLoading: overviewLoading } = useOverview();\n\n const [selectedTable, setSelectedTable] = useState<string | null>(null);\n const [mode, setMode] = useState<\"table\" | \"sql\">(\"table\");\n const [fkFilters, setFkFilters] = useState<DbAdminFilter[] | undefined>(\n undefined,\n );\n\n const tables = overview?.tables ?? [];\n const dialect = overview?.dialect ?? \"sqlite\";\n\n // Default selection to the first table once the overview loads.\n useEffect(() => {\n if (selectedTable === null && tables.length > 0) {\n setSelectedTable(tables[0].name);\n }\n }, [selectedTable, tables]);\n\n // Keep the agent's <current-screen> in sync, and let it drive navigation.\n useDbAdminAgentSync({ table: selectedTable, mode });\n useNavigateConsumer((table) => {\n setSelectedTable(table);\n setMode(\"table\");\n setFkFilters(undefined);\n });\n\n const tableNames = useMemo(() => tables.map((t) => t.name), [tables]);\n // SqlEditor degrades gracefully without per-table columns; pass an empty map.\n // (Table-name autocomplete still works; column autocomplete fills in lazily.)\n const columnsByTable = useMemo<Record<string, string[]>>(() => ({}), []);\n\n // ─── Code mode gate ──────────────────────────────────────────────────────\n if (!devLoading && !canToggle) {\n return (\n <div className=\"flex h-full w-full items-center justify-center bg-background p-6\">\n <div className=\"flex max-w-md flex-col items-center rounded-lg border bg-card p-8 text-center shadow-sm\">\n <div className=\"mb-4 flex h-12 w-12 items-center justify-center rounded-full bg-muted\">\n <IconDatabase\n className=\"h-6 w-6 text-muted-foreground\"\n stroke={1.75}\n />\n </div>\n <h2 className=\"text-base font-semibold text-foreground\">\n Code mode only\n </h2>\n <p className=\"mt-1.5 text-sm text-muted-foreground\">\n Database admin is available in Code mode only.\n </p>\n </div>\n </div>\n );\n }\n\n const showInitialLoading = (devLoading || overviewLoading) && !overview;\n\n return (\n <div className=\"flex h-full w-full flex-col bg-background text-foreground\">\n {/* Header */}\n <header className=\"flex h-12 shrink-0 items-center gap-3 border-b px-4\">\n <IconDatabase className=\"h-5 w-5 text-muted-foreground\" stroke={1.75} />\n <span className=\"text-sm font-semibold\">Database</span>\n <span className=\"inline-flex items-center rounded-full border bg-muted px-2 py-0.5 text-xs font-medium text-muted-foreground\">\n {DIALECT_LABEL[dialect] ?? dialect}\n </span>\n <span className=\"text-xs text-muted-foreground\">\n {tables.length} {tables.length === 1 ? \"table\" : \"tables\"}\n </span>\n </header>\n\n {/* Body: fixed sidebar + flexible main */}\n <div className=\"flex min-h-0 flex-1\">\n <aside className=\"w-[260px] shrink-0 border-r\">\n {showInitialLoading ? (\n <SidebarSkeleton />\n ) : (\n <TableBrowser\n tables={tables}\n selected={selectedTable}\n onSelect={(t) => {\n setSelectedTable(t);\n setFkFilters(undefined);\n }}\n mode={mode}\n onModeChange={setMode}\n />\n )}\n </aside>\n\n <main className=\"min-w-0 flex-1 overflow-hidden\">\n {showInitialLoading ? (\n <MainLoading />\n ) : mode === \"sql\" ? (\n <SqlEditor\n dialect={dialect}\n tableNames={tableNames}\n columnsByTable={columnsByTable}\n />\n ) : selectedTable ? (\n <TableEditor\n key={selectedTable}\n table={selectedTable}\n dialect={dialect}\n initialFilters={fkFilters}\n onNavigateToRow={(t, filters) => {\n setSelectedTable(t);\n setMode(\"table\");\n setFkFilters(filters);\n }}\n />\n ) : (\n <NoTableSelected />\n )}\n </main>\n </div>\n </div>\n );\n}\n\nfunction SidebarSkeleton() {\n return (\n <div className=\"flex h-full flex-col bg-card p-2\">\n <div className=\"mb-2 h-9 animate-pulse rounded-md bg-muted\" />\n <div className=\"mb-3 h-9 animate-pulse rounded-md bg-muted\" />\n <div className=\"space-y-1.5\">\n {Array.from({ length: 8 }).map((_, i) => (\n <div\n key={i}\n className=\"h-8 animate-pulse rounded-md bg-muted\"\n style={{ opacity: 1 - i * 0.08 }}\n />\n ))}\n </div>\n </div>\n );\n}\n\nfunction MainLoading() {\n return (\n <div className=\"flex h-full w-full items-center justify-center\">\n <IconLoader2\n className={cn(\"h-5 w-5 animate-spin text-muted-foreground\")}\n />\n </div>\n );\n}\n\nfunction NoTableSelected() {\n return (\n <div className=\"flex h-full w-full items-center justify-center p-6 text-center\">\n <div className=\"flex flex-col items-center\">\n <IconDatabase\n className=\"mb-3 h-8 w-8 text-muted-foreground/50\"\n stroke={1.5}\n />\n <p className=\"text-sm font-medium text-foreground\">No table selected</p>\n <p className=\"mt-1 text-sm text-muted-foreground\">\n Pick a table from the sidebar to browse and edit its rows.\n </p>\n </div>\n </div>\n );\n}\n"]}
@@ -74,7 +74,7 @@ function InlineTextEditor({ kind, value, nullable, onCommit, onCancel, onNavigat
74
74
  setError(err instanceof ParseError ? err.message : String(err));
75
75
  }
76
76
  };
77
- return (_jsxs("div", { className: "relative h-full w-full", children: [_jsx("input", { ref: ref, type: kind === "number" ? "text" : "text", inputMode: kind === "number" ? "decimal" : undefined, value: text, onChange: (e) => setText(e.target.value), onBlur: () => commit(), onKeyDown: (e) => {
77
+ return (_jsxs("div", { className: "relative h-full w-full", children: [_jsx("input", { ref: ref, type: "text", inputMode: kind === "number" ? "decimal" : undefined, value: text, onChange: (e) => setText(e.target.value), onBlur: () => commit(), onKeyDown: (e) => {
78
78
  if (e.key === "Enter") {
79
79
  e.preventDefault();
80
80
  commit("down");
@@ -1 +1 @@
1
- {"version":3,"file":"EditableCell.js","sourceRoot":"","sources":["../../../src/client/db-admin/EditableCell.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useEffect, useRef, useState } from \"react\";\nimport {\n IconChevronDown,\n IconCircleX,\n IconMaximize,\n} from \"@tabler/icons-react\";\nimport { cn } from \"../utils.js\";\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from \"../components/ui/popover.js\";\nimport {\n type EditorKind,\n formatCellValue,\n inferEnumValues,\n valueToEditString,\n parseEditValue,\n ParseError,\n cycleTriStateBoolean,\n formatJsonPretty,\n} from \"./cell-format.js\";\nimport type { DbAdminColumn } from \"../../db-admin/types.js\";\n\nexport interface EditableCellProps {\n column: DbAdminColumn;\n kind: EditorKind;\n value: unknown;\n /** Whether this cell holds a staged (uncommitted) edit. */\n dirty?: boolean;\n /** Whether editing is allowed (false when the table has no PK). */\n editable?: boolean;\n /** Whether this cell is the keyboard-focused/active cell in the grid. */\n active?: boolean;\n /** True if the editor should open immediately (e.g. typing began). */\n editing?: boolean;\n /** Commit a new value into the changeset. */\n onCommit: (value: unknown) => void;\n /** Request entering edit mode. */\n onStartEdit?: () => void;\n /** Request leaving edit mode without committing. */\n onCancelEdit?: () => void;\n /** Move focus after Enter (\"down\") or Tab (\"right\"). */\n onNavigate?: (dir: \"up\" | \"down\" | \"left\" | \"right\") => void;\n className?: string;\n}\n\nconst NULL_TOKEN = (\n <span className=\"italic text-muted-foreground/60 select-none\">NULL</span>\n);\n\nexport function EditableCell({\n column,\n kind,\n value,\n dirty,\n editable = true,\n active,\n editing,\n onCommit,\n onStartEdit,\n onCancelEdit,\n onNavigate,\n className,\n}: EditableCellProps) {\n const display = formatCellValue(value, kind);\n\n // Boolean cells toggle in place rather than opening a text editor.\n if (kind === \"boolean\") {\n return (\n <BooleanCell\n value={value}\n dirty={dirty}\n editable={editable}\n active={active}\n onCommit={onCommit}\n onNavigate={onNavigate}\n className={className}\n />\n );\n }\n\n const baseCell = cn(\n \"relative h-full w-full px-2 py-1 text-xs truncate outline-none\",\n \"font-mono\",\n active && \"ring-1 ring-inset ring-ring\",\n dirty && \"bg-amber-500/10 ring-1 ring-inset ring-amber-500/50\",\n editable && \"cursor-text\",\n className,\n );\n\n if (editing && editable) {\n if (kind === \"enum\") {\n return (\n <EnumEditor\n column={column}\n value={value}\n onCommit={onCommit}\n onCancel={onCancelEdit}\n onNavigate={onNavigate}\n />\n );\n }\n if (kind === \"json\") {\n return (\n <JsonEditor value={value} onCommit={onCommit} onCancel={onCancelEdit} />\n );\n }\n return (\n <InlineTextEditor\n kind={kind}\n value={value}\n nullable={column.nullable}\n onCommit={onCommit}\n onCancel={onCancelEdit}\n onNavigate={onNavigate}\n />\n );\n }\n\n return (\n <div\n role=\"gridcell\"\n tabIndex={active ? 0 : -1}\n className={baseCell}\n onDoubleClick={() => editable && onStartEdit?.()}\n onKeyDown={(e) => {\n if (!editable) return;\n if (e.key === \"Enter\" || e.key === \"F2\") {\n e.preventDefault();\n onStartEdit?.();\n }\n }}\n title={display.isNull ? \"NULL\" : display.text}\n >\n <div className=\"flex items-center gap-1\">\n <span className=\"truncate\">\n {display.isNull ? NULL_TOKEN : display.text}\n </span>\n {editable && (kind === \"json\" || kind === \"text\") && (\n <button\n type=\"button\"\n tabIndex={-1}\n onClick={(e) => {\n e.stopPropagation();\n onStartEdit?.();\n }}\n className=\"ml-auto shrink-0 text-muted-foreground/50 opacity-0 hover:text-foreground group-hover:opacity-100\"\n aria-label=\"Expand editor\"\n >\n <IconMaximize className=\"h-3 w-3\" />\n </button>\n )}\n </div>\n </div>\n );\n}\n\n// ─── Boolean (tri-state) ─────────────────────────────────────────────────────\n\nfunction BooleanCell({\n value,\n dirty,\n editable,\n active,\n onCommit,\n onNavigate,\n className,\n}: {\n value: unknown;\n dirty?: boolean;\n editable: boolean;\n active?: boolean;\n onCommit: (v: unknown) => void;\n onNavigate?: (dir: \"up\" | \"down\" | \"left\" | \"right\") => void;\n className?: string;\n}) {\n const label = value === true ? \"true\" : value === false ? \"false\" : null;\n return (\n <div\n role=\"gridcell\"\n tabIndex={active ? 0 : -1}\n className={cn(\n \"h-full w-full px-2 py-1 text-xs font-mono outline-none cursor-pointer select-none\",\n active && \"ring-1 ring-inset ring-ring\",\n dirty && \"bg-amber-500/10 ring-1 ring-inset ring-amber-500/50\",\n className,\n )}\n onClick={() => editable && onCommit(cycleTriStateBoolean(value))}\n onKeyDown={(e) => {\n if (!editable) return;\n if (e.key === \" \" || e.key === \"Enter\") {\n e.preventDefault();\n onCommit(cycleTriStateBoolean(value));\n } else if (e.key === \"ArrowDown\") {\n e.preventDefault();\n onNavigate?.(\"down\");\n } else if (e.key === \"ArrowUp\") {\n e.preventDefault();\n onNavigate?.(\"up\");\n }\n }}\n >\n {label === null ? NULL_TOKEN : label}\n </div>\n );\n}\n\n// ─── Inline text / number / timestamp / uuid editor ──────────────────────────\n\nfunction InlineTextEditor({\n kind,\n value,\n nullable,\n onCommit,\n onCancel,\n onNavigate,\n}: {\n kind: EditorKind;\n value: unknown;\n nullable: boolean;\n onCommit: (v: unknown) => void;\n onCancel?: () => void;\n onNavigate?: (dir: \"up\" | \"down\" | \"left\" | \"right\") => void;\n}) {\n const ref = useRef<HTMLInputElement>(null);\n const [text, setText] = useState(() => valueToEditString(value, kind));\n const [error, setError] = useState<string | null>(null);\n\n useEffect(() => {\n ref.current?.focus();\n ref.current?.select();\n }, []);\n\n const commit = (nav?: \"down\" | \"right\") => {\n try {\n const parsed = parseEditValue(text, kind);\n setError(null);\n onCommit(parsed);\n if (nav) onNavigate?.(nav);\n } catch (err) {\n setError(err instanceof ParseError ? err.message : String(err));\n }\n };\n\n return (\n <div className=\"relative h-full w-full\">\n <input\n ref={ref}\n type={kind === \"number\" ? \"text\" : \"text\"}\n inputMode={kind === \"number\" ? \"decimal\" : undefined}\n value={text}\n onChange={(e) => setText(e.target.value)}\n onBlur={() => commit()}\n onKeyDown={(e) => {\n if (e.key === \"Enter\") {\n e.preventDefault();\n commit(\"down\");\n } else if (e.key === \"Tab\") {\n e.preventDefault();\n commit(\"right\");\n } else if (e.key === \"Escape\") {\n e.preventDefault();\n onCancel?.();\n }\n }}\n className={cn(\n \"h-full w-full bg-background px-2 py-1 text-xs font-mono outline-none\",\n \"ring-2 ring-inset ring-ring\",\n error && \"ring-destructive\",\n )}\n />\n {nullable && (\n <button\n type=\"button\"\n tabIndex={-1}\n title=\"Set NULL\"\n onMouseDown={(e) => {\n e.preventDefault();\n onCommit(null);\n }}\n className=\"absolute right-1 top-1/2 -translate-y-1/2 text-muted-foreground/50 hover:text-foreground\"\n >\n <IconCircleX className=\"h-3.5 w-3.5\" />\n </button>\n )}\n {error && (\n <div className=\"absolute left-0 top-full z-50 mt-0.5 rounded border border-destructive bg-popover px-2 py-1 text-[11px] text-destructive shadow-md\">\n {error}\n </div>\n )}\n </div>\n );\n}\n\n// ─── Enum (select) editor ────────────────────────────────────────────────────\n\nfunction EnumEditor({\n column,\n value,\n onCommit,\n onCancel,\n onNavigate,\n}: {\n column: DbAdminColumn;\n value: unknown;\n onCommit: (v: unknown) => void;\n onCancel?: () => void;\n onNavigate?: (dir: \"up\" | \"down\" | \"left\" | \"right\") => void;\n}) {\n const ref = useRef<HTMLSelectElement>(null);\n const options = inferEnumValues(column) ?? [];\n\n useEffect(() => {\n ref.current?.focus();\n }, []);\n\n return (\n <select\n ref={ref}\n defaultValue={value === null || value === undefined ? \"\" : String(value)}\n onChange={(e) => {\n const v = e.target.value;\n onCommit(v === \"\" ? null : v);\n onNavigate?.(\"down\");\n }}\n onBlur={() => onCancel?.()}\n onKeyDown={(e) => {\n if (e.key === \"Escape\") onCancel?.();\n }}\n className=\"h-full w-full appearance-none bg-background px-2 py-1 text-xs font-mono outline-none ring-2 ring-inset ring-ring\"\n >\n {column.nullable && <option value=\"\">NULL</option>}\n {options.map((opt) => (\n <option key={opt} value={opt}>\n {opt}\n </option>\n ))}\n </select>\n );\n}\n\n// ─── JSON / long-text expanding editor ───────────────────────────────────────\n\nfunction JsonEditor({\n value,\n onCommit,\n onCancel,\n}: {\n value: unknown;\n onCommit: (v: unknown) => void;\n onCancel?: () => void;\n}) {\n const [open, setOpen] = useState(true);\n const [text, setText] = useState(() => formatJsonPretty(value));\n const [error, setError] = useState<string | null>(null);\n\n const commit = () => {\n if (text.trim() === \"\") {\n onCommit(null);\n setOpen(false);\n return;\n }\n try {\n const parsed = parseEditValue(text, \"json\");\n setError(null);\n onCommit(parsed);\n setOpen(false);\n } catch (err) {\n setError(err instanceof ParseError ? err.message : String(err));\n }\n };\n\n return (\n <Popover\n open={open}\n onOpenChange={(o) => {\n if (!o) onCancel?.();\n setOpen(o);\n }}\n >\n <PopoverTrigger asChild>\n <button\n type=\"button\"\n className=\"flex h-full w-full items-center gap-1 px-2 py-1 text-xs font-mono ring-2 ring-inset ring-ring outline-none\"\n >\n <span className=\"truncate\">{formatJsonPretty(value) || \"{}\"}</span>\n <IconChevronDown className=\"ml-auto h-3 w-3 shrink-0\" />\n </button>\n </PopoverTrigger>\n <PopoverContent\n align=\"start\"\n className=\"w-[28rem] p-2\"\n onOpenAutoFocus={(e) => e.preventDefault()}\n >\n <textarea\n autoFocus\n value={text}\n onChange={(e) => setText(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === \"Enter\" && (e.metaKey || e.ctrlKey)) {\n e.preventDefault();\n commit();\n } else if (e.key === \"Escape\") {\n e.preventDefault();\n onCancel?.();\n }\n }}\n rows={10}\n spellCheck={false}\n className={cn(\n \"w-full resize-y rounded border border-border bg-background p-2 font-mono text-xs outline-none focus:ring-1 focus:ring-ring\",\n error && \"border-destructive\",\n )}\n />\n {error && (\n <div className=\"mt-1 text-[11px] text-destructive\">{error}</div>\n )}\n <div className=\"mt-2 flex items-center justify-between\">\n <button\n type=\"button\"\n onClick={() => {\n onCommit(null);\n setOpen(false);\n }}\n className=\"rounded px-2 py-1 text-[11px] text-muted-foreground hover:text-foreground\"\n >\n Set NULL\n </button>\n <div className=\"flex gap-1\">\n <button\n type=\"button\"\n onClick={() => onCancel?.()}\n className=\"rounded px-2 py-1 text-[11px] text-muted-foreground hover:bg-muted hover:text-foreground\"\n >\n Cancel\n </button>\n <button\n type=\"button\"\n onClick={commit}\n className=\"rounded bg-primary px-2 py-1 text-[11px] font-medium text-primary-foreground hover:bg-primary/90\"\n >\n Apply\n </button>\n </div>\n </div>\n </PopoverContent>\n </Popover>\n );\n}\n"]}
1
+ {"version":3,"file":"EditableCell.js","sourceRoot":"","sources":["../../../src/client/db-admin/EditableCell.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useEffect, useRef, useState } from \"react\";\nimport {\n IconChevronDown,\n IconCircleX,\n IconMaximize,\n} from \"@tabler/icons-react\";\nimport { cn } from \"../utils.js\";\nimport {\n Popover,\n PopoverContent,\n PopoverTrigger,\n} from \"../components/ui/popover.js\";\nimport {\n type EditorKind,\n formatCellValue,\n inferEnumValues,\n valueToEditString,\n parseEditValue,\n ParseError,\n cycleTriStateBoolean,\n formatJsonPretty,\n} from \"./cell-format.js\";\nimport type { DbAdminColumn } from \"../../db-admin/types.js\";\n\nexport interface EditableCellProps {\n column: DbAdminColumn;\n kind: EditorKind;\n value: unknown;\n /** Whether this cell holds a staged (uncommitted) edit. */\n dirty?: boolean;\n /** Whether editing is allowed (false when the table has no PK). */\n editable?: boolean;\n /** Whether this cell is the keyboard-focused/active cell in the grid. */\n active?: boolean;\n /** True if the editor should open immediately (e.g. typing began). */\n editing?: boolean;\n /** Commit a new value into the changeset. */\n onCommit: (value: unknown) => void;\n /** Request entering edit mode. */\n onStartEdit?: () => void;\n /** Request leaving edit mode without committing. */\n onCancelEdit?: () => void;\n /** Move focus after Enter (\"down\") or Tab (\"right\"). */\n onNavigate?: (dir: \"up\" | \"down\" | \"left\" | \"right\") => void;\n className?: string;\n}\n\nconst NULL_TOKEN = (\n <span className=\"italic text-muted-foreground/60 select-none\">NULL</span>\n);\n\nexport function EditableCell({\n column,\n kind,\n value,\n dirty,\n editable = true,\n active,\n editing,\n onCommit,\n onStartEdit,\n onCancelEdit,\n onNavigate,\n className,\n}: EditableCellProps) {\n const display = formatCellValue(value, kind);\n\n // Boolean cells toggle in place rather than opening a text editor.\n if (kind === \"boolean\") {\n return (\n <BooleanCell\n value={value}\n dirty={dirty}\n editable={editable}\n active={active}\n onCommit={onCommit}\n onNavigate={onNavigate}\n className={className}\n />\n );\n }\n\n const baseCell = cn(\n \"relative h-full w-full px-2 py-1 text-xs truncate outline-none\",\n \"font-mono\",\n active && \"ring-1 ring-inset ring-ring\",\n dirty && \"bg-amber-500/10 ring-1 ring-inset ring-amber-500/50\",\n editable && \"cursor-text\",\n className,\n );\n\n if (editing && editable) {\n if (kind === \"enum\") {\n return (\n <EnumEditor\n column={column}\n value={value}\n onCommit={onCommit}\n onCancel={onCancelEdit}\n onNavigate={onNavigate}\n />\n );\n }\n if (kind === \"json\") {\n return (\n <JsonEditor value={value} onCommit={onCommit} onCancel={onCancelEdit} />\n );\n }\n return (\n <InlineTextEditor\n kind={kind}\n value={value}\n nullable={column.nullable}\n onCommit={onCommit}\n onCancel={onCancelEdit}\n onNavigate={onNavigate}\n />\n );\n }\n\n return (\n <div\n role=\"gridcell\"\n tabIndex={active ? 0 : -1}\n className={baseCell}\n onDoubleClick={() => editable && onStartEdit?.()}\n onKeyDown={(e) => {\n if (!editable) return;\n if (e.key === \"Enter\" || e.key === \"F2\") {\n e.preventDefault();\n onStartEdit?.();\n }\n }}\n title={display.isNull ? \"NULL\" : display.text}\n >\n <div className=\"flex items-center gap-1\">\n <span className=\"truncate\">\n {display.isNull ? NULL_TOKEN : display.text}\n </span>\n {editable && (kind === \"json\" || kind === \"text\") && (\n <button\n type=\"button\"\n tabIndex={-1}\n onClick={(e) => {\n e.stopPropagation();\n onStartEdit?.();\n }}\n className=\"ml-auto shrink-0 text-muted-foreground/50 opacity-0 hover:text-foreground group-hover:opacity-100\"\n aria-label=\"Expand editor\"\n >\n <IconMaximize className=\"h-3 w-3\" />\n </button>\n )}\n </div>\n </div>\n );\n}\n\n// ─── Boolean (tri-state) ─────────────────────────────────────────────────────\n\nfunction BooleanCell({\n value,\n dirty,\n editable,\n active,\n onCommit,\n onNavigate,\n className,\n}: {\n value: unknown;\n dirty?: boolean;\n editable: boolean;\n active?: boolean;\n onCommit: (v: unknown) => void;\n onNavigate?: (dir: \"up\" | \"down\" | \"left\" | \"right\") => void;\n className?: string;\n}) {\n const label = value === true ? \"true\" : value === false ? \"false\" : null;\n return (\n <div\n role=\"gridcell\"\n tabIndex={active ? 0 : -1}\n className={cn(\n \"h-full w-full px-2 py-1 text-xs font-mono outline-none cursor-pointer select-none\",\n active && \"ring-1 ring-inset ring-ring\",\n dirty && \"bg-amber-500/10 ring-1 ring-inset ring-amber-500/50\",\n className,\n )}\n onClick={() => editable && onCommit(cycleTriStateBoolean(value))}\n onKeyDown={(e) => {\n if (!editable) return;\n if (e.key === \" \" || e.key === \"Enter\") {\n e.preventDefault();\n onCommit(cycleTriStateBoolean(value));\n } else if (e.key === \"ArrowDown\") {\n e.preventDefault();\n onNavigate?.(\"down\");\n } else if (e.key === \"ArrowUp\") {\n e.preventDefault();\n onNavigate?.(\"up\");\n }\n }}\n >\n {label === null ? NULL_TOKEN : label}\n </div>\n );\n}\n\n// ─── Inline text / number / timestamp / uuid editor ──────────────────────────\n\nfunction InlineTextEditor({\n kind,\n value,\n nullable,\n onCommit,\n onCancel,\n onNavigate,\n}: {\n kind: EditorKind;\n value: unknown;\n nullable: boolean;\n onCommit: (v: unknown) => void;\n onCancel?: () => void;\n onNavigate?: (dir: \"up\" | \"down\" | \"left\" | \"right\") => void;\n}) {\n const ref = useRef<HTMLInputElement>(null);\n const [text, setText] = useState(() => valueToEditString(value, kind));\n const [error, setError] = useState<string | null>(null);\n\n useEffect(() => {\n ref.current?.focus();\n ref.current?.select();\n }, []);\n\n const commit = (nav?: \"down\" | \"right\") => {\n try {\n const parsed = parseEditValue(text, kind);\n setError(null);\n onCommit(parsed);\n if (nav) onNavigate?.(nav);\n } catch (err) {\n setError(err instanceof ParseError ? err.message : String(err));\n }\n };\n\n return (\n <div className=\"relative h-full w-full\">\n <input\n ref={ref}\n type=\"text\"\n inputMode={kind === \"number\" ? \"decimal\" : undefined}\n value={text}\n onChange={(e) => setText(e.target.value)}\n onBlur={() => commit()}\n onKeyDown={(e) => {\n if (e.key === \"Enter\") {\n e.preventDefault();\n commit(\"down\");\n } else if (e.key === \"Tab\") {\n e.preventDefault();\n commit(\"right\");\n } else if (e.key === \"Escape\") {\n e.preventDefault();\n onCancel?.();\n }\n }}\n className={cn(\n \"h-full w-full bg-background px-2 py-1 text-xs font-mono outline-none\",\n \"ring-2 ring-inset ring-ring\",\n error && \"ring-destructive\",\n )}\n />\n {nullable && (\n <button\n type=\"button\"\n tabIndex={-1}\n title=\"Set NULL\"\n onMouseDown={(e) => {\n e.preventDefault();\n onCommit(null);\n }}\n className=\"absolute right-1 top-1/2 -translate-y-1/2 text-muted-foreground/50 hover:text-foreground\"\n >\n <IconCircleX className=\"h-3.5 w-3.5\" />\n </button>\n )}\n {error && (\n <div className=\"absolute left-0 top-full z-50 mt-0.5 rounded border border-destructive bg-popover px-2 py-1 text-[11px] text-destructive shadow-md\">\n {error}\n </div>\n )}\n </div>\n );\n}\n\n// ─── Enum (select) editor ────────────────────────────────────────────────────\n\nfunction EnumEditor({\n column,\n value,\n onCommit,\n onCancel,\n onNavigate,\n}: {\n column: DbAdminColumn;\n value: unknown;\n onCommit: (v: unknown) => void;\n onCancel?: () => void;\n onNavigate?: (dir: \"up\" | \"down\" | \"left\" | \"right\") => void;\n}) {\n const ref = useRef<HTMLSelectElement>(null);\n const options = inferEnumValues(column) ?? [];\n\n useEffect(() => {\n ref.current?.focus();\n }, []);\n\n return (\n <select\n ref={ref}\n defaultValue={value === null || value === undefined ? \"\" : String(value)}\n onChange={(e) => {\n const v = e.target.value;\n onCommit(v === \"\" ? null : v);\n onNavigate?.(\"down\");\n }}\n onBlur={() => onCancel?.()}\n onKeyDown={(e) => {\n if (e.key === \"Escape\") onCancel?.();\n }}\n className=\"h-full w-full appearance-none bg-background px-2 py-1 text-xs font-mono outline-none ring-2 ring-inset ring-ring\"\n >\n {column.nullable && <option value=\"\">NULL</option>}\n {options.map((opt) => (\n <option key={opt} value={opt}>\n {opt}\n </option>\n ))}\n </select>\n );\n}\n\n// ─── JSON / long-text expanding editor ───────────────────────────────────────\n\nfunction JsonEditor({\n value,\n onCommit,\n onCancel,\n}: {\n value: unknown;\n onCommit: (v: unknown) => void;\n onCancel?: () => void;\n}) {\n const [open, setOpen] = useState(true);\n const [text, setText] = useState(() => formatJsonPretty(value));\n const [error, setError] = useState<string | null>(null);\n\n const commit = () => {\n if (text.trim() === \"\") {\n onCommit(null);\n setOpen(false);\n return;\n }\n try {\n const parsed = parseEditValue(text, \"json\");\n setError(null);\n onCommit(parsed);\n setOpen(false);\n } catch (err) {\n setError(err instanceof ParseError ? err.message : String(err));\n }\n };\n\n return (\n <Popover\n open={open}\n onOpenChange={(o) => {\n if (!o) onCancel?.();\n setOpen(o);\n }}\n >\n <PopoverTrigger asChild>\n <button\n type=\"button\"\n className=\"flex h-full w-full items-center gap-1 px-2 py-1 text-xs font-mono ring-2 ring-inset ring-ring outline-none\"\n >\n <span className=\"truncate\">{formatJsonPretty(value) || \"{}\"}</span>\n <IconChevronDown className=\"ml-auto h-3 w-3 shrink-0\" />\n </button>\n </PopoverTrigger>\n <PopoverContent\n align=\"start\"\n className=\"w-[28rem] p-2\"\n onOpenAutoFocus={(e) => e.preventDefault()}\n >\n <textarea\n autoFocus\n value={text}\n onChange={(e) => setText(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === \"Enter\" && (e.metaKey || e.ctrlKey)) {\n e.preventDefault();\n commit();\n } else if (e.key === \"Escape\") {\n e.preventDefault();\n onCancel?.();\n }\n }}\n rows={10}\n spellCheck={false}\n className={cn(\n \"w-full resize-y rounded border border-border bg-background p-2 font-mono text-xs outline-none focus:ring-1 focus:ring-ring\",\n error && \"border-destructive\",\n )}\n />\n {error && (\n <div className=\"mt-1 text-[11px] text-destructive\">{error}</div>\n )}\n <div className=\"mt-2 flex items-center justify-between\">\n <button\n type=\"button\"\n onClick={() => {\n onCommit(null);\n setOpen(false);\n }}\n className=\"rounded px-2 py-1 text-[11px] text-muted-foreground hover:text-foreground\"\n >\n Set NULL\n </button>\n <div className=\"flex gap-1\">\n <button\n type=\"button\"\n onClick={() => onCancel?.()}\n className=\"rounded px-2 py-1 text-[11px] text-muted-foreground hover:bg-muted hover:text-foreground\"\n >\n Cancel\n </button>\n <button\n type=\"button\"\n onClick={commit}\n className=\"rounded bg-primary px-2 py-1 text-[11px] font-medium text-primary-foreground hover:bg-primary/90\"\n >\n Apply\n </button>\n </div>\n </div>\n </PopoverContent>\n </Popover>\n );\n}\n"]}
@@ -11,7 +11,6 @@
11
11
  * shipping with the keybinding active in prod is fine because nothing renders
12
12
  * unless invoked.
13
13
  */
14
- import { type ReactNode } from "react";
15
14
  import "./builtins.js";
16
15
  export interface DevOverlayProps {
17
16
  /**
@@ -22,5 +21,4 @@ export interface DevOverlayProps {
22
21
  onOpenChange?: (open: boolean) => void;
23
22
  }
24
23
  export declare function DevOverlay({ open, onOpenChange }?: DevOverlayProps): import("react/jsx-runtime").JSX.Element;
25
- export type { ReactNode };
26
24
  //# sourceMappingURL=DevOverlay.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"DevOverlay.d.ts","sourceRoot":"","sources":["../../../src/client/dev-overlay/DevOverlay.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAKL,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAwBf,OAAO,eAAe,CAAC;AAWvB,MAAM,WAAW,eAAe;IAC9B;;;OAGG;IACH,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;CACxC;AAED,wBAAgB,UAAU,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,GAAE,eAAoB,2CAqCtE;AAoeD,YAAY,EAAE,SAAS,EAAE,CAAC"}
1
+ {"version":3,"file":"DevOverlay.d.ts","sourceRoot":"","sources":["../../../src/client/dev-overlay/DevOverlay.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AA0BH,OAAO,eAAe,CAAC;AAUvB,MAAM,WAAW,eAAe;IAC9B;;;OAGG;IACH,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;CACxC;AAED,wBAAgB,UAAU,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,GAAE,eAAoB,2CAqCtE"}
@@ -12,14 +12,13 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
12
12
  * shipping with the keybinding active in prod is fine because nothing renders
13
13
  * unless invoked.
14
14
  */
15
- import { useCallback, useEffect, useState, useSyncExternalStore, } from "react";
15
+ import { useCallback, useEffect, useState, useSyncExternalStore } from "react";
16
16
  import { IconChevronDown, IconChevronRight, IconLoader2, IconRefresh, IconTrash, IconX, } from "@tabler/icons-react";
17
17
  import { listDevPanels, subscribeDevPanels } from "./registry.js";
18
18
  import { clearAllDevOverlayStorage, useDevOption, DEV_OVERLAY_STORAGE_PREFIX, } from "./use-dev-option.js";
19
19
  import { useDevOverlayShortcut } from "./use-dev-overlay-shortcut.js";
20
20
  import "./builtins.js";
21
21
  import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, } from "../components/ui/tooltip.js";
22
- const PANEL_OPEN_KEY = `${DEV_OVERLAY_STORAGE_PREFIX}open`;
23
22
  const COLLAPSED_KEY_PREFIX = `${DEV_OVERLAY_STORAGE_PREFIX}collapsed-`;
24
23
  export function DevOverlay({ open, onOpenChange } = {}) {
25
24
  const [internalOpen, setInternalOpen] = useState(false);