@agent-native/core 0.109.2 → 0.109.4

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 (334) hide show
  1. package/corpus/README.md +2 -2
  2. package/corpus/core/CHANGELOG.md +16 -0
  3. package/corpus/core/docs/content/agent-native-toolkit.mdx +46 -13
  4. package/corpus/core/docs/content/locales/ar-SA/agent-native-toolkit.mdx +79 -55
  5. package/corpus/core/docs/content/locales/ar-SA/toolkit-capability-packages.mdx +21 -0
  6. package/corpus/core/docs/content/locales/ar-SA/toolkit-context-knowledge.mdx +12 -0
  7. package/corpus/core/docs/content/locales/ar-SA/toolkit-editors-canvases.mdx +17 -0
  8. package/corpus/core/docs/content/locales/de-DE/agent-native-toolkit.mdx +82 -54
  9. package/corpus/core/docs/content/locales/de-DE/toolkit-capability-packages.mdx +21 -0
  10. package/corpus/core/docs/content/locales/de-DE/toolkit-context-knowledge.mdx +12 -0
  11. package/corpus/core/docs/content/locales/de-DE/toolkit-editors-canvases.mdx +17 -0
  12. package/corpus/core/docs/content/locales/es-ES/agent-native-toolkit.mdx +81 -52
  13. package/corpus/core/docs/content/locales/es-ES/toolkit-capability-packages.mdx +21 -0
  14. package/corpus/core/docs/content/locales/es-ES/toolkit-context-knowledge.mdx +12 -0
  15. package/corpus/core/docs/content/locales/es-ES/toolkit-editors-canvases.mdx +21 -0
  16. package/corpus/core/docs/content/locales/fr-FR/agent-native-toolkit.mdx +84 -54
  17. package/corpus/core/docs/content/locales/fr-FR/toolkit-capability-packages.mdx +21 -0
  18. package/corpus/core/docs/content/locales/fr-FR/toolkit-context-knowledge.mdx +12 -0
  19. package/corpus/core/docs/content/locales/fr-FR/toolkit-editors-canvases.mdx +21 -0
  20. package/corpus/core/docs/content/locales/hi-IN/agent-native-toolkit.mdx +69 -62
  21. package/corpus/core/docs/content/locales/hi-IN/toolkit-capability-packages.mdx +21 -0
  22. package/corpus/core/docs/content/locales/hi-IN/toolkit-context-knowledge.mdx +12 -0
  23. package/corpus/core/docs/content/locales/hi-IN/toolkit-editors-canvases.mdx +17 -0
  24. package/corpus/core/docs/content/locales/ja-JP/agent-native-toolkit.mdx +69 -62
  25. package/corpus/core/docs/content/locales/ja-JP/toolkit-capability-packages.mdx +21 -0
  26. package/corpus/core/docs/content/locales/ja-JP/toolkit-context-knowledge.mdx +12 -0
  27. package/corpus/core/docs/content/locales/ja-JP/toolkit-editors-canvases.mdx +17 -0
  28. package/corpus/core/docs/content/locales/ko-KR/agent-native-toolkit.mdx +69 -62
  29. package/corpus/core/docs/content/locales/ko-KR/toolkit-capability-packages.mdx +21 -0
  30. package/corpus/core/docs/content/locales/ko-KR/toolkit-context-knowledge.mdx +12 -0
  31. package/corpus/core/docs/content/locales/ko-KR/toolkit-editors-canvases.mdx +17 -0
  32. package/corpus/core/docs/content/locales/pt-BR/agent-native-toolkit.mdx +82 -54
  33. package/corpus/core/docs/content/locales/pt-BR/toolkit-capability-packages.mdx +21 -0
  34. package/corpus/core/docs/content/locales/pt-BR/toolkit-context-knowledge.mdx +12 -0
  35. package/corpus/core/docs/content/locales/pt-BR/toolkit-editors-canvases.mdx +17 -0
  36. package/corpus/core/docs/content/locales/zh-CN/agent-native-toolkit.mdx +69 -62
  37. package/corpus/core/docs/content/locales/zh-CN/toolkit-capability-packages.mdx +21 -0
  38. package/corpus/core/docs/content/locales/zh-CN/toolkit-context-knowledge.mdx +12 -0
  39. package/corpus/core/docs/content/locales/zh-CN/toolkit-editors-canvases.mdx +17 -0
  40. package/corpus/core/docs/content/locales/zh-TW/agent-native-toolkit.mdx +69 -62
  41. package/corpus/core/docs/content/locales/zh-TW/toolkit-capability-packages.mdx +21 -0
  42. package/corpus/core/docs/content/locales/zh-TW/toolkit-context-knowledge.mdx +12 -0
  43. package/corpus/core/docs/content/locales/zh-TW/toolkit-editors-canvases.mdx +17 -0
  44. package/corpus/core/docs/content/toolkit-capability-packages.mdx +52 -0
  45. package/corpus/core/docs/content/toolkit-context-knowledge.mdx +46 -0
  46. package/corpus/core/docs/content/toolkit-editors-canvases.mdx +55 -0
  47. package/corpus/core/package.json +35 -34
  48. package/corpus/core/src/cli/create.ts +57 -15
  49. package/corpus/core/src/cli/package-lifecycle.ts +2 -0
  50. package/corpus/core/src/cli/skills-content/visual-plan-skill.ts +2 -0
  51. package/corpus/core/src/client/context-xray/ContextMeter.tsx +31 -111
  52. package/corpus/core/src/client/context-xray/ContextSegmentRow.tsx +8 -111
  53. package/corpus/core/src/client/context-xray/ContextTreemap.tsx +6 -111
  54. package/corpus/core/src/client/context-xray/ContextXRayPanel.tsx +31 -391
  55. package/corpus/core/src/client/context-xray/SegmentProvenancePopover.tsx +4 -52
  56. package/corpus/core/src/client/context-xray/format.ts +0 -33
  57. package/corpus/core/src/client/require-session.tsx +19 -3
  58. package/corpus/core/src/client/rich-markdown-editor/index.ts +42 -57
  59. package/corpus/core/src/client/rich-markdown-editor/uploadEditorImage.ts +2 -1
  60. package/corpus/core/src/client/use-action.ts +145 -2
  61. package/corpus/core/src/client/use-session.ts +79 -48
  62. package/corpus/core/src/client/visual-style-controls.tsx +1 -1088
  63. package/corpus/core/src/collab/agent-identity.ts +5 -22
  64. package/corpus/core/src/collab/client.ts +1 -53
  65. package/corpus/core/src/db/client.ts +13 -7
  66. package/corpus/core/src/db/create-get-db.ts +20 -13
  67. package/corpus/core/src/db/request-telemetry.ts +154 -0
  68. package/corpus/core/src/integrations/index.ts +1 -0
  69. package/corpus/core/src/integrations/plugin.ts +9 -3
  70. package/corpus/core/src/integrations/remote-push-delivery-job.ts +48 -0
  71. package/corpus/core/src/integrations/remote-push-delivery.ts +370 -0
  72. package/corpus/core/src/integrations/remote-push-store.ts +275 -26
  73. package/corpus/core/src/server/better-auth-instance.ts +11 -3
  74. package/corpus/core/src/server/core-routes-plugin.ts +36 -14
  75. package/corpus/core/src/server/framework-request-handler.ts +11 -1
  76. package/corpus/core/src/server/http-response-telemetry.ts +233 -31
  77. package/corpus/core/src/styles/rich-markdown-editor.css +1 -510
  78. package/corpus/core/src/templates/workspace-core/.agents/skills/tracking/SKILL.md +19 -0
  79. package/corpus/core/src/testing.ts +1 -1
  80. package/corpus/core/src/vite/client.ts +3 -0
  81. package/corpus/templates/clips/actions/finalize-recording.ts +3 -1
  82. package/corpus/templates/clips/actions/set-mobile-capture-state.ts +4 -1
  83. package/corpus/templates/clips/app/components/library/library-layout.tsx +1 -6
  84. package/corpus/templates/clips/changelog/2026-07-18-new-recording-is-now-emphasized-as-the-primary-action-in-the.md +6 -0
  85. package/corpus/templates/clips/changelog/2026-07-18-recordings-now-remain-safely-recoverable-until-the-stored-me.md +6 -0
  86. package/corpus/templates/content/app/components/editor/VisualEditor.tsx +5 -3
  87. package/corpus/templates/content/app/components/editor/extensions/DragHandle.tsx +4 -4
  88. package/corpus/templates/content/package.json +25 -25
  89. package/corpus/templates/design/app/components/design/TweaksPanel.tsx +2 -1
  90. package/corpus/templates/design/package.json +1 -1
  91. package/corpus/templates/mail/package.json +9 -9
  92. package/corpus/templates/plan/.agents/skills/visual-plan/SKILL.md +2 -0
  93. package/corpus/templates/plan/app/components/editor/PlanDocumentEditor.tsx +8 -8
  94. package/corpus/templates/plan/app/components/editor/planSlashCommands.ts +6 -6
  95. package/corpus/templates/plan/app/components/plan/PlanImageNode.tsx +4 -7
  96. package/corpus/templates/plan/app/components/plan/PlanMarkdownEditor.tsx +6 -4
  97. package/corpus/templates/plan/app/components/plan/PlanVisualSurface.tsx +1 -1
  98. package/corpus/templates/plan/changelog/2026-07-18-visual-plans-now-open-on-wireframes-by-default-when-a-protot.md +6 -0
  99. package/corpus/templates/plan/package.json +3 -3
  100. package/corpus/templates/slides/app/components/editor/SlideStyleInspector.tsx +2 -2
  101. package/corpus/templates/slides/app/components/editor/TweaksPanel.tsx +2 -2
  102. package/corpus/templates/slides/package.json +13 -13
  103. package/corpus/templates/tasks/AGENTS.md +3 -0
  104. package/corpus/templates/tasks/actions/render-task-list-inline.ts +202 -0
  105. package/corpus/templates/tasks/changelog/2026-07-18-task-lists-can-now-appear-as-interactive-widgets-inline-in-c.md +6 -0
  106. package/corpus/templates/tasks/docs/features/f8-chat.mdx +2 -0
  107. package/corpus/templates/tasks/server/plugins/agent-chat.ts +2 -0
  108. package/dist/catalog.json +39 -1
  109. package/dist/cli/create.d.ts +10 -1
  110. package/dist/cli/create.d.ts.map +1 -1
  111. package/dist/cli/create.js +49 -16
  112. package/dist/cli/create.js.map +1 -1
  113. package/dist/cli/package-lifecycle.d.ts.map +1 -1
  114. package/dist/cli/package-lifecycle.js +2 -0
  115. package/dist/cli/package-lifecycle.js.map +1 -1
  116. package/dist/cli/skills-content/visual-plan-skill.d.ts +1 -1
  117. package/dist/cli/skills-content/visual-plan-skill.d.ts.map +1 -1
  118. package/dist/cli/skills-content/visual-plan-skill.js +2 -0
  119. package/dist/cli/skills-content/visual-plan-skill.js.map +1 -1
  120. package/dist/client/context-xray/ContextMeter.d.ts.map +1 -1
  121. package/dist/client/context-xray/ContextMeter.js +8 -23
  122. package/dist/client/context-xray/ContextMeter.js.map +1 -1
  123. package/dist/client/context-xray/ContextSegmentRow.d.ts.map +1 -1
  124. package/dist/client/context-xray/ContextSegmentRow.js +3 -19
  125. package/dist/client/context-xray/ContextSegmentRow.js.map +1 -1
  126. package/dist/client/context-xray/ContextTreemap.d.ts.map +1 -1
  127. package/dist/client/context-xray/ContextTreemap.js +3 -54
  128. package/dist/client/context-xray/ContextTreemap.js.map +1 -1
  129. package/dist/client/context-xray/ContextXRayPanel.d.ts.map +1 -1
  130. package/dist/client/context-xray/ContextXRayPanel.js +21 -163
  131. package/dist/client/context-xray/ContextXRayPanel.js.map +1 -1
  132. package/dist/client/context-xray/SegmentProvenancePopover.d.ts.map +1 -1
  133. package/dist/client/context-xray/SegmentProvenancePopover.js +3 -4
  134. package/dist/client/context-xray/SegmentProvenancePopover.js.map +1 -1
  135. package/dist/client/context-xray/format.d.ts +0 -4
  136. package/dist/client/context-xray/format.d.ts.map +1 -1
  137. package/dist/client/context-xray/format.js +0 -49
  138. package/dist/client/context-xray/format.js.map +1 -1
  139. package/dist/client/require-session.d.ts.map +1 -1
  140. package/dist/client/require-session.js +6 -3
  141. package/dist/client/require-session.js.map +1 -1
  142. package/dist/client/rich-markdown-editor/index.d.ts +1 -12
  143. package/dist/client/rich-markdown-editor/index.d.ts.map +1 -1
  144. package/dist/client/rich-markdown-editor/index.js +1 -12
  145. package/dist/client/rich-markdown-editor/index.js.map +1 -1
  146. package/dist/client/rich-markdown-editor/uploadEditorImage.d.ts +1 -1
  147. package/dist/client/rich-markdown-editor/uploadEditorImage.d.ts.map +1 -1
  148. package/dist/client/rich-markdown-editor/uploadEditorImage.js.map +1 -1
  149. package/dist/client/use-action.d.ts.map +1 -1
  150. package/dist/client/use-action.js +117 -1
  151. package/dist/client/use-action.js.map +1 -1
  152. package/dist/client/use-session.d.ts.map +1 -1
  153. package/dist/client/use-session.js +72 -50
  154. package/dist/client/use-session.js.map +1 -1
  155. package/dist/client/visual-style-controls.d.ts +1 -89
  156. package/dist/client/visual-style-controls.d.ts.map +1 -1
  157. package/dist/client/visual-style-controls.js +1 -498
  158. package/dist/client/visual-style-controls.js.map +1 -1
  159. package/dist/collab/agent-identity.d.ts +1 -14
  160. package/dist/collab/agent-identity.d.ts.map +1 -1
  161. package/dist/collab/agent-identity.js +1 -13
  162. package/dist/collab/agent-identity.js.map +1 -1
  163. package/dist/collab/awareness.d.ts +2 -2
  164. package/dist/collab/awareness.d.ts.map +1 -1
  165. package/dist/collab/client.d.ts +1 -19
  166. package/dist/collab/client.d.ts.map +1 -1
  167. package/dist/collab/client.js +1 -53
  168. package/dist/collab/client.js.map +1 -1
  169. package/dist/collab/struct-routes.d.ts +1 -1
  170. package/dist/db/client.d.ts.map +1 -1
  171. package/dist/db/client.js +7 -1
  172. package/dist/db/client.js.map +1 -1
  173. package/dist/db/create-get-db.d.ts +3 -6
  174. package/dist/db/create-get-db.d.ts.map +1 -1
  175. package/dist/db/create-get-db.js +9 -2
  176. package/dist/db/create-get-db.js.map +1 -1
  177. package/dist/db/request-telemetry.d.ts +23 -0
  178. package/dist/db/request-telemetry.d.ts.map +1 -0
  179. package/dist/db/request-telemetry.js +95 -0
  180. package/dist/db/request-telemetry.js.map +1 -0
  181. package/dist/integrations/index.d.ts +1 -0
  182. package/dist/integrations/index.d.ts.map +1 -1
  183. package/dist/integrations/index.js +1 -0
  184. package/dist/integrations/index.js.map +1 -1
  185. package/dist/integrations/plugin.d.ts.map +1 -1
  186. package/dist/integrations/plugin.js +8 -3
  187. package/dist/integrations/plugin.js.map +1 -1
  188. package/dist/integrations/remote-push-delivery-job.d.ts +4 -0
  189. package/dist/integrations/remote-push-delivery-job.d.ts.map +1 -0
  190. package/dist/integrations/remote-push-delivery-job.js +44 -0
  191. package/dist/integrations/remote-push-delivery-job.js.map +1 -0
  192. package/dist/integrations/remote-push-delivery.d.ts +11 -0
  193. package/dist/integrations/remote-push-delivery.d.ts.map +1 -0
  194. package/dist/integrations/remote-push-delivery.js +265 -0
  195. package/dist/integrations/remote-push-delivery.js.map +1 -0
  196. package/dist/integrations/remote-push-store.d.ts +33 -0
  197. package/dist/integrations/remote-push-store.d.ts.map +1 -1
  198. package/dist/integrations/remote-push-store.js +195 -26
  199. package/dist/integrations/remote-push-store.js.map +1 -1
  200. package/dist/notifications/routes.d.ts +3 -3
  201. package/dist/progress/routes.d.ts +1 -1
  202. package/dist/provider-api/corpus-jobs.d.ts +2 -2
  203. package/dist/resources/handlers.d.ts +3 -3
  204. package/dist/secrets/routes.d.ts +9 -9
  205. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  206. package/dist/server/better-auth-instance.js +7 -3
  207. package/dist/server/better-auth-instance.js.map +1 -1
  208. package/dist/server/core-routes-plugin.d.ts +8 -0
  209. package/dist/server/core-routes-plugin.d.ts.map +1 -1
  210. package/dist/server/core-routes-plugin.js +23 -8
  211. package/dist/server/core-routes-plugin.js.map +1 -1
  212. package/dist/server/framework-request-handler.d.ts.map +1 -1
  213. package/dist/server/framework-request-handler.js +9 -1
  214. package/dist/server/framework-request-handler.js.map +1 -1
  215. package/dist/server/http-response-telemetry.d.ts +3 -2
  216. package/dist/server/http-response-telemetry.d.ts.map +1 -1
  217. package/dist/server/http-response-telemetry.js +160 -27
  218. package/dist/server/http-response-telemetry.js.map +1 -1
  219. package/dist/server/transcribe-voice.d.ts +1 -1
  220. package/dist/styles/rich-markdown-editor.css +1 -510
  221. package/dist/templates/workspace-core/.agents/skills/tracking/SKILL.md +19 -0
  222. package/dist/testing.d.ts +1 -1
  223. package/dist/testing.d.ts.map +1 -1
  224. package/dist/testing.js +1 -1
  225. package/dist/testing.js.map +1 -1
  226. package/dist/vite/client.d.ts.map +1 -1
  227. package/dist/vite/client.js +3 -0
  228. package/dist/vite/client.js.map +1 -1
  229. package/docs/content/agent-native-toolkit.mdx +46 -13
  230. package/docs/content/locales/ar-SA/agent-native-toolkit.mdx +79 -55
  231. package/docs/content/locales/ar-SA/toolkit-capability-packages.mdx +21 -0
  232. package/docs/content/locales/ar-SA/toolkit-context-knowledge.mdx +12 -0
  233. package/docs/content/locales/ar-SA/toolkit-editors-canvases.mdx +17 -0
  234. package/docs/content/locales/de-DE/agent-native-toolkit.mdx +82 -54
  235. package/docs/content/locales/de-DE/toolkit-capability-packages.mdx +21 -0
  236. package/docs/content/locales/de-DE/toolkit-context-knowledge.mdx +12 -0
  237. package/docs/content/locales/de-DE/toolkit-editors-canvases.mdx +17 -0
  238. package/docs/content/locales/es-ES/agent-native-toolkit.mdx +81 -52
  239. package/docs/content/locales/es-ES/toolkit-capability-packages.mdx +21 -0
  240. package/docs/content/locales/es-ES/toolkit-context-knowledge.mdx +12 -0
  241. package/docs/content/locales/es-ES/toolkit-editors-canvases.mdx +21 -0
  242. package/docs/content/locales/fr-FR/agent-native-toolkit.mdx +84 -54
  243. package/docs/content/locales/fr-FR/toolkit-capability-packages.mdx +21 -0
  244. package/docs/content/locales/fr-FR/toolkit-context-knowledge.mdx +12 -0
  245. package/docs/content/locales/fr-FR/toolkit-editors-canvases.mdx +21 -0
  246. package/docs/content/locales/hi-IN/agent-native-toolkit.mdx +69 -62
  247. package/docs/content/locales/hi-IN/toolkit-capability-packages.mdx +21 -0
  248. package/docs/content/locales/hi-IN/toolkit-context-knowledge.mdx +12 -0
  249. package/docs/content/locales/hi-IN/toolkit-editors-canvases.mdx +17 -0
  250. package/docs/content/locales/ja-JP/agent-native-toolkit.mdx +69 -62
  251. package/docs/content/locales/ja-JP/toolkit-capability-packages.mdx +21 -0
  252. package/docs/content/locales/ja-JP/toolkit-context-knowledge.mdx +12 -0
  253. package/docs/content/locales/ja-JP/toolkit-editors-canvases.mdx +17 -0
  254. package/docs/content/locales/ko-KR/agent-native-toolkit.mdx +69 -62
  255. package/docs/content/locales/ko-KR/toolkit-capability-packages.mdx +21 -0
  256. package/docs/content/locales/ko-KR/toolkit-context-knowledge.mdx +12 -0
  257. package/docs/content/locales/ko-KR/toolkit-editors-canvases.mdx +17 -0
  258. package/docs/content/locales/pt-BR/agent-native-toolkit.mdx +82 -54
  259. package/docs/content/locales/pt-BR/toolkit-capability-packages.mdx +21 -0
  260. package/docs/content/locales/pt-BR/toolkit-context-knowledge.mdx +12 -0
  261. package/docs/content/locales/pt-BR/toolkit-editors-canvases.mdx +17 -0
  262. package/docs/content/locales/zh-CN/agent-native-toolkit.mdx +69 -62
  263. package/docs/content/locales/zh-CN/toolkit-capability-packages.mdx +21 -0
  264. package/docs/content/locales/zh-CN/toolkit-context-knowledge.mdx +12 -0
  265. package/docs/content/locales/zh-CN/toolkit-editors-canvases.mdx +17 -0
  266. package/docs/content/locales/zh-TW/agent-native-toolkit.mdx +69 -62
  267. package/docs/content/locales/zh-TW/toolkit-capability-packages.mdx +21 -0
  268. package/docs/content/locales/zh-TW/toolkit-context-knowledge.mdx +12 -0
  269. package/docs/content/locales/zh-TW/toolkit-editors-canvases.mdx +17 -0
  270. package/docs/content/toolkit-capability-packages.mdx +52 -0
  271. package/docs/content/toolkit-context-knowledge.mdx +46 -0
  272. package/docs/content/toolkit-editors-canvases.mdx +55 -0
  273. package/package.json +27 -26
  274. package/src/templates/workspace-core/.agents/skills/tracking/SKILL.md +19 -0
  275. package/corpus/core/src/client/rich-markdown-editor/BubbleToolbar.tsx +0 -253
  276. package/corpus/core/src/client/rich-markdown-editor/CodeBlockNode.tsx +0 -258
  277. package/corpus/core/src/client/rich-markdown-editor/DragHandle.ts +0 -1437
  278. package/corpus/core/src/client/rich-markdown-editor/ImageExtension.ts +0 -306
  279. package/corpus/core/src/client/rich-markdown-editor/RichMarkdownEditor.tsx +0 -80
  280. package/corpus/core/src/client/rich-markdown-editor/RunId.ts +0 -61
  281. package/corpus/core/src/client/rich-markdown-editor/SharedRichEditor.tsx +0 -321
  282. package/corpus/core/src/client/rich-markdown-editor/SlashCommandMenu.tsx +0 -310
  283. package/corpus/core/src/client/rich-markdown-editor/extensions.ts +0 -402
  284. package/corpus/core/src/client/rich-markdown-editor/gfmDoc.ts +0 -92
  285. package/corpus/core/src/client/rich-markdown-editor/surgical-apply.ts +0 -192
  286. package/corpus/core/src/client/rich-markdown-editor/useCollabReconcile.ts +0 -590
  287. package/dist/client/rich-markdown-editor/BubbleToolbar.d.ts +0 -37
  288. package/dist/client/rich-markdown-editor/BubbleToolbar.d.ts.map +0 -1
  289. package/dist/client/rich-markdown-editor/BubbleToolbar.js +0 -171
  290. package/dist/client/rich-markdown-editor/BubbleToolbar.js.map +0 -1
  291. package/dist/client/rich-markdown-editor/CodeBlockNode.d.ts +0 -49
  292. package/dist/client/rich-markdown-editor/CodeBlockNode.d.ts.map +0 -1
  293. package/dist/client/rich-markdown-editor/CodeBlockNode.js +0 -127
  294. package/dist/client/rich-markdown-editor/CodeBlockNode.js.map +0 -1
  295. package/dist/client/rich-markdown-editor/DragHandle.d.ts +0 -97
  296. package/dist/client/rich-markdown-editor/DragHandle.d.ts.map +0 -1
  297. package/dist/client/rich-markdown-editor/DragHandle.js +0 -1066
  298. package/dist/client/rich-markdown-editor/DragHandle.js.map +0 -1
  299. package/dist/client/rich-markdown-editor/ImageExtension.d.ts +0 -63
  300. package/dist/client/rich-markdown-editor/ImageExtension.d.ts.map +0 -1
  301. package/dist/client/rich-markdown-editor/ImageExtension.js +0 -243
  302. package/dist/client/rich-markdown-editor/ImageExtension.js.map +0 -1
  303. package/dist/client/rich-markdown-editor/RichMarkdownEditor.d.ts +0 -51
  304. package/dist/client/rich-markdown-editor/RichMarkdownEditor.d.ts.map +0 -1
  305. package/dist/client/rich-markdown-editor/RichMarkdownEditor.js +0 -37
  306. package/dist/client/rich-markdown-editor/RichMarkdownEditor.js.map +0 -1
  307. package/dist/client/rich-markdown-editor/RunId.d.ts +0 -28
  308. package/dist/client/rich-markdown-editor/RunId.d.ts.map +0 -1
  309. package/dist/client/rich-markdown-editor/RunId.js +0 -60
  310. package/dist/client/rich-markdown-editor/RunId.js.map +0 -1
  311. package/dist/client/rich-markdown-editor/SharedRichEditor.d.ts +0 -110
  312. package/dist/client/rich-markdown-editor/SharedRichEditor.d.ts.map +0 -1
  313. package/dist/client/rich-markdown-editor/SharedRichEditor.js +0 -144
  314. package/dist/client/rich-markdown-editor/SharedRichEditor.js.map +0 -1
  315. package/dist/client/rich-markdown-editor/SlashCommandMenu.d.ts +0 -41
  316. package/dist/client/rich-markdown-editor/SlashCommandMenu.d.ts.map +0 -1
  317. package/dist/client/rich-markdown-editor/SlashCommandMenu.js +0 -221
  318. package/dist/client/rich-markdown-editor/SlashCommandMenu.js.map +0 -1
  319. package/dist/client/rich-markdown-editor/extensions.d.ts +0 -178
  320. package/dist/client/rich-markdown-editor/extensions.d.ts.map +0 -1
  321. package/dist/client/rich-markdown-editor/extensions.js +0 -224
  322. package/dist/client/rich-markdown-editor/extensions.js.map +0 -1
  323. package/dist/client/rich-markdown-editor/gfmDoc.d.ts +0 -24
  324. package/dist/client/rich-markdown-editor/gfmDoc.d.ts.map +0 -1
  325. package/dist/client/rich-markdown-editor/gfmDoc.js +0 -83
  326. package/dist/client/rich-markdown-editor/gfmDoc.js.map +0 -1
  327. package/dist/client/rich-markdown-editor/surgical-apply.d.ts +0 -66
  328. package/dist/client/rich-markdown-editor/surgical-apply.d.ts.map +0 -1
  329. package/dist/client/rich-markdown-editor/surgical-apply.js +0 -147
  330. package/dist/client/rich-markdown-editor/surgical-apply.js.map +0 -1
  331. package/dist/client/rich-markdown-editor/useCollabReconcile.d.ts +0 -110
  332. package/dist/client/rich-markdown-editor/useCollabReconcile.d.ts.map +0 -1
  333. package/dist/client/rich-markdown-editor/useCollabReconcile.js +0 -441
  334. package/dist/client/rich-markdown-editor/useCollabReconcile.js.map +0 -1
@@ -1,1088 +1 @@
1
- import { IconColorPicker } from "@tabler/icons-react";
2
- import {
3
- useEffect,
4
- useId,
5
- useRef,
6
- useState,
7
- type KeyboardEvent,
8
- type PointerEvent,
9
- type ReactNode,
10
- } from "react";
11
-
12
- import {
13
- Popover,
14
- PopoverContent,
15
- PopoverTrigger,
16
- } from "./components/ui/popover.js";
17
- import { cn } from "./utils.js";
18
-
19
- export type VisualControlValue = string | number | boolean;
20
-
21
- export interface VisualControlOption {
22
- label: string;
23
- value: string;
24
- color?: string;
25
- }
26
-
27
- export interface VisualTweakDefinition {
28
- id: string;
29
- label: string;
30
- type: "color-swatch" | "color-swatches" | "segment" | "slider" | "toggle";
31
- options?: VisualControlOption[];
32
- min?: number;
33
- max?: number;
34
- step?: number;
35
- defaultValue: VisualControlValue;
36
- cssVar?: string;
37
- unit?: string;
38
- }
39
-
40
- function clampNumber(value: number, min?: number, max?: number) {
41
- let next = value;
42
- if (typeof min === "number") next = Math.max(min, next);
43
- if (typeof max === "number") next = Math.min(max, next);
44
- return next;
45
- }
46
-
47
- function formatNumber(value: number, unit?: string) {
48
- const rounded = Number.isInteger(value) ? value : Number(value.toFixed(2));
49
- return unit ? `${rounded}${unit}` : String(rounded);
50
- }
51
-
52
- function parseDraftNumber(value: string, fallback: number) {
53
- const match = value.trim().match(/-?\d+(?:\.\d+)?/);
54
- if (!match) return fallback;
55
- const next = Number(match[0]);
56
- return Number.isFinite(next) ? next : fallback;
57
- }
58
-
59
- interface RgbaColor {
60
- r: number;
61
- g: number;
62
- b: number;
63
- a: number;
64
- }
65
-
66
- interface HsvaColor {
67
- h: number;
68
- s: number;
69
- v: number;
70
- a: number;
71
- }
72
-
73
- const CHECKERBOARD_IMAGE =
74
- "linear-gradient(45deg, #d4d4d4 25%, transparent 25%), linear-gradient(-45deg, #d4d4d4 25%, transparent 25%), linear-gradient(45deg, transparent 75%, #d4d4d4 75%), linear-gradient(-45deg, transparent 75%, #d4d4d4 75%)";
75
- const FALLBACK_RGBA: RgbaColor = { r: 0, g: 0, b: 0, a: 1 };
76
-
77
- function normalizeRgba(color: RgbaColor): RgbaColor {
78
- return {
79
- r: clamp(color.r, 0, 255),
80
- g: clamp(color.g, 0, 255),
81
- b: clamp(color.b, 0, 255),
82
- a: clampFloat(color.a, 0, 1),
83
- };
84
- }
85
-
86
- function normalizeHexColor(value: string): string | null {
87
- const trimmed = value.trim();
88
- if (/^#[0-9a-f]{6}$/i.test(trimmed)) return trimmed.toUpperCase();
89
- if (/^[0-9a-f]{6}$/i.test(trimmed)) return `#${trimmed}`.toUpperCase();
90
- if (/^#[0-9a-f]{3}$/i.test(trimmed)) {
91
- return `#${trimmed
92
- .slice(1)
93
- .split("")
94
- .map((char) => char + char)
95
- .join("")}`.toUpperCase();
96
- }
97
- if (/^[0-9a-f]{3}$/i.test(trimmed)) {
98
- return `#${trimmed
99
- .split("")
100
- .map((char) => char + char)
101
- .join("")}`.toUpperCase();
102
- }
103
- return null;
104
- }
105
-
106
- function parseCssColor(value: string): RgbaColor | null {
107
- const trimmed = value.trim();
108
- if (!trimmed) return null;
109
- const normalizedHex = normalizeHexColor(trimmed);
110
- if (normalizedHex) {
111
- return normalizeRgba({
112
- r: Number.parseInt(normalizedHex.slice(1, 3), 16),
113
- g: Number.parseInt(normalizedHex.slice(3, 5), 16),
114
- b: Number.parseInt(normalizedHex.slice(5, 7), 16),
115
- a: 1,
116
- });
117
- }
118
- const rgb = trimmed.match(
119
- /^rgba?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)(?:\s*,\s*([0-9.]+%?))?/i,
120
- );
121
- if (rgb) {
122
- return normalizeRgba({
123
- r: Number(rgb[1]),
124
- g: Number(rgb[2]),
125
- b: Number(rgb[3]),
126
- a: parseAlpha(rgb[4]),
127
- });
128
- }
129
- const lower = trimmed.toLowerCase();
130
- if (lower === "transparent" || lower === "rgba(0, 0, 0, 0)") {
131
- return { r: 0, g: 0, b: 0, a: 0 };
132
- }
133
- return null;
134
- }
135
-
136
- function channelToHex(value: number): string {
137
- return clamp(value, 0, 255).toString(16).padStart(2, "0");
138
- }
139
-
140
- function rgbaToHex(color: RgbaColor): string {
141
- const normalized = normalizeRgba(color);
142
- return `#${channelToHex(normalized.r)}${channelToHex(normalized.g)}${channelToHex(normalized.b)}`.toUpperCase();
143
- }
144
-
145
- function rgbaToCss(color: RgbaColor): string {
146
- const normalized = normalizeRgba(color);
147
- if (normalized.a >= 1) return rgbaToHex(normalized);
148
- return `rgba(${normalized.r}, ${normalized.g}, ${normalized.b}, ${trimNumber(normalized.a)})`;
149
- }
150
-
151
- function parseAlpha(value: string | undefined): number {
152
- if (!value) return 1;
153
- if (value.endsWith("%")) return Number(value.slice(0, -1)) / 100;
154
- return Number(value);
155
- }
156
-
157
- function trimNumber(value: number) {
158
- return Number(value.toFixed(2)).toString();
159
- }
160
-
161
- function rgbaToHsv(color: RgbaColor): HsvaColor {
162
- const normalized = normalizeRgba(color);
163
- const r = normalized.r / 255;
164
- const g = normalized.g / 255;
165
- const b = normalized.b / 255;
166
- const max = Math.max(r, g, b);
167
- const min = Math.min(r, g, b);
168
- const delta = max - min;
169
-
170
- let h = 0;
171
- if (delta !== 0) {
172
- if (max === r) h = ((g - b) / delta) % 6;
173
- else if (max === g) h = (b - r) / delta + 2;
174
- else h = (r - g) / delta + 4;
175
- h *= 60;
176
- if (h < 0) h += 360;
177
- }
178
-
179
- return {
180
- h: Math.round(h),
181
- s: max === 0 ? 0 : Math.round((delta / max) * 100),
182
- v: Math.round(max * 100),
183
- a: normalized.a,
184
- };
185
- }
186
-
187
- function hsvToRgba(color: HsvaColor): RgbaColor {
188
- const h = ((color.h % 360) + 360) % 360;
189
- const s = clampFloat(color.s, 0, 100) / 100;
190
- const v = clampFloat(color.v, 0, 100) / 100;
191
- const chroma = v * s;
192
- const x = chroma * (1 - Math.abs(((h / 60) % 2) - 1));
193
- const m = v - chroma;
194
-
195
- let r = 0;
196
- let g = 0;
197
- let b = 0;
198
- if (h < 60) [r, g, b] = [chroma, x, 0];
199
- else if (h < 120) [r, g, b] = [x, chroma, 0];
200
- else if (h < 180) [r, g, b] = [0, chroma, x];
201
- else if (h < 240) [r, g, b] = [0, x, chroma];
202
- else if (h < 300) [r, g, b] = [x, 0, chroma];
203
- else [r, g, b] = [chroma, 0, x];
204
-
205
- return normalizeRgba({
206
- r: Math.round((r + m) * 255),
207
- g: Math.round((g + m) * 255),
208
- b: Math.round((b + m) * 255),
209
- a: clampFloat(color.a, 0, 1),
210
- });
211
- }
212
-
213
- function clamp(value: number, min: number, max: number): number {
214
- if (!Number.isFinite(value)) return min;
215
- return Math.max(min, Math.min(max, Math.round(value)));
216
- }
217
-
218
- function clampFloat(value: number, min: number, max: number): number {
219
- if (!Number.isFinite(value)) return min;
220
- return Math.max(min, Math.min(max, value));
221
- }
222
-
223
- function swatchBackground(value: string) {
224
- if (value === "transparent" || value === "rgba(0, 0, 0, 0)") {
225
- return {
226
- background: CHECKERBOARD_IMAGE,
227
- backgroundPosition: "0 0, 0 4px, 4px -4px, -4px 0",
228
- backgroundSize: "8px 8px",
229
- };
230
- }
231
- return { background: value };
232
- }
233
-
234
- export function VisualInspectorPanel({
235
- title,
236
- subtitle,
237
- children,
238
- className,
239
- headerAction,
240
- }: {
241
- title: ReactNode;
242
- subtitle?: ReactNode;
243
- children: ReactNode;
244
- className?: string;
245
- headerAction?: ReactNode;
246
- }) {
247
- return (
248
- <aside
249
- className={cn(
250
- "w-64 overflow-hidden rounded-xl border border-border bg-card/95 text-card-foreground shadow-2xl shadow-black/35 backdrop-blur",
251
- className,
252
- )}
253
- >
254
- <div className="flex min-h-10 items-start justify-between gap-2 border-b border-border/70 px-3 py-2.5">
255
- <div className="min-w-0">
256
- <div className="truncate text-[11px] font-semibold uppercase tracking-wide text-muted-foreground">
257
- {title}
258
- </div>
259
- {subtitle && (
260
- <div className="mt-0.5 truncate text-[12px] text-foreground">
261
- {subtitle}
262
- </div>
263
- )}
264
- </div>
265
- {headerAction}
266
- </div>
267
- <div className="max-h-[min(680px,calc(100vh-7rem))] overflow-y-auto p-2">
268
- {children}
269
- </div>
270
- </aside>
271
- );
272
- }
273
-
274
- export function VisualInspectorSection({
275
- title,
276
- children,
277
- className,
278
- }: {
279
- title: ReactNode;
280
- children: ReactNode;
281
- className?: string;
282
- }) {
283
- return (
284
- <section className={cn("rounded-lg px-1.5 py-2", className)}>
285
- <div className="mb-2 px-1 text-[10px] font-semibold uppercase tracking-wide text-muted-foreground/75">
286
- {title}
287
- </div>
288
- <div className="space-y-2">{children}</div>
289
- </section>
290
- );
291
- }
292
-
293
- export function VisualControlRow({
294
- label,
295
- children,
296
- className,
297
- }: {
298
- label: ReactNode;
299
- children: ReactNode;
300
- className?: string;
301
- }) {
302
- return (
303
- <div className={cn("grid gap-1", className)}>
304
- <span className="text-[11px] text-muted-foreground">{label}</span>
305
- {children}
306
- </div>
307
- );
308
- }
309
-
310
- export function VisualSwatchControl({
311
- options,
312
- value,
313
- onChange,
314
- columns = 8,
315
- className,
316
- }: {
317
- options: VisualControlOption[];
318
- value: string;
319
- onChange: (value: string) => void;
320
- columns?: number;
321
- className?: string;
322
- }) {
323
- return (
324
- <div
325
- className={cn("grid gap-1.5", className)}
326
- style={{ gridTemplateColumns: `repeat(${columns}, minmax(0, 1fr))` }}
327
- >
328
- {options.map((option) => {
329
- const swatch = option.color ?? option.value;
330
- const isTransparent = swatch === "transparent";
331
- return (
332
- <button
333
- key={`${option.value}-${option.label}`}
334
- type="button"
335
- title={option.label}
336
- aria-label={option.label}
337
- onClick={() => onChange(option.value)}
338
- className={cn(
339
- "size-5 cursor-pointer rounded-md border border-border/70 transition-[transform,border-color] hover:scale-105 hover:border-foreground/40 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
340
- value === option.value &&
341
- "border-foreground/70 ring-2 ring-foreground/40 ring-offset-1 ring-offset-card",
342
- )}
343
- style={{
344
- background: isTransparent
345
- ? "linear-gradient(45deg, hsl(var(--muted)) 25%, transparent 25%), linear-gradient(-45deg, hsl(var(--muted)) 25%, transparent 25%), linear-gradient(45deg, transparent 75%, hsl(var(--muted)) 75%), linear-gradient(-45deg, transparent 75%, hsl(var(--muted)) 75%)"
346
- : swatch,
347
- backgroundPosition: isTransparent
348
- ? "0 0, 0 4px, 4px -4px, -4px 0"
349
- : undefined,
350
- backgroundSize: isTransparent ? "8px 8px" : undefined,
351
- }}
352
- />
353
- );
354
- })}
355
- </div>
356
- );
357
- }
358
-
359
- export function VisualColorPicker({
360
- label,
361
- value,
362
- onChange,
363
- documentColors = [],
364
- allowTransparent = false,
365
- hexLabel = "Hex",
366
- documentColorsLabel = "Document colors",
367
- transparentLabel = "Transparent",
368
- className,
369
- }: {
370
- label: string;
371
- value: string;
372
- onChange: (value: string) => void;
373
- documentColors?: string[];
374
- allowTransparent?: boolean;
375
- hexLabel?: string;
376
- documentColorsLabel?: string;
377
- transparentLabel?: string;
378
- className?: string;
379
- }) {
380
- const [open, setOpen] = useState(false);
381
- const color = parseCssColor(value) ?? FALLBACK_RGBA;
382
- const colorHex = rgbaToHex(color);
383
- const [draft, setDraft] = useState(colorHex.replace(/^#/, ""));
384
- const [picking, setPicking] = useState(false);
385
- const hasEyeDropper = typeof window !== "undefined" && "EyeDropper" in window;
386
-
387
- useEffect(() => {
388
- if (!open) setDraft(colorHex.replace(/^#/, ""));
389
- }, [colorHex, open]);
390
-
391
- const commitDraft = (nextDraft = draft) => {
392
- const normalized = normalizeHexColor(nextDraft);
393
- if (!normalized) {
394
- setDraft(colorHex.replace(/^#/, ""));
395
- return;
396
- }
397
- setDraft(normalized.replace(/^#/, ""));
398
- onChange(normalized);
399
- };
400
-
401
- const emitHsv = (nextHsv: HsvaColor) => {
402
- const nextColor = hsvToRgba({ ...nextHsv, a: color.a });
403
- const nextValue = rgbaToCss(nextColor);
404
- setDraft(rgbaToHex(nextColor).replace(/^#/, ""));
405
- onChange(nextValue);
406
- };
407
-
408
- const pickScreenColor = async () => {
409
- if (!hasEyeDropper || picking) return;
410
- try {
411
- setPicking(true);
412
- const EyeDropperCtor = (
413
- window as unknown as {
414
- EyeDropper?: new () => { open: () => Promise<{ sRGBHex: string }> };
415
- }
416
- ).EyeDropper;
417
- if (!EyeDropperCtor) return;
418
- const result = await new EyeDropperCtor().open();
419
- if (result?.sRGBHex) {
420
- const next = normalizeHexColor(result.sRGBHex);
421
- if (next) {
422
- setDraft(next.replace(/^#/, ""));
423
- onChange(next);
424
- }
425
- }
426
- } finally {
427
- setPicking(false);
428
- }
429
- };
430
-
431
- const uniqueDocumentColors = Array.from(
432
- new Set(
433
- documentColors
434
- .map((color) =>
435
- color === "transparent" ? color : normalizeHexColor(color),
436
- )
437
- .filter(Boolean) as string[],
438
- ),
439
- ).slice(0, 16);
440
- const displayValue =
441
- value === "transparent" || color.a === 0
442
- ? transparentLabel
443
- : colorHex.replace(/^#/, "");
444
- const hsv = rgbaToHsv(color);
445
-
446
- return (
447
- <Popover open={open} onOpenChange={setOpen}>
448
- <PopoverTrigger asChild>
449
- <button
450
- type="button"
451
- aria-label={label}
452
- className={cn(
453
- "flex h-7 w-full cursor-pointer items-center gap-1.5 rounded-md border border-border bg-background/70 px-2 text-[11px] shadow-none transition-colors hover:bg-accent/60 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
454
- className,
455
- )}
456
- >
457
- <span
458
- className="size-4 shrink-0 rounded-[3px] border border-border/70"
459
- style={swatchBackground(value)}
460
- />
461
- <span className="min-w-0 flex-1 truncate text-left font-medium tabular-nums text-foreground">
462
- {displayValue}
463
- </span>
464
- <span
465
- aria-hidden="true"
466
- className="size-0 border-x-[4px] border-t-[5px] border-x-transparent border-t-muted-foreground/70"
467
- />
468
- </button>
469
- </PopoverTrigger>
470
- <PopoverContent
471
- side="left"
472
- align="start"
473
- sideOffset={8}
474
- className="z-[10000] w-[252px] p-0 text-[11px] shadow-xl"
475
- onFocusOutside={(event) => event.preventDefault()}
476
- >
477
- <div className="rounded-md bg-popover text-popover-foreground">
478
- <VisualSaturationBrightnessField
479
- hsv={hsv}
480
- label={label}
481
- onChange={emitHsv}
482
- />
483
-
484
- <div className="mt-2.5 px-3">
485
- <div className="grid grid-cols-[1.5rem_1fr] items-center gap-x-2">
486
- <div className="flex items-center justify-center">
487
- <button
488
- type="button"
489
- aria-label={label}
490
- disabled={!hasEyeDropper || picking}
491
- onClick={() => void pickScreenColor()}
492
- className={cn(
493
- "flex size-6 cursor-pointer items-center justify-center rounded-sm text-muted-foreground transition-colors hover:bg-accent hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
494
- (!hasEyeDropper || picking) &&
495
- "pointer-events-none opacity-40",
496
- picking &&
497
- "bg-primary/10 text-primary ring-1 ring-primary/50",
498
- )}
499
- >
500
- <IconColorPicker className="size-4" />
501
- </button>
502
- </div>
503
- <VisualColorTrack
504
- label={label}
505
- value={hsv.h}
506
- min={0}
507
- max={360}
508
- backgroundImage="linear-gradient(90deg, #ff0000, #ffff00, #00ff00, #00ffff, #0000ff, #ff00ff, #ff0000)"
509
- onChange={(nextHue) =>
510
- emitHsv({ ...hsv, h: nextHue === 360 ? 0 : nextHue })
511
- }
512
- />
513
- <span
514
- className="mt-2 size-[18px] shrink-0 rounded-[3px] border border-border/60"
515
- style={swatchBackground(rgbaToCss(color))}
516
- />
517
- <VisualColorTrack
518
- label={transparentLabel}
519
- value={Math.round(color.a * 100)}
520
- min={0}
521
- max={100}
522
- backgroundImage={`${CHECKERBOARD_IMAGE}, linear-gradient(90deg, rgba(${color.r}, ${color.g}, ${color.b}, 0), rgba(${color.r}, ${color.g}, ${color.b}, 1))`}
523
- backgroundSize="8px 8px, 8px 8px, 8px 8px, 8px 8px, 100% 100%"
524
- backgroundPosition="0 0, 0 4px, 4px -4px, -4px 0, 0 0"
525
- onChange={(nextOpacity) => {
526
- const nextColor = normalizeRgba({
527
- ...color,
528
- a: nextOpacity / 100,
529
- });
530
- const nextValue = rgbaToCss(nextColor);
531
- setDraft(rgbaToHex(nextColor).replace(/^#/, ""));
532
- onChange(nextValue);
533
- }}
534
- />
535
- </div>
536
- </div>
537
-
538
- <div className="mt-2.5 grid grid-cols-[4.5rem_1fr] items-center gap-1 border-b border-border/70 px-3 pb-3">
539
- <span className="text-[11px] font-medium text-muted-foreground">
540
- {hexLabel}
541
- </span>
542
- <input
543
- value={draft}
544
- spellCheck={false}
545
- onChange={(event) => setDraft(event.currentTarget.value)}
546
- onFocus={(event) => event.currentTarget.select()}
547
- onBlur={() => commitDraft()}
548
- onKeyDown={(event) => {
549
- if (event.key === "Enter") {
550
- event.preventDefault();
551
- commitDraft();
552
- event.currentTarget.blur();
553
- }
554
- if (event.key === "Escape") {
555
- event.preventDefault();
556
- setDraft(colorHex.replace(/^#/, ""));
557
- event.currentTarget.blur();
558
- }
559
- }}
560
- className="h-6 min-w-0 rounded-md border border-input bg-background/70 px-2 text-right text-[11px] uppercase tabular-nums outline-none transition-colors focus:border-ring focus:ring-1 focus:ring-ring"
561
- />
562
- </div>
563
- {(allowTransparent || uniqueDocumentColors.length > 0) && (
564
- <div className="px-3 py-2.5">
565
- <div className="mb-2 flex h-5 items-center justify-between text-[11px] text-muted-foreground">
566
- <span>{documentColorsLabel}</span>
567
- </div>
568
- <div className="grid grid-cols-8 gap-1">
569
- {allowTransparent && (
570
- <button
571
- type="button"
572
- aria-label={transparentLabel}
573
- aria-pressed={value === "transparent"}
574
- className={cn(
575
- "size-5 cursor-pointer rounded-sm border transition-transform hover:scale-110 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
576
- value === "transparent" || color.a === 0
577
- ? "border-primary ring-1 ring-primary"
578
- : "border-border/60",
579
- )}
580
- style={swatchBackground("transparent")}
581
- onClick={() => {
582
- setDraft(colorHex.replace(/^#/, ""));
583
- onChange("transparent");
584
- }}
585
- />
586
- )}
587
- {uniqueDocumentColors.map((color) => (
588
- <button
589
- key={color}
590
- type="button"
591
- title={color}
592
- aria-label={color}
593
- aria-pressed={colorHex === color}
594
- className={cn(
595
- "size-5 cursor-pointer rounded-sm border transition-transform hover:scale-110 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
596
- colorHex === color
597
- ? "border-primary ring-1 ring-primary"
598
- : "border-border/60",
599
- )}
600
- style={swatchBackground(color)}
601
- onClick={() => {
602
- setDraft(color);
603
- onChange(color);
604
- }}
605
- />
606
- ))}
607
- </div>
608
- </div>
609
- )}
610
- </div>
611
- </PopoverContent>
612
- </Popover>
613
- );
614
- }
615
-
616
- function VisualSaturationBrightnessField({
617
- hsv,
618
- label,
619
- onChange,
620
- }: {
621
- hsv: HsvaColor;
622
- label: string;
623
- onChange: (value: HsvaColor) => void;
624
- }) {
625
- const fieldRef = useRef<HTMLDivElement>(null);
626
- const draggingRef = useRef(false);
627
- const hueColor = rgbaToCss(hsvToRgba({ h: hsv.h, s: 100, v: 100, a: 1 }));
628
-
629
- const updateFromPointer = (event: PointerEvent<HTMLDivElement>) => {
630
- const rect = fieldRef.current?.getBoundingClientRect();
631
- if (!rect) return;
632
- onChange({
633
- ...hsv,
634
- s: clamp(((event.clientX - rect.left) / rect.width) * 100, 0, 100),
635
- v: clamp(100 - ((event.clientY - rect.top) / rect.height) * 100, 0, 100),
636
- });
637
- };
638
-
639
- const stepWithKeyboard = (event: KeyboardEvent<HTMLDivElement>) => {
640
- const step = event.shiftKey ? 10 : 1;
641
- if (event.key === "ArrowRight") {
642
- event.preventDefault();
643
- onChange({ ...hsv, s: clamp(hsv.s + step, 0, 100) });
644
- }
645
- if (event.key === "ArrowLeft") {
646
- event.preventDefault();
647
- onChange({ ...hsv, s: clamp(hsv.s - step, 0, 100) });
648
- }
649
- if (event.key === "ArrowUp") {
650
- event.preventDefault();
651
- onChange({ ...hsv, v: clamp(hsv.v + step, 0, 100) });
652
- }
653
- if (event.key === "ArrowDown") {
654
- event.preventDefault();
655
- onChange({ ...hsv, v: clamp(hsv.v - step, 0, 100) });
656
- }
657
- };
658
-
659
- return (
660
- <div
661
- ref={fieldRef}
662
- tabIndex={0}
663
- aria-label={label}
664
- onPointerDown={(event) => {
665
- draggingRef.current = true;
666
- event.currentTarget.setPointerCapture(event.pointerId);
667
- updateFromPointer(event);
668
- }}
669
- onPointerMove={(event) => {
670
- if (!draggingRef.current) return;
671
- updateFromPointer(event);
672
- }}
673
- onPointerUp={(event) => {
674
- draggingRef.current = false;
675
- if (event.currentTarget.hasPointerCapture(event.pointerId)) {
676
- event.currentTarget.releasePointerCapture(event.pointerId);
677
- }
678
- }}
679
- onPointerCancel={() => {
680
- draggingRef.current = false;
681
- }}
682
- onKeyDown={stepWithKeyboard}
683
- className="relative h-40 w-full cursor-crosshair overflow-hidden rounded-t-md outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-inset active:cursor-grabbing"
684
- style={{
685
- backgroundImage: `linear-gradient(to top, #000 0%, transparent 100%), linear-gradient(to right, #fff 0%, ${hueColor} 100%)`,
686
- }}
687
- >
688
- <span
689
- className="pointer-events-none absolute size-4 -translate-x-1/2 -translate-y-1/2 rounded-full border-2 border-white shadow-[0_0_0_1px_hsl(var(--foreground)/0.6)]"
690
- style={{
691
- left: `${hsv.s}%`,
692
- top: `${100 - hsv.v}%`,
693
- }}
694
- />
695
- </div>
696
- );
697
- }
698
-
699
- function VisualColorTrack({
700
- label,
701
- value,
702
- min,
703
- max,
704
- backgroundImage,
705
- backgroundSize,
706
- backgroundPosition,
707
- onChange,
708
- }: {
709
- label: string;
710
- value: number;
711
- min: number;
712
- max: number;
713
- backgroundImage: string;
714
- backgroundSize?: string;
715
- backgroundPosition?: string;
716
- onChange: (value: number) => void;
717
- }) {
718
- const trackRef = useRef<HTMLDivElement>(null);
719
- const draggingRef = useRef(false);
720
- const percent = ((value - min) / (max - min)) * 100;
721
-
722
- const updateFromPointer = (event: PointerEvent<HTMLDivElement>) => {
723
- const rect = trackRef.current?.getBoundingClientRect();
724
- if (!rect) return;
725
- const next = min + ((event.clientX - rect.left) / rect.width) * (max - min);
726
- onChange(clamp(next, min, max));
727
- };
728
-
729
- const stepWithKeyboard = (event: KeyboardEvent<HTMLDivElement>) => {
730
- const step = event.shiftKey ? 10 : 1;
731
- if (event.key === "ArrowRight" || event.key === "ArrowUp") {
732
- event.preventDefault();
733
- onChange(clamp(value + step, min, max));
734
- }
735
- if (event.key === "ArrowLeft" || event.key === "ArrowDown") {
736
- event.preventDefault();
737
- onChange(clamp(value - step, min, max));
738
- }
739
- if (event.key === "Home") {
740
- event.preventDefault();
741
- onChange(min);
742
- }
743
- if (event.key === "End") {
744
- event.preventDefault();
745
- onChange(max);
746
- }
747
- };
748
-
749
- return (
750
- <div
751
- ref={trackRef}
752
- role="slider"
753
- tabIndex={0}
754
- aria-label={label}
755
- aria-valuemin={min}
756
- aria-valuemax={max}
757
- aria-valuenow={Math.round(value)}
758
- onKeyDown={stepWithKeyboard}
759
- onPointerDown={(event) => {
760
- draggingRef.current = true;
761
- event.currentTarget.setPointerCapture(event.pointerId);
762
- updateFromPointer(event);
763
- }}
764
- onPointerMove={(event) => {
765
- if (!draggingRef.current) return;
766
- updateFromPointer(event);
767
- }}
768
- onPointerUp={(event) => {
769
- draggingRef.current = false;
770
- if (event.currentTarget.hasPointerCapture(event.pointerId)) {
771
- event.currentTarget.releasePointerCapture(event.pointerId);
772
- }
773
- }}
774
- onPointerCancel={() => {
775
- draggingRef.current = false;
776
- }}
777
- className="relative h-3.5 cursor-pointer rounded-full border border-border/60 outline-none ring-offset-background focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 active:cursor-grabbing"
778
- style={{ backgroundImage, backgroundSize, backgroundPosition }}
779
- >
780
- <span
781
- className="pointer-events-none absolute top-1/2 size-4 -translate-x-1/2 -translate-y-1/2 rounded-full border-2 border-white shadow-[0_0_0_1px_hsl(var(--foreground)/0.6)]"
782
- style={{ left: `${clamp(percent, 0, 100)}%` }}
783
- />
784
- </div>
785
- );
786
- }
787
-
788
- export function VisualSegmentedControl({
789
- options,
790
- value,
791
- onChange,
792
- className,
793
- }: {
794
- options: VisualControlOption[];
795
- value: string;
796
- onChange: (value: string) => void;
797
- className?: string;
798
- }) {
799
- return (
800
- <div
801
- className={cn(
802
- "flex min-h-7 overflow-hidden rounded-md border border-border bg-background/60",
803
- className,
804
- )}
805
- >
806
- {options.map((option) => (
807
- <button
808
- key={option.value}
809
- type="button"
810
- onClick={() => onChange(option.value)}
811
- className={cn(
812
- "min-w-0 flex-1 cursor-pointer px-2 text-[11px] font-medium text-muted-foreground transition-colors hover:bg-accent/70 hover:text-foreground",
813
- value === option.value && "bg-accent text-foreground",
814
- )}
815
- >
816
- <span className="truncate">{option.label}</span>
817
- </button>
818
- ))}
819
- </div>
820
- );
821
- }
822
-
823
- export function VisualToggleControl({
824
- checked,
825
- onChange,
826
- label,
827
- }: {
828
- checked: boolean;
829
- onChange: (checked: boolean) => void;
830
- label?: string;
831
- }) {
832
- return (
833
- <button
834
- type="button"
835
- aria-pressed={checked}
836
- aria-label={label}
837
- onClick={() => onChange(!checked)}
838
- className={cn(
839
- "relative h-5 w-9 cursor-pointer rounded-full border border-border transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
840
- checked ? "bg-primary/35" : "bg-muted",
841
- )}
842
- >
843
- <span
844
- className={cn(
845
- "absolute top-1/2 size-3.5 -translate-y-1/2 rounded-full bg-foreground shadow transition-transform",
846
- checked ? "translate-x-[18px]" : "translate-x-[3px]",
847
- )}
848
- />
849
- </button>
850
- );
851
- }
852
-
853
- export function VisualSliderControl({
854
- value,
855
- onChange,
856
- min = 0,
857
- max = 100,
858
- step = 1,
859
- unit,
860
- }: {
861
- value: number;
862
- onChange: (value: number) => void;
863
- min?: number;
864
- max?: number;
865
- step?: number;
866
- unit?: string;
867
- }) {
868
- const safeValue = clampNumber(Number.isFinite(value) ? value : min, min, max);
869
- return (
870
- <div className="flex h-7 items-center gap-2">
871
- <input
872
- type="range"
873
- min={min}
874
- max={max}
875
- step={step}
876
- value={safeValue}
877
- onChange={(event) => onChange(Number(event.currentTarget.value))}
878
- className="min-w-0 flex-1 cursor-pointer accent-foreground"
879
- />
880
- <span className="w-9 text-right text-[11px] tabular-nums text-muted-foreground">
881
- {formatNumber(safeValue, unit)}
882
- </span>
883
- </div>
884
- );
885
- }
886
-
887
- export function VisualScrubInput({
888
- label,
889
- value,
890
- onChange,
891
- min,
892
- max,
893
- step = 1,
894
- unit,
895
- disabled = false,
896
- }: {
897
- label: string;
898
- value: number;
899
- onChange: (value: number) => void;
900
- min?: number;
901
- max?: number;
902
- step?: number;
903
- unit?: string;
904
- disabled?: boolean;
905
- }) {
906
- const id = useId();
907
- const [draft, setDraft] = useState(() => formatNumber(value, unit));
908
- const [focused, setFocused] = useState(false);
909
- const dragRef = useRef<{
910
- pointerId: number;
911
- prevX: number;
912
- dragged: boolean;
913
- } | null>(null);
914
-
915
- useEffect(() => {
916
- if (!focused) setDraft(formatNumber(value, unit));
917
- }, [focused, unit, value]);
918
-
919
- const commit = (nextDraft = draft) => {
920
- const parsed = parseDraftNumber(nextDraft, value);
921
- const next = clampNumber(parsed, min, max);
922
- onChange(next);
923
- setDraft(formatNumber(next, unit));
924
- };
925
-
926
- const setNext = (next: number) => {
927
- const clamped = clampNumber(next, min, max);
928
- onChange(clamped);
929
- setDraft(formatNumber(clamped, unit));
930
- };
931
-
932
- const onKeyDown = (event: KeyboardEvent<HTMLInputElement>) => {
933
- if (event.key === "Enter") {
934
- event.preventDefault();
935
- commit();
936
- event.currentTarget.blur();
937
- return;
938
- }
939
- if (event.key === "Escape") {
940
- event.preventDefault();
941
- setDraft(formatNumber(value, unit));
942
- event.currentTarget.blur();
943
- return;
944
- }
945
- if (event.key === "ArrowUp" || event.key === "ArrowDown") {
946
- event.preventDefault();
947
- const mult =
948
- event.shiftKey || event.metaKey ? 10 : event.altKey ? 0.1 : 1;
949
- const direction = event.key === "ArrowUp" ? 1 : -1;
950
- const base = parseDraftNumber(draft, value);
951
- setNext(base + direction * step * mult);
952
- }
953
- };
954
-
955
- const onPointerDown = (event: PointerEvent<HTMLLabelElement>) => {
956
- if (disabled || event.button !== 0) return;
957
- event.preventDefault();
958
- dragRef.current = {
959
- pointerId: event.pointerId,
960
- prevX: event.clientX,
961
- dragged: false,
962
- };
963
- event.currentTarget.setPointerCapture(event.pointerId);
964
- };
965
-
966
- const onPointerMove = (event: PointerEvent<HTMLLabelElement>) => {
967
- const drag = dragRef.current;
968
- if (!drag || drag.pointerId !== event.pointerId) return;
969
- const delta = event.clientX - drag.prevX;
970
- if (delta === 0) return;
971
- drag.prevX = event.clientX;
972
- drag.dragged = true;
973
- const mult = event.shiftKey || event.metaKey ? 10 : event.altKey ? 0.1 : 1;
974
- setNext(value + delta * step * mult);
975
- };
976
-
977
- const onPointerUp = (event: PointerEvent<HTMLLabelElement>) => {
978
- const drag = dragRef.current;
979
- if (!drag || drag.pointerId !== event.pointerId) return;
980
- event.currentTarget.releasePointerCapture(event.pointerId);
981
- dragRef.current = null;
982
- if (!drag.dragged) {
983
- document.getElementById(id)?.focus();
984
- }
985
- };
986
-
987
- return (
988
- <div className="flex items-center gap-1.5">
989
- <label
990
- htmlFor={id}
991
- onPointerDown={onPointerDown}
992
- onPointerMove={onPointerMove}
993
- onPointerUp={onPointerUp}
994
- className={cn(
995
- "flex w-8 shrink-0 cursor-ew-resize select-none items-center justify-center rounded border border-transparent px-1 text-[10px] font-semibold text-muted-foreground hover:border-border hover:bg-accent/60",
996
- disabled && "cursor-not-allowed opacity-50",
997
- )}
998
- >
999
- {label}
1000
- </label>
1001
- <input
1002
- id={id}
1003
- value={draft}
1004
- disabled={disabled}
1005
- onFocus={() => setFocused(true)}
1006
- onBlur={() => {
1007
- setFocused(false);
1008
- commit();
1009
- }}
1010
- onChange={(event) => setDraft(event.currentTarget.value)}
1011
- onKeyDown={onKeyDown}
1012
- className="h-7 min-w-0 flex-1 rounded-md border border-input bg-background/70 px-2 text-right text-[11px] tabular-nums text-foreground outline-none transition-colors focus:border-ring focus:ring-1 focus:ring-ring disabled:opacity-50"
1013
- />
1014
- </div>
1015
- );
1016
- }
1017
-
1018
- export function VisualTweakControl({
1019
- tweak,
1020
- value,
1021
- onChange,
1022
- className,
1023
- }: {
1024
- tweak: VisualTweakDefinition;
1025
- value: VisualControlValue;
1026
- onChange: (value: VisualControlValue) => void;
1027
- className?: string;
1028
- }) {
1029
- if (tweak.type === "toggle") {
1030
- return (
1031
- <div
1032
- className={cn("flex h-7 items-center justify-between gap-2", className)}
1033
- >
1034
- <span className="truncate text-[11px] text-muted-foreground">
1035
- {tweak.label}
1036
- </span>
1037
- <VisualToggleControl
1038
- checked={Boolean(value)}
1039
- onChange={onChange}
1040
- label={tweak.label}
1041
- />
1042
- </div>
1043
- );
1044
- }
1045
-
1046
- const numericValue =
1047
- typeof value === "number"
1048
- ? value
1049
- : typeof value === "string"
1050
- ? Number(value)
1051
- : Number(tweak.defaultValue);
1052
-
1053
- return (
1054
- <VisualControlRow label={tweak.label} className={className}>
1055
- {((tweak.type as string) === "color-swatch" ||
1056
- (tweak.type as string) === "color-swatches") && (
1057
- <VisualColorPicker
1058
- label={tweak.label}
1059
- value={String(value)}
1060
- documentColors={(tweak.options ?? []).map(
1061
- (option) => option.color ?? option.value,
1062
- )}
1063
- onChange={onChange}
1064
- />
1065
- )}
1066
- {tweak.type === "segment" && (
1067
- <VisualSegmentedControl
1068
- options={tweak.options ?? []}
1069
- value={String(value)}
1070
- onChange={onChange}
1071
- />
1072
- )}
1073
- {tweak.type === "slider" && (
1074
- <VisualSliderControl
1075
- min={tweak.min ?? 0}
1076
- max={tweak.max ?? 100}
1077
- step={tweak.step ?? 1}
1078
- unit={
1079
- tweak.unit ??
1080
- (tweak.cssVar?.toLowerCase().includes("radius") ? "px" : undefined)
1081
- }
1082
- value={Number.isFinite(numericValue) ? numericValue : 0}
1083
- onChange={onChange}
1084
- />
1085
- )}
1086
- </VisualControlRow>
1087
- );
1088
- }
1
+ export * from "@agent-native/toolkit/design-tweaks";