@agent-native/core 0.119.3 → 0.119.5

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 (277) hide show
  1. package/corpus/README.md +2 -2
  2. package/corpus/core/CHANGELOG.md +21 -0
  3. package/corpus/core/package.json +3 -3
  4. package/corpus/core/src/agent/engine/index.ts +2 -0
  5. package/corpus/core/src/agent/engine/registry.ts +95 -2
  6. package/corpus/core/src/agent/production-agent.ts +107 -125
  7. package/corpus/core/src/agent/run-manager.ts +45 -2
  8. package/corpus/core/src/agent/thread-data-builder.ts +85 -8
  9. package/corpus/core/src/client/AssistantChat.tsx +37 -9
  10. package/corpus/core/src/client/chat/message-components.tsx +9 -1
  11. package/corpus/core/src/client/chat/repo-helpers.ts +77 -0
  12. package/corpus/core/src/client/chat/tool-call-display.tsx +51 -15
  13. package/corpus/core/src/scripts/agent-engines/list-agent-engines.ts +8 -0
  14. package/corpus/core/src/scripts/agent-engines/manage-agent-engine.ts +5 -1
  15. package/corpus/core/src/scripts/agent-engines/set-agent-engine.ts +9 -1
  16. package/corpus/core/src/server/agent-chat/framework-prompts.ts +3 -1
  17. package/corpus/core/src/server/agent-chat/plugin-options.ts +9 -0
  18. package/corpus/core/src/server/agent-chat-plugin.ts +12 -3
  19. package/corpus/core/src/templates/chat/.agents/skills/actions/SKILL.md +512 -0
  20. package/corpus/core/src/templates/chat/.agents/skills/adding-a-feature/SKILL.md +189 -0
  21. package/corpus/core/src/templates/chat/.agents/skills/agent-native-docs/SKILL.md +115 -0
  22. package/corpus/core/src/templates/chat/.agents/skills/agent-native-toolkit/SKILL.md +177 -0
  23. package/corpus/core/src/templates/chat/.agents/skills/capture-learnings/SKILL.md +89 -0
  24. package/corpus/core/src/templates/chat/.agents/skills/create-skill/SKILL.md +221 -0
  25. package/corpus/core/src/templates/chat/.agents/skills/customizing-agent-native/SKILL.md +220 -0
  26. package/corpus/core/src/templates/chat/.agents/skills/delegate-to-agent/SKILL.md +263 -0
  27. package/corpus/core/src/templates/chat/.agents/skills/feature-flags/SKILL.md +169 -0
  28. package/corpus/core/src/templates/chat/.agents/skills/frontend-design/SKILL.md +160 -0
  29. package/corpus/core/src/templates/chat/.agents/skills/real-time-sync/SKILL.md +232 -0
  30. package/corpus/core/src/templates/chat/.agents/skills/security/SKILL.md +280 -0
  31. package/corpus/core/src/templates/chat/.agents/skills/self-modifying-code/SKILL.md +118 -0
  32. package/corpus/core/src/templates/chat/.agents/skills/shadcn-ui/SKILL.md +119 -0
  33. package/corpus/core/src/templates/chat/.agents/skills/upgrade-agent-native/SKILL.md +100 -0
  34. package/corpus/core/src/templates/chat/.env.example +5 -0
  35. package/corpus/core/src/templates/chat/.ignore +0 -0
  36. package/corpus/core/src/templates/chat/.oxfmtrc.json +8 -0
  37. package/corpus/core/src/templates/chat/AGENTS.md +69 -0
  38. package/corpus/core/src/templates/chat/CHANGELOG.md +10 -0
  39. package/corpus/core/src/templates/chat/DEVELOPING.md +185 -0
  40. package/corpus/core/src/templates/chat/README.md +32 -0
  41. package/corpus/core/src/templates/chat/_gitignore +43 -0
  42. package/corpus/core/src/templates/chat/actions/hello.ts +13 -0
  43. package/corpus/core/src/templates/chat/actions/navigate.ts +41 -0
  44. package/corpus/core/src/templates/chat/actions/run.ts +2 -0
  45. package/corpus/core/src/templates/chat/actions/view-screen.ts +31 -0
  46. package/corpus/core/src/templates/chat/app/components/layout/Header.tsx +60 -0
  47. package/corpus/core/src/templates/chat/app/components/layout/Layout.tsx +185 -0
  48. package/corpus/core/src/templates/chat/app/components/layout/Sidebar.tsx +450 -0
  49. package/corpus/core/src/templates/chat/app/components/ui/button.tsx +1 -0
  50. package/corpus/core/src/templates/chat/app/components/ui/card.tsx +1 -0
  51. package/corpus/core/src/templates/chat/app/components/ui/dropdown-menu.tsx +1 -0
  52. package/corpus/core/src/templates/chat/app/components/ui/input.tsx +1 -0
  53. package/corpus/core/src/templates/chat/app/components/ui/label.tsx +1 -0
  54. package/corpus/core/src/templates/chat/app/components/ui/sheet.tsx +1 -0
  55. package/corpus/core/src/templates/chat/app/components/ui/toolkit-provider.tsx +17 -0
  56. package/corpus/core/src/templates/chat/app/components/ui/tooltip.tsx +1 -0
  57. package/corpus/core/src/templates/chat/app/design-system.ts +3 -0
  58. package/corpus/core/src/templates/chat/app/entry.client.tsx +19 -0
  59. package/corpus/core/src/templates/chat/app/entry.server.tsx +10 -0
  60. package/corpus/core/src/templates/chat/app/global.css +93 -0
  61. package/corpus/core/src/templates/chat/app/hooks/use-navigation-state.ts +93 -0
  62. package/corpus/core/src/templates/chat/app/i18n/ar-SA.ts +68 -0
  63. package/corpus/core/src/templates/chat/app/i18n/de-DE.ts +71 -0
  64. package/corpus/core/src/templates/chat/app/i18n/en-US.ts +70 -0
  65. package/corpus/core/src/templates/chat/app/i18n/es-ES.ts +71 -0
  66. package/corpus/core/src/templates/chat/app/i18n/fr-FR.ts +71 -0
  67. package/corpus/core/src/templates/chat/app/i18n/hi-IN.ts +69 -0
  68. package/corpus/core/src/templates/chat/app/i18n/index.ts +34 -0
  69. package/corpus/core/src/templates/chat/app/i18n/ja-JP.ts +70 -0
  70. package/corpus/core/src/templates/chat/app/i18n/ko-KR.ts +70 -0
  71. package/corpus/core/src/templates/chat/app/i18n/pt-BR.ts +71 -0
  72. package/corpus/core/src/templates/chat/app/i18n/zh-CN.ts +66 -0
  73. package/corpus/core/src/templates/chat/app/i18n/zh-TW.ts +66 -0
  74. package/corpus/core/src/templates/chat/app/i18n-data.ts +556 -0
  75. package/corpus/core/src/templates/chat/app/lib/agent-page.tsx +49 -0
  76. package/corpus/core/src/templates/chat/app/lib/app-config.ts +11 -0
  77. package/corpus/core/src/templates/chat/app/lib/tab-id.ts +1 -0
  78. package/corpus/core/src/templates/chat/app/lib/utils.ts +1 -0
  79. package/corpus/core/src/templates/chat/app/root.tsx +173 -0
  80. package/corpus/core/src/templates/chat/app/routes/_index.tsx +94 -0
  81. package/corpus/core/src/templates/chat/app/routes/agent.tsx +24 -0
  82. package/corpus/core/src/templates/chat/app/routes/chat.$threadId.tsx +1 -0
  83. package/corpus/core/src/templates/chat/app/routes/database.tsx +17 -0
  84. package/corpus/core/src/templates/chat/app/routes/extensions.$id.$slug.tsx +2 -0
  85. package/corpus/core/src/templates/chat/app/routes/extensions.$id.tsx +11 -0
  86. package/corpus/core/src/templates/chat/app/routes/extensions._index.tsx +11 -0
  87. package/corpus/core/src/templates/chat/app/routes/extensions.tsx +5 -0
  88. package/corpus/core/src/templates/chat/app/routes/observability.tsx +19 -0
  89. package/corpus/core/src/templates/chat/app/routes/settings.tsx +89 -0
  90. package/corpus/core/src/templates/chat/app/routes/team.tsx +11 -0
  91. package/corpus/core/src/templates/chat/app/routes.ts +4 -0
  92. package/corpus/core/src/templates/chat/app/vite-env.d.ts +6 -0
  93. package/corpus/core/src/templates/chat/changelog/2026-06-24-a-new-settings-page-gives-quick-access-to-language-workspace.md +6 -0
  94. package/corpus/core/src/templates/chat/changelog/2026-06-24-added-a-language-picker-and-localized-app-chrome-for-support.md +6 -0
  95. package/corpus/core/src/templates/chat/changelog/2026-06-27-traditional-chinese-copy-uses-taiwan-terminology.md +6 -0
  96. package/corpus/core/src/templates/chat/changelog/2026-06-28-left-sidebar-collapse-motion-and-footer-chrome-are-quieter.md +6 -0
  97. package/corpus/core/src/templates/chat/changelog/2026-06-29-chat-layouts-adapt-when-the-agent-sidebar-is-open.md +6 -0
  98. package/corpus/core/src/templates/chat/changelog/2026-07-08-settings-are-cleaner-and-searchable.md +5 -0
  99. package/corpus/core/src/templates/chat/changelog/2026-07-10-chat-now-makes-ai-connection-setup-clear-without-shifting-th.md +6 -0
  100. package/corpus/core/src/templates/chat/changelog/2026-07-13-a-full-agent-page-now-brings-context-files-connections-jobs-.md +6 -0
  101. package/corpus/core/src/templates/chat/changelog/2026-07-14-chat-opens-reliably-on-hosted-deployments-instead-of-failing.md +6 -0
  102. package/corpus/core/src/templates/chat/changelog/2026-07-14-fixed-chat-template-startup-with-older-core-versions.md +6 -0
  103. package/corpus/core/src/templates/chat/changelog/2026-07-15-chat-navigation-focuses-on-chat-and-agent.md +6 -0
  104. package/corpus/core/src/templates/chat/changelog/2026-07-17-the-agent-chat-sidebar-stays-closed-until-you-open-it-or-sta.md +6 -0
  105. package/corpus/core/src/templates/chat/changelog/2026-07-22-compact-sidebar-footer.md +6 -0
  106. package/corpus/core/src/templates/chat/changelog/2026-07-22-full-page-chat-keeps-the-active-conversation-when-moving-to-.md +6 -0
  107. package/corpus/core/src/templates/chat/changelog/2026-07-22-manage-agent-navigation-now-uses-the-connected-nodes-icon.md +6 -0
  108. package/corpus/core/src/templates/chat/changelog/2026-07-22-recent-chats-are-easier-to-scan-and-expand.md +6 -0
  109. package/corpus/core/src/templates/chat/changelog/2026-07-23-full-page-chat-is-better-centered-with-quieter-chat-history-.md +6 -0
  110. package/corpus/core/src/templates/chat/components.json +20 -0
  111. package/corpus/core/src/templates/chat/learnings.defaults.md +5 -0
  112. package/corpus/core/src/templates/chat/netlify.toml +10 -0
  113. package/corpus/core/src/templates/chat/package.json +92 -0
  114. package/corpus/core/src/templates/chat/public/agent-native-icon-dark.svg +10 -0
  115. package/corpus/core/src/templates/chat/public/agent-native-icon-light.svg +10 -0
  116. package/corpus/core/src/templates/chat/public/agent-native-logo-dark.svg +21 -0
  117. package/corpus/core/src/templates/chat/public/agent-native-logo-light.svg +21 -0
  118. package/corpus/core/src/templates/chat/public/favicon.svg +1 -0
  119. package/corpus/core/src/templates/chat/public/icon-180.svg +1 -0
  120. package/corpus/core/src/templates/chat/public/icon-192.svg +1 -0
  121. package/corpus/core/src/templates/chat/public/icon-512.svg +1 -0
  122. package/corpus/core/src/templates/chat/public/manifest.json +21 -0
  123. package/corpus/core/src/templates/chat/react-router.config.ts +7 -0
  124. package/corpus/core/src/templates/chat/server/middleware/auth.ts +15 -0
  125. package/corpus/core/src/templates/chat/server/plugins/agent-chat.ts +21 -0
  126. package/corpus/core/src/templates/chat/server/plugins/auth.ts +17 -0
  127. package/corpus/core/src/templates/chat/server/routes/[...page].get.ts +5 -0
  128. package/corpus/core/src/templates/chat/ssr-entry.ts +15 -0
  129. package/corpus/core/src/templates/chat/tsconfig.json +21 -0
  130. package/corpus/core/src/templates/chat/vite.config.ts +19 -0
  131. package/corpus/templates/analytics/AGENTS.md +19 -11
  132. package/corpus/templates/analytics/actions/list-data-dictionary.ts +3 -1
  133. package/corpus/templates/analytics/actions/save-data-dictionary-entry.ts +14 -0
  134. package/corpus/templates/analytics/actions/search-analytics-query-catalog.ts +41 -0
  135. package/corpus/templates/analytics/app/components/dashboard/DashboardPanelSkeleton.tsx +13 -0
  136. package/corpus/templates/analytics/app/components/dashboard/SqlChart.tsx +12 -11
  137. package/corpus/templates/analytics/app/pages/adhoc/DashboardSkeleton.tsx +3 -3
  138. package/corpus/templates/analytics/changelog/2026-07-23-dashboard-chart-loading-placeholders-are-easier-to-see-in-da.md +6 -0
  139. package/corpus/templates/analytics/changelog/2026-07-23-routine-analytics-lookups-reuse-existing-query-definitions.md +6 -0
  140. package/corpus/templates/analytics/server/lib/agent-chat-plan-mode.ts +1 -12
  141. package/corpus/templates/analytics/server/lib/analytics-query-catalog.ts +405 -0
  142. package/corpus/templates/analytics/server/plugins/agent-chat.ts +11 -16
  143. package/corpus/templates/content/changelog/2026-07-23-database-toolbar-sort-and-filter-controls-open-reliably.md +6 -0
  144. package/corpus/templates/forms/app/lib/public-form-link.ts +14 -0
  145. package/corpus/templates/forms/app/pages/FormBuilderPage.tsx +6 -14
  146. package/corpus/templates/forms/changelog/2026-07-23-published-form-links-can-be-copied-without-being-asked-to-re.md +6 -0
  147. package/corpus/templates/mail/changelog/2026-07-23-scheduled-emails-now-send-only-once-when-multiple-requests-r.md +6 -0
  148. package/corpus/templates/mail/server/lib/jobs.ts +13 -4
  149. package/corpus/templates/mail/server/plugins/mail-jobs.ts +1 -1
  150. package/corpus/templates/slides/actions/patch-deck.ts +2 -1
  151. package/corpus/templates/slides/app/components/editor/EditorSidebar.tsx +7 -18
  152. package/corpus/templates/slides/app/lib/agent-visible-message.ts +28 -0
  153. package/corpus/templates/slides/app/pages/Index.tsx +6 -34
  154. package/corpus/templates/slides/changelog/2026-07-23-full-prompts-stay-visible-in-chat-when-creating-decks-or-add.md +6 -0
  155. package/corpus/templates/slides/changelog/2026-07-23-opening-or-refining-a-deck-no-longer-crashes-with-a-blank-er.md +6 -0
  156. package/corpus/templates/slides/shared/aspect-ratios.ts +4 -1
  157. package/corpus/templates/tasks/.oxfmtrc.json +8 -0
  158. package/corpus/templates/tasks/AGENTS.md +34 -41
  159. package/corpus/templates/tasks/README.md +13 -6
  160. package/corpus/templates/tasks/actions/bulk-delete-inbox-items.ts +10 -8
  161. package/corpus/templates/tasks/actions/bulk-delete-tasks.ts +10 -8
  162. package/corpus/templates/tasks/actions/bulk-mark-inbox-items-ready.ts +1 -1
  163. package/corpus/templates/tasks/actions/bulk-update-tasks.ts +12 -10
  164. package/corpus/templates/tasks/actions/create-inbox-item.ts +7 -4
  165. package/corpus/templates/tasks/actions/create-task.ts +2 -1
  166. package/corpus/templates/tasks/actions/delete-inbox-item.ts +6 -4
  167. package/corpus/templates/tasks/actions/delete-task.ts +1 -1
  168. package/corpus/templates/tasks/actions/list-inbox-items.ts +4 -2
  169. package/corpus/templates/tasks/actions/list-visible-task-fields.ts +3 -1
  170. package/corpus/templates/tasks/actions/mark-inbox-item-ready.ts +6 -4
  171. package/corpus/templates/tasks/actions/navigate.ts +16 -14
  172. package/corpus/templates/tasks/actions/reorder-inbox-items.ts +9 -7
  173. package/corpus/templates/tasks/actions/update-inbox-item.ts +6 -4
  174. package/corpus/templates/tasks/actions/update-task.ts +12 -9
  175. package/corpus/templates/tasks/actions/update-visible-task-fields.ts +10 -8
  176. package/corpus/templates/tasks/actions/view-screen.ts +1 -1
  177. package/corpus/templates/tasks/app/components/tasks/fields/TaskFieldsSidebar.tsx +15 -0
  178. package/corpus/templates/tasks/changelog/2026-07-23-task-detail-extensions.md +6 -0
  179. package/corpus/templates/tasks/drizzle.config.ts +3 -0
  180. package/corpus/templates/tasks/package.json +4 -1
  181. package/corpus/templates/tasks/server/db/schema.ts +0 -10
  182. package/corpus/templates/tasks/server/db/test-tasks-table.ts +0 -5
  183. package/corpus/templates/tasks/server/plugins/agent-chat.ts +1 -1
  184. package/corpus/templates/tasks/server/plugins/db.ts +43 -10
  185. package/corpus/templates/tasks/server/user-config/store.ts +42 -81
  186. package/corpus/templates/tasks/tsconfig.json +1 -2
  187. package/corpus/templates/tasks/vitest.config.ts +10 -1
  188. package/corpus/toolkit/CHANGELOG.md +13 -0
  189. package/corpus/toolkit/package.json +1 -1
  190. package/corpus/toolkit/src/editor/SharedRichEditor.tsx +23 -2
  191. package/corpus/toolkit/src/editor/SlashCommandMenu.tsx +68 -2
  192. package/corpus/toolkit/src/editor/index.ts +1 -0
  193. package/corpus/toolkit/src/editor.css +75 -0
  194. package/corpus/toolkit/src/ui/button.tsx +3 -2
  195. package/dist/agent/engine/index.d.ts +1 -1
  196. package/dist/agent/engine/index.d.ts.map +1 -1
  197. package/dist/agent/engine/index.js +1 -1
  198. package/dist/agent/engine/index.js.map +1 -1
  199. package/dist/agent/engine/registry.d.ts +32 -1
  200. package/dist/agent/engine/registry.d.ts.map +1 -1
  201. package/dist/agent/engine/registry.js +75 -3
  202. package/dist/agent/engine/registry.js.map +1 -1
  203. package/dist/agent/production-agent.d.ts.map +1 -1
  204. package/dist/agent/production-agent.js +96 -115
  205. package/dist/agent/production-agent.js.map +1 -1
  206. package/dist/agent/run-manager.d.ts +9 -1
  207. package/dist/agent/run-manager.d.ts.map +1 -1
  208. package/dist/agent/run-manager.js +26 -0
  209. package/dist/agent/run-manager.js.map +1 -1
  210. package/dist/agent/thread-data-builder.d.ts +2 -0
  211. package/dist/agent/thread-data-builder.d.ts.map +1 -1
  212. package/dist/agent/thread-data-builder.js +69 -9
  213. package/dist/agent/thread-data-builder.js.map +1 -1
  214. package/dist/client/AssistantChat.d.ts.map +1 -1
  215. package/dist/client/AssistantChat.js +32 -10
  216. package/dist/client/AssistantChat.js.map +1 -1
  217. package/dist/client/chat/message-components.d.ts +2 -1
  218. package/dist/client/chat/message-components.d.ts.map +1 -1
  219. package/dist/client/chat/message-components.js +9 -3
  220. package/dist/client/chat/message-components.js.map +1 -1
  221. package/dist/client/chat/repo-helpers.d.ts +4 -0
  222. package/dist/client/chat/repo-helpers.d.ts.map +1 -1
  223. package/dist/client/chat/repo-helpers.js +61 -0
  224. package/dist/client/chat/repo-helpers.js.map +1 -1
  225. package/dist/client/chat/tool-call-display.d.ts +2 -1
  226. package/dist/client/chat/tool-call-display.d.ts.map +1 -1
  227. package/dist/client/chat/tool-call-display.js +10 -9
  228. package/dist/client/chat/tool-call-display.js.map +1 -1
  229. package/dist/collab/struct-routes.d.ts +1 -1
  230. package/dist/observability/routes.d.ts +5 -5
  231. package/dist/progress/routes.d.ts +1 -1
  232. package/dist/provider-api/actions/custom-provider-registration.d.ts +7 -7
  233. package/dist/provider-api/actions/provider-api.d.ts +7 -7
  234. package/dist/provider-api/corpus-jobs.d.ts +2 -2
  235. package/dist/resources/handlers.d.ts +1 -1
  236. package/dist/scripts/agent-engines/list-agent-engines.d.ts.map +1 -1
  237. package/dist/scripts/agent-engines/list-agent-engines.js +8 -2
  238. package/dist/scripts/agent-engines/list-agent-engines.js.map +1 -1
  239. package/dist/scripts/agent-engines/manage-agent-engine.d.ts.map +1 -1
  240. package/dist/scripts/agent-engines/manage-agent-engine.js +5 -2
  241. package/dist/scripts/agent-engines/manage-agent-engine.js.map +1 -1
  242. package/dist/scripts/agent-engines/set-agent-engine.d.ts.map +1 -1
  243. package/dist/scripts/agent-engines/set-agent-engine.js +9 -2
  244. package/dist/scripts/agent-engines/set-agent-engine.js.map +1 -1
  245. package/dist/secrets/routes.d.ts +9 -9
  246. package/dist/server/agent-chat/framework-prompts.d.ts.map +1 -1
  247. package/dist/server/agent-chat/framework-prompts.js +3 -1
  248. package/dist/server/agent-chat/framework-prompts.js.map +1 -1
  249. package/dist/server/agent-chat/plugin-options.d.ts +9 -0
  250. package/dist/server/agent-chat/plugin-options.d.ts.map +1 -1
  251. package/dist/server/agent-chat/plugin-options.js.map +1 -1
  252. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  253. package/dist/server/agent-chat-plugin.js +11 -2
  254. package/dist/server/agent-chat-plugin.js.map +1 -1
  255. package/dist/server/realtime-token.d.ts +1 -1
  256. package/dist/server/transcribe-voice.d.ts +1 -1
  257. package/package.json +4 -4
  258. package/src/agent/engine/index.ts +2 -0
  259. package/src/agent/engine/registry.ts +95 -2
  260. package/src/agent/production-agent.ts +107 -125
  261. package/src/agent/run-manager.ts +45 -2
  262. package/src/agent/thread-data-builder.ts +85 -8
  263. package/src/client/AssistantChat.tsx +37 -9
  264. package/src/client/chat/message-components.tsx +9 -1
  265. package/src/client/chat/repo-helpers.ts +77 -0
  266. package/src/client/chat/tool-call-display.tsx +51 -15
  267. package/src/scripts/agent-engines/list-agent-engines.ts +8 -0
  268. package/src/scripts/agent-engines/manage-agent-engine.ts +5 -1
  269. package/src/scripts/agent-engines/set-agent-engine.ts +9 -1
  270. package/src/server/agent-chat/framework-prompts.ts +3 -1
  271. package/src/server/agent-chat/plugin-options.ts +9 -0
  272. package/src/server/agent-chat-plugin.ts +12 -3
  273. package/corpus/templates/tasks/.prettierrc +0 -5
  274. package/src/templates/chat/actions/hello.spec.ts +0 -23
  275. package/src/templates/chat/actions/navigate.spec.ts +0 -68
  276. package/src/templates/chat/actions/view-screen.spec.ts +0 -40
  277. package/src/templates/chat/app/lib/agent-page.spec.tsx +0 -61
@@ -4,12 +4,14 @@ import { z } from "zod";
4
4
  import { UserInputError } from "../server/errors.js";
5
5
  import { requireUserEmail, updateInboxItem } from "../server/inbox/store.js";
6
6
 
7
+ export const updateInboxItemSchema = z.object({
8
+ inboxItemId: z.string().describe("Inbox item id"),
9
+ title: z.string().min(1).optional().describe("New inbox item title"),
10
+ });
11
+
7
12
  export default defineAction({
8
13
  description: "Update an inbox item title.",
9
- schema: z.object({
10
- inboxItemId: z.string().describe("Inbox item id"),
11
- title: z.string().min(1).optional().describe("New inbox item title"),
12
- }),
14
+ schema: updateInboxItemSchema,
13
15
  run: async (args, ctx) => {
14
16
  const ownerEmail = requireUserEmail(ctx?.userEmail);
15
17
  if (args.title === undefined) {
@@ -25,16 +25,19 @@ const fieldValuesSchema: z.ZodType<FieldValuePatch[]> = z.preprocess(
25
25
  z.array(fieldValuePatchSchema),
26
26
  );
27
27
 
28
+ export const updateTaskSchema = z.object({
29
+ taskId: z.string().describe("Task id"),
30
+ title: z.string().min(1).optional().describe("New task title"),
31
+ done: z.boolean().optional().describe("Completion state"),
32
+ fieldValues: fieldValuesSchema
33
+ .optional()
34
+ .describe("Custom field values to set or clear for this task"),
35
+ });
36
+
28
37
  export default defineAction({
29
- description: "Update a task title, completion state, and/or custom fields.",
30
- schema: z.object({
31
- taskId: z.string().describe("Task id"),
32
- title: z.string().min(1).optional().describe("New task title"),
33
- done: z.boolean().optional().describe("Completion state"),
34
- fieldValues: fieldValuesSchema
35
- .optional()
36
- .describe("Custom field values to set or clear for this task"),
37
- }),
38
+ description:
39
+ "Update one task's title, completion state, and/or custom fields. Use bulk-update-tasks to apply the same title or completion state to multiple tasks.",
40
+ schema: updateTaskSchema,
38
41
  run: async (args, ctx) => {
39
42
  const ownerEmail = requireUserEmail(ctx?.userEmail);
40
43
  if (
@@ -5,17 +5,19 @@ import { requireUserEmail } from "../server/custom-fields/store.js";
5
5
  import { setTaskCardFieldIds } from "../server/user-config/store.js";
6
6
  import { TASK_CARD_FIELD_LIMIT } from "../shared/visible-task-fields.js";
7
7
 
8
+ export const updateVisibleTaskFieldsSchema = z.object({
9
+ fieldIds: z
10
+ .array(z.string())
11
+ .max(TASK_CARD_FIELD_LIMIT)
12
+ .describe(
13
+ `Field ids to show on task cards, top-to-bottom. Max ${TASK_CARD_FIELD_LIMIT}.`,
14
+ ),
15
+ });
16
+
8
17
  export default defineAction({
9
18
  description:
10
19
  "Replace the custom fields shown on task cards for the current user.",
11
- schema: z.object({
12
- fieldIds: z
13
- .array(z.string())
14
- .max(TASK_CARD_FIELD_LIMIT)
15
- .describe(
16
- `Field ids to show on task cards, top-to-bottom. Max ${TASK_CARD_FIELD_LIMIT}.`,
17
- ),
18
- }),
20
+ schema: updateVisibleTaskFieldsSchema,
19
21
  run: async (args, ctx) => {
20
22
  const ownerEmail = requireUserEmail(ctx?.userEmail);
21
23
  const fieldIds = await setTaskCardFieldIds({
@@ -89,7 +89,7 @@ async function readParsedAppState<T>(
89
89
 
90
90
  export default defineAction({
91
91
  description:
92
- "See what the user is currently looking at on screen. Returns navigation state, UI bulk selection on /tasks or /inbox when active, visible list snapshot, and selected item. Always call this first before ambiguous task or inbox edits.",
92
+ "Inspect the current Tasks screen. Returns navigation, visible items, the selected item, and active bulk selection.",
93
93
  schema: z.object({}),
94
94
  http: false,
95
95
  readOnly: true,
@@ -1,3 +1,4 @@
1
+ import { ExtensionSlot } from "@agent-native/core/client/extensions";
1
2
  import { useT } from "@agent-native/core/client/i18n";
2
3
  import { useCallback } from "react";
3
4
  import { toast } from "sonner";
@@ -76,6 +77,20 @@ function TaskFieldsSidebarPanel({ task }: { task: TaskWithFields }) {
76
77
  />
77
78
  ))
78
79
  )}
80
+
81
+ {/* Stable extension contract: changing this slot id or context requires a migration. */}
82
+ <ExtensionSlot
83
+ id="tasks.task-detail.bottom"
84
+ context={{
85
+ taskId: task.id,
86
+ title: task.title,
87
+ done: task.done,
88
+ fieldValues: fields.map((field) => ({
89
+ fieldId: field.id,
90
+ value: field.value ?? null,
91
+ })),
92
+ }}
93
+ />
79
94
  </div>
80
95
  );
81
96
  }
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: added
3
+ date: 2026-07-23
4
+ ---
5
+
6
+ Task detail panels can now host installed extension widgets.
@@ -0,0 +1,3 @@
1
+ import { createDrizzleConfig } from "@agent-native/core/db/drizzle-config";
2
+
3
+ export default createDrizzleConfig();
@@ -12,6 +12,8 @@
12
12
  "typecheck": "agent-native typecheck",
13
13
  "action": "agent-native action",
14
14
  "script": "agent-native script",
15
+ "db:push": "drizzle-kit push",
16
+ "db:generate": "drizzle-kit generate",
15
17
  "test": "vitest --run --config vitest.config.ts",
16
18
  "test:e2e": "playwright test",
17
19
  "test:e2e:install": "playwright install chromium",
@@ -26,6 +28,7 @@
26
28
  "@fontsource-variable/inter": "^5.2.8",
27
29
  "@libsql/client": "^0.15.8",
28
30
  "@tabler/icons-react": "catalog:",
31
+ "drizzle-orm": "^0.45.2",
29
32
  "h3": "^2.0.1-rc.20",
30
33
  "isbot": "^5",
31
34
  "node-pty": "^1.1.0",
@@ -78,7 +81,7 @@
78
81
  "class-variance-authority": "^0.7.1",
79
82
  "clsx": "^2.1.1",
80
83
  "cmdk": "^1.1.1",
81
- "drizzle-orm": "^0.45.2",
84
+ "drizzle-kit": "^0.31.10",
82
85
  "embla-carousel-react": "^8.6.0",
83
86
  "input-otp": "^1.4.2",
84
87
  "next-themes": "^0.4.6",
@@ -51,17 +51,7 @@ export const customFieldValues = table(
51
51
  }),
52
52
  );
53
53
 
54
- export const userConfig = table("user_config", {
55
- ownerEmail: text("owner_email").primaryKey(),
56
- taskCardFieldIdsJson: text("task_card_field_ids_json")
57
- .notNull()
58
- .default("[]"),
59
- updatedAt: text("updated_at").notNull().default(now()),
60
- });
61
-
62
54
  export type StoredCustomField = typeof customFields.$inferSelect;
63
55
  export type NewCustomField = typeof customFields.$inferInsert;
64
56
  export type StoredCustomFieldValue = typeof customFieldValues.$inferSelect;
65
57
  export type NewCustomFieldValue = typeof customFieldValues.$inferInsert;
66
- export type StoredUserConfig = typeof userConfig.$inferSelect;
67
- export type NewUserConfig = typeof userConfig.$inferInsert;
@@ -51,11 +51,6 @@ CREATE INDEX IF NOT EXISTS idx_custom_field_values_owner_task
51
51
  ON custom_field_values (owner_email, task_id);
52
52
  CREATE INDEX IF NOT EXISTS idx_custom_field_values_owner_field
53
53
  ON custom_field_values (owner_email, field_id);
54
- CREATE TABLE IF NOT EXISTS user_config (
55
- owner_email TEXT PRIMARY KEY,
56
- task_card_field_ids_json TEXT NOT NULL DEFAULT '[]',
57
- updated_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP
58
- );
59
54
  `;
60
55
 
61
56
  // libsql, not better-sqlite3: its sync driver lets `.run()`/`.all()`/`.get()` pass here and fail in production.
@@ -43,6 +43,6 @@ When the user asks to see, review, or manage the task list, check the current-sc
43
43
  When view-screen returns selection, treat selectedItems as the user's current UI multi-select on /tasks or /inbox.
44
44
  Prefer bulk-update-tasks and bulk-delete-tasks when the user clearly means multiple tasks (e.g. "mark these done", "delete the selected ones", or several titles at once). Use single-task actions for one task or when bulk selection is not in play.
45
45
  Prefer bulk-delete-inbox-items when the user clearly means multiple inbox items.
46
- Ask for confirmation before delete-task, bulk-delete-tasks, delete-inbox-item, and bulk-delete-inbox-items.
46
+ Ask for confirmation before deleting tasks, inbox items, or custom fields.
47
47
  Do not use db-query for normal task or inbox operations.`,
48
48
  });
@@ -1,6 +1,14 @@
1
- import { runMigrations } from "@agent-native/core/db";
1
+ import {
2
+ ensureAdditiveColumns,
3
+ getDbExec,
4
+ runMigrations,
5
+ } from "@agent-native/core/db";
2
6
 
3
- export default runMigrations(
7
+ import * as schema from "../db/schema.js";
8
+
9
+ // Keep historical entries unnamed for legacy-ledger compatibility; every new
10
+ // migration must add a stable, unique `name` slug.
11
+ const runTasksMigrations = runMigrations(
4
12
  [
5
13
  {
6
14
  version: 1,
@@ -77,14 +85,39 @@ export default runMigrations(
77
85
  CREATE INDEX IF NOT EXISTS idx_custom_field_values_owner_field
78
86
  ON custom_field_values (owner_email, field_id)`,
79
87
  },
80
- {
81
- version: 8,
82
- sql: `CREATE TABLE IF NOT EXISTS user_config (
83
- owner_email TEXT PRIMARY KEY,
84
- task_card_field_ids_json TEXT NOT NULL DEFAULT '[]',
85
- updated_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP
86
- )`,
87
- },
88
88
  ],
89
89
  { table: "tasks_migrations" },
90
90
  );
91
+
92
+ function isDrizzleTable(value: unknown): value is object {
93
+ return (
94
+ !!value &&
95
+ typeof value === "object" &&
96
+ Object.getOwnPropertySymbols(value).some((s) =>
97
+ s.toString().includes("drizzle"),
98
+ )
99
+ );
100
+ }
101
+
102
+ const schemaTables = Object.values(schema).filter(isDrizzleTable);
103
+
104
+ export default async (nitroApp: any): Promise<void> => {
105
+ await runTasksMigrations(nitroApp);
106
+ try {
107
+ const summary = await ensureAdditiveColumns({
108
+ db: getDbExec(),
109
+ tables: schemaTables,
110
+ });
111
+ if (summary.errors.length > 0) {
112
+ console.warn(
113
+ "[db] ensureAdditiveColumns completed with errors:",
114
+ summary.errors,
115
+ );
116
+ }
117
+ } catch (err) {
118
+ console.warn(
119
+ "[db] ensureAdditiveColumns failed (non-fatal):",
120
+ err instanceof Error ? err.message : err,
121
+ );
122
+ }
123
+ };
@@ -1,18 +1,16 @@
1
- import { eq } from "drizzle-orm";
1
+ import { getUserSetting, putUserSetting } from "@agent-native/core/settings";
2
2
 
3
3
  import {
4
4
  DEFAULT_TASK_CARD_FIELD_NAMES,
5
5
  TASK_CARD_FIELD_LIMIT,
6
6
  } from "../../shared/visible-task-fields.js";
7
7
  import { listCustomFields } from "../custom-fields/store.js";
8
- import { getDb } from "../db/index.js";
9
- import { timestamp } from "../db/record-utils.js";
10
- import { userConfig } from "../db/schema.js";
11
- import type { DbHandle } from "../db/transaction.js";
12
8
  import { UserInputError } from "../errors.js";
13
9
 
14
10
  export { DEFAULT_TASK_CARD_FIELD_NAMES, TASK_CARD_FIELD_LIMIT };
15
11
 
12
+ const VISIBLE_TASK_FIELDS_SETTING_KEY = "visible-task-fields";
13
+
16
14
  function fieldIdsForNames(
17
15
  fieldNames: readonly string[],
18
16
  fields: readonly { id: string; title: string }[],
@@ -26,16 +24,11 @@ function fieldIdsForNames(
26
24
  .slice(0, TASK_CARD_FIELD_LIMIT);
27
25
  }
28
26
 
29
- function parseStoredFieldIds(raw: string): string[] {
30
- try {
31
- const parsed = JSON.parse(raw);
32
- if (!Array.isArray(parsed)) return [];
33
- return parsed
34
- .filter((value): value is string => typeof value === "string")
35
- .slice(0, TASK_CARD_FIELD_LIMIT);
36
- } catch {
37
- return [];
38
- }
27
+ function parseFieldIdsValue(value: unknown): string[] {
28
+ if (!Array.isArray(value)) return [];
29
+ return value
30
+ .filter((entry): entry is string => typeof entry === "string")
31
+ .slice(0, TASK_CARD_FIELD_LIMIT);
39
32
  }
40
33
 
41
34
  function dedupeFieldIds(fieldIds: readonly string[]) {
@@ -49,39 +42,34 @@ function filterKnownFieldIds(
49
42
  return fieldIds.filter((fieldId) => knownIds.has(fieldId));
50
43
  }
51
44
 
52
- export async function getTaskCardFieldIds(
53
- input: {
54
- ownerEmail: string;
55
- },
56
- db: DbHandle = getDb(),
57
- ): Promise<string[]> {
45
+ async function readStoredFieldIds(
46
+ ownerEmail: string,
47
+ ): Promise<string[] | null> {
48
+ const setting = await getUserSetting(
49
+ ownerEmail,
50
+ VISIBLE_TASK_FIELDS_SETTING_KEY,
51
+ );
52
+ return setting ? parseFieldIdsValue(setting.fieldIds) : null;
53
+ }
54
+
55
+ export async function getTaskCardFieldIds(input: {
56
+ ownerEmail: string;
57
+ }): Promise<string[]> {
58
58
  const { fields } = await listCustomFields({ ownerEmail: input.ownerEmail });
59
59
  const knownIds = new Set(fields.map((field) => field.id));
60
60
 
61
- const [row] = await db
62
- .select()
63
- .from(userConfig)
64
- .where(eq(userConfig.ownerEmail, input.ownerEmail))
65
- .limit(1);
66
-
67
- if (!row) {
61
+ const stored = await readStoredFieldIds(input.ownerEmail);
62
+ if (stored === null) {
68
63
  return fieldIdsForNames(DEFAULT_TASK_CARD_FIELD_NAMES, fields);
69
64
  }
70
65
 
71
- return filterKnownFieldIds(
72
- parseStoredFieldIds(row.taskCardFieldIdsJson),
73
- knownIds,
74
- );
66
+ return filterKnownFieldIds(stored, knownIds);
75
67
  }
76
68
 
77
- export async function setTaskCardFieldIds(
78
- input: {
79
- ownerEmail: string;
80
- fieldIds: readonly string[];
81
- now?: string;
82
- },
83
- db: DbHandle = getDb(),
84
- ): Promise<string[]> {
69
+ export async function setTaskCardFieldIds(input: {
70
+ ownerEmail: string;
71
+ fieldIds: readonly string[];
72
+ }): Promise<string[]> {
85
73
  const { fields } = await listCustomFields({ ownerEmail: input.ownerEmail });
86
74
  const knownIds = new Set(fields.map((field) => field.id));
87
75
  const next = dedupeFieldIds(input.fieldIds);
@@ -90,49 +78,22 @@ export async function setTaskCardFieldIds(
90
78
  throw new UserInputError("fieldIds must reference existing custom fields.");
91
79
  }
92
80
 
93
- const updatedAt = timestamp(input.now);
94
- const taskCardFieldIdsJson = JSON.stringify(next);
95
-
96
- await db
97
- .insert(userConfig)
98
- .values({
99
- ownerEmail: input.ownerEmail,
100
- taskCardFieldIdsJson,
101
- updatedAt,
102
- })
103
- .onConflictDoUpdate({
104
- target: userConfig.ownerEmail,
105
- set: { taskCardFieldIdsJson, updatedAt },
106
- });
81
+ await putUserSetting(input.ownerEmail, VISIBLE_TASK_FIELDS_SETTING_KEY, {
82
+ fieldIds: next,
83
+ });
107
84
 
108
85
  return next;
109
86
  }
110
87
 
111
- export async function removeTaskCardFieldId(
112
- input: {
113
- ownerEmail: string;
114
- fieldId: string;
115
- now?: string;
116
- },
117
- db: DbHandle = getDb(),
118
- ): Promise<void> {
119
- const [row] = await db
120
- .select()
121
- .from(userConfig)
122
- .where(eq(userConfig.ownerEmail, input.ownerEmail))
123
- .limit(1);
124
-
125
- if (!row) return;
126
-
127
- const next = parseStoredFieldIds(row.taskCardFieldIdsJson).filter(
128
- (fieldId) => fieldId !== input.fieldId,
129
- );
130
-
131
- await db
132
- .update(userConfig)
133
- .set({
134
- taskCardFieldIdsJson: JSON.stringify(next),
135
- updatedAt: timestamp(input.now),
136
- })
137
- .where(eq(userConfig.ownerEmail, input.ownerEmail));
88
+ export async function removeTaskCardFieldId(input: {
89
+ ownerEmail: string;
90
+ fieldId: string;
91
+ }): Promise<void> {
92
+ const stored = await readStoredFieldIds(input.ownerEmail);
93
+ if (stored === null) return;
94
+
95
+ const next = stored.filter((fieldId) => fieldId !== input.fieldId);
96
+ await putUserSetting(input.ownerEmail, VISIBLE_TASK_FIELDS_SETTING_KEY, {
97
+ fieldIds: next,
98
+ });
138
99
  }
@@ -19,6 +19,5 @@
19
19
  "react-router.config.ts",
20
20
  ".react-router/types/**/*",
21
21
  ".generated/**/*"
22
- ],
23
- "exclude": ["**/*.test.ts", "**/*.spec.ts"]
22
+ ]
24
23
  }
@@ -1,8 +1,17 @@
1
+ import path from "node:path";
2
+
1
3
  import { defineConfig } from "vitest/config";
2
4
 
3
5
  export default defineConfig({
6
+ resolve: {
7
+ alias: {
8
+ "@": path.resolve(__dirname, "./app"),
9
+ "@shared": path.resolve(__dirname, "./shared"),
10
+ },
11
+ },
4
12
  test: {
5
- include: ["**/*.test.ts"],
13
+ include: ["**/*.{test,spec}.?(c|m)[jt]s?(x)"],
14
+ exclude: ["**/node_modules/**", "**/.git/**", "**/dist/**", "**/e2e/**"],
6
15
  environment: "node",
7
16
  },
8
17
  });
@@ -1,5 +1,18 @@
1
1
  # @agent-native/toolkit
2
2
 
3
+ ## 0.10.4
4
+
5
+ ### Patch Changes
6
+
7
+ - 4b734be: Give `SharedRichEditor` Notion-style block grips by default and keep the caret
8
+ inside blocks created through the shared slash-command menu.
9
+
10
+ ## 0.10.3
11
+
12
+ ### Patch Changes
13
+
14
+ - 180b41d: Preserve native pointer, keyboard, accessibility, and ref props when legacy Toolkit buttons are composed as menu triggers.
15
+
3
16
  ## 0.10.2
4
17
 
5
18
  ### Patch Changes
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agent-native/toolkit",
3
- "version": "0.10.2",
3
+ "version": "0.10.4",
4
4
  "description": "Reusable app-building UI and helpers for Agent-Native apps.",
5
5
  "homepage": "https://github.com/BuilderIO/agent-native#readme",
6
6
  "bugs": {
@@ -6,6 +6,7 @@ import type { Doc as YDoc } from "yjs";
6
6
 
7
7
  import { cn } from "../utils.js";
8
8
  import { BubbleToolbar, type BubbleToolbarItem } from "./BubbleToolbar.js";
9
+ import { DragHandle } from "./DragHandle.js";
9
10
  import {
10
11
  createSharedEditorExtensions,
11
12
  type RichMarkdownDialect,
@@ -37,6 +38,8 @@ export interface SharedRichEditorProps {
37
38
  preset?: RichMarkdownEditorPreset;
38
39
  /** Toggle individual base extensions (tables/tasks/link/codeBlock/image). */
39
40
  features?: SharedEditorFeatures;
41
+ /** Show the Notion-style block grip and action menu. Defaults to `true`. */
42
+ dragHandle?: boolean;
40
43
  /**
41
44
  * Injectable image uploader for the shared image block. Used only when
42
45
  * `features.image` is on. Pass `uploadEditorImage` (the framework
@@ -141,6 +144,7 @@ export function SharedRichEditor({
141
144
  dialect = "gfm",
142
145
  preset = "plan",
143
146
  features,
147
+ dragHandle = true,
144
148
  onImageUpload = null,
145
149
  extraExtensions,
146
150
  placeholder = "Type '/' for commands...",
@@ -170,6 +174,23 @@ export function SharedRichEditor({
170
174
  onChangeRef.current = onChange;
171
175
  onBlurRef.current = onBlur;
172
176
 
177
+ const effectiveExtraExtensions = useMemo(() => {
178
+ const extras = extraExtensions ?? [];
179
+ if (
180
+ !dragHandle ||
181
+ extras.some((extension) => extension.name === "dragHandle")
182
+ ) {
183
+ return extras;
184
+ }
185
+
186
+ return [
187
+ DragHandle.configure({
188
+ wrapperSelector: ".an-rich-md-wrapper",
189
+ }),
190
+ ...extras,
191
+ ];
192
+ }, [dragHandle, extraExtensions]);
193
+
173
194
  const extensions = useMemo(
174
195
  () =>
175
196
  createSharedEditorExtensions({
@@ -177,7 +198,7 @@ export function SharedRichEditor({
177
198
  preset,
178
199
  placeholder,
179
200
  features,
180
- extraExtensions,
201
+ extraExtensions: effectiveExtraExtensions,
181
202
  onImageUpload,
182
203
  collab: ydoc ? { ydoc, awareness, user } : null,
183
204
  disableHistory,
@@ -192,7 +213,7 @@ export function SharedRichEditor({
192
213
  placeholder,
193
214
  preset,
194
215
  features,
195
- extraExtensions,
216
+ effectiveExtraExtensions,
196
217
  onImageUpload,
197
218
  ydoc,
198
219
  awareness,
@@ -1,3 +1,4 @@
1
+ import { TextSelection } from "@tiptap/pm/state";
1
2
  import type { Editor } from "@tiptap/react";
2
3
  import {
3
4
  useCallback,
@@ -27,6 +28,66 @@ export interface SlashCommandItem {
27
28
  action: (editor: Editor) => void;
28
29
  }
29
30
 
31
+ /**
32
+ * Put the caret inside the block a slash command just created or transformed.
33
+ *
34
+ * Tiptap commands usually preserve a text selection, but commands that replace
35
+ * the current paragraph (notably code blocks and horizontal rules) can leave a
36
+ * node selection or a caret at the following block. Resolving from the slash
37
+ * range keeps the behavior consistent for built-in and app-provided block
38
+ * commands: after selecting a block, typing starts in that block immediately.
39
+ */
40
+ export function focusEditorInInsertedBlock(
41
+ editor: Editor,
42
+ anchorPosition?: number,
43
+ ): void {
44
+ if (editor.isDestroyed) return;
45
+
46
+ const { state } = editor;
47
+ const anchor = Math.max(
48
+ 1,
49
+ Math.min(anchorPosition ?? state.selection.from, state.doc.content.size),
50
+ );
51
+ let containingTextblock: number | null = null;
52
+ let nextTextblock: number | null = null;
53
+ let previousTextblock: number | null = null;
54
+
55
+ state.doc.nodesBetween(0, state.doc.content.size, (node, pos) => {
56
+ if (!node.isTextblock) return;
57
+
58
+ const start = pos + 1;
59
+ const end = pos + node.nodeSize - 1;
60
+ if (anchor >= start && anchor <= end) {
61
+ containingTextblock ??= anchor;
62
+ return;
63
+ }
64
+ if (start > anchor) {
65
+ if (nextTextblock === null || start < nextTextblock) {
66
+ nextTextblock = start;
67
+ }
68
+ return;
69
+ }
70
+ if (previousTextblock === null || start > previousTextblock) {
71
+ previousTextblock = Math.min(anchor, end);
72
+ }
73
+ });
74
+
75
+ const target = containingTextblock ?? nextTextblock ?? previousTextblock;
76
+ if (target === null) {
77
+ editor.commands.focus();
78
+ return;
79
+ }
80
+
81
+ const transaction = state.tr.setSelection(
82
+ TextSelection.create(
83
+ state.doc,
84
+ Math.max(1, Math.min(target, state.doc.content.size)),
85
+ ),
86
+ );
87
+ editor.view.dispatch(transaction.scrollIntoView());
88
+ editor.view.focus();
89
+ }
90
+
30
91
  export interface SlashCommandFeatureFlags {
31
92
  tables?: boolean;
32
93
  tasks?: boolean;
@@ -192,13 +253,18 @@ export function SlashCommandMenu({
192
253
  (command: SlashCommandItem) => {
193
254
  if (slashPosRef.current !== null) {
194
255
  const { from } = editor.state.selection;
256
+ const anchorPosition = slashPosRef.current;
195
257
  editor
196
258
  .chain()
197
259
  .focus()
198
- .deleteRange({ from: slashPosRef.current, to: from })
260
+ .deleteRange({ from: anchorPosition, to: from })
199
261
  .run();
262
+ command.action(editor);
263
+ focusEditorInInsertedBlock(editor, anchorPosition);
264
+ } else {
265
+ command.action(editor);
266
+ focusEditorInInsertedBlock(editor);
200
267
  }
201
- command.action(editor);
202
268
  close();
203
269
  },
204
270
  [close, editor],
@@ -26,6 +26,7 @@ export {
26
26
  DEFAULT_SLASH_COMMANDS,
27
27
  createImageSlashCommand,
28
28
  filterSlashCommandItems,
29
+ focusEditorInInsertedBlock,
29
30
  type SlashCommandItem,
30
31
  type SlashCommandMenuProps,
31
32
  type SlashCommandFeatureFlags,