@agent-native/core 0.14.8 → 0.15.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (544) hide show
  1. package/README.md +1 -1
  2. package/dist/agent/engine/builder-engine.d.ts.map +1 -1
  3. package/dist/agent/engine/builder-engine.js +30 -9
  4. package/dist/agent/engine/builder-engine.js.map +1 -1
  5. package/dist/agent/engine/registry.d.ts.map +1 -1
  6. package/dist/agent/engine/registry.js +14 -4
  7. package/dist/agent/engine/registry.js.map +1 -1
  8. package/dist/agent/production-agent.d.ts.map +1 -1
  9. package/dist/agent/production-agent.js +71 -4
  10. package/dist/agent/production-agent.js.map +1 -1
  11. package/dist/agent/types.d.ts +9 -0
  12. package/dist/agent/types.d.ts.map +1 -1
  13. package/dist/agent/types.js.map +1 -1
  14. package/dist/appearance/actions/change-appearance.d.ts +3 -0
  15. package/dist/appearance/actions/change-appearance.d.ts.map +1 -0
  16. package/dist/appearance/actions/change-appearance.js +29 -0
  17. package/dist/appearance/actions/change-appearance.js.map +1 -0
  18. package/dist/chat-threads/store.d.ts +53 -2
  19. package/dist/chat-threads/store.d.ts.map +1 -1
  20. package/dist/chat-threads/store.js +172 -12
  21. package/dist/chat-threads/store.js.map +1 -1
  22. package/dist/cli/create.d.ts.map +1 -1
  23. package/dist/cli/create.js +114 -37
  24. package/dist/cli/create.js.map +1 -1
  25. package/dist/cli/index.js +30 -4
  26. package/dist/cli/index.js.map +1 -1
  27. package/dist/cli/workspace-dev.d.ts +25 -1
  28. package/dist/cli/workspace-dev.d.ts.map +1 -1
  29. package/dist/cli/workspace-dev.js +275 -49
  30. package/dist/cli/workspace-dev.js.map +1 -1
  31. package/dist/client/AgentPanel.d.ts +23 -4
  32. package/dist/client/AgentPanel.d.ts.map +1 -1
  33. package/dist/client/AgentPanel.js +276 -53
  34. package/dist/client/AgentPanel.js.map +1 -1
  35. package/dist/client/AppearancePicker.d.ts +11 -0
  36. package/dist/client/AppearancePicker.d.ts.map +1 -0
  37. package/dist/client/AppearancePicker.js +16 -0
  38. package/dist/client/AppearancePicker.js.map +1 -0
  39. package/dist/client/AssistantChat.d.ts +35 -0
  40. package/dist/client/AssistantChat.d.ts.map +1 -1
  41. package/dist/client/AssistantChat.js +315 -32
  42. package/dist/client/AssistantChat.js.map +1 -1
  43. package/dist/client/ConnectBuilderCard.d.ts.map +1 -1
  44. package/dist/client/ConnectBuilderCard.js +5 -2
  45. package/dist/client/ConnectBuilderCard.js.map +1 -1
  46. package/dist/client/ErrorBoundary.d.ts.map +1 -1
  47. package/dist/client/ErrorBoundary.js +8 -10
  48. package/dist/client/ErrorBoundary.js.map +1 -1
  49. package/dist/client/FeedbackButton.d.ts.map +1 -1
  50. package/dist/client/FeedbackButton.js +1 -1
  51. package/dist/client/FeedbackButton.js.map +1 -1
  52. package/dist/client/MultiTabAssistantChat.d.ts +13 -1
  53. package/dist/client/MultiTabAssistantChat.d.ts.map +1 -1
  54. package/dist/client/MultiTabAssistantChat.js +217 -38
  55. package/dist/client/MultiTabAssistantChat.js.map +1 -1
  56. package/dist/client/NewWorkspaceAppFlow.d.ts.map +1 -1
  57. package/dist/client/NewWorkspaceAppFlow.js +37 -14
  58. package/dist/client/NewWorkspaceAppFlow.js.map +1 -1
  59. package/dist/client/agent-chat-adapter.d.ts +5 -0
  60. package/dist/client/agent-chat-adapter.d.ts.map +1 -1
  61. package/dist/client/agent-chat-adapter.js +4 -0
  62. package/dist/client/agent-chat-adapter.js.map +1 -1
  63. package/dist/client/agent-sidebar-state.d.ts +12 -0
  64. package/dist/client/agent-sidebar-state.d.ts.map +1 -1
  65. package/dist/client/agent-sidebar-state.js +8 -0
  66. package/dist/client/agent-sidebar-state.js.map +1 -1
  67. package/dist/client/analytics.d.ts.map +1 -1
  68. package/dist/client/analytics.js +175 -3
  69. package/dist/client/analytics.js.map +1 -1
  70. package/dist/client/appearance.d.ts +40 -0
  71. package/dist/client/appearance.d.ts.map +1 -0
  72. package/dist/client/appearance.js +114 -0
  73. package/dist/client/appearance.js.map +1 -0
  74. package/dist/client/builder-frame.d.ts +1 -0
  75. package/dist/client/builder-frame.d.ts.map +1 -1
  76. package/dist/client/builder-frame.js +19 -9
  77. package/dist/client/builder-frame.js.map +1 -1
  78. package/dist/client/components/CodeRequiredDialog.d.ts.map +1 -1
  79. package/dist/client/components/CodeRequiredDialog.js +10 -2
  80. package/dist/client/components/CodeRequiredDialog.js.map +1 -1
  81. package/dist/client/components/ui/dropdown-menu.js +2 -2
  82. package/dist/client/components/ui/dropdown-menu.js.map +1 -1
  83. package/dist/client/components/ui/hover-card.js +1 -1
  84. package/dist/client/components/ui/hover-card.js.map +1 -1
  85. package/dist/client/components/ui/popover.js +1 -1
  86. package/dist/client/components/ui/popover.js.map +1 -1
  87. package/dist/client/composer/PromptComposer.d.ts +7 -0
  88. package/dist/client/composer/PromptComposer.d.ts.map +1 -1
  89. package/dist/client/composer/PromptComposer.js +63 -32
  90. package/dist/client/composer/PromptComposer.js.map +1 -1
  91. package/dist/client/composer/TiptapComposer.d.ts +5 -0
  92. package/dist/client/composer/TiptapComposer.d.ts.map +1 -1
  93. package/dist/client/composer/TiptapComposer.js +36 -6
  94. package/dist/client/composer/TiptapComposer.js.map +1 -1
  95. package/dist/client/composer/useVoiceDictation.d.ts.map +1 -1
  96. package/dist/client/composer/useVoiceDictation.js +13 -1
  97. package/dist/client/composer/useVoiceDictation.js.map +1 -1
  98. package/dist/client/dev-mode.d.ts +14 -0
  99. package/dist/client/dev-mode.d.ts.map +1 -0
  100. package/dist/client/dev-mode.js +14 -0
  101. package/dist/client/dev-mode.js.map +1 -0
  102. package/dist/client/error-format.d.ts +3 -2
  103. package/dist/client/error-format.d.ts.map +1 -1
  104. package/dist/client/error-format.js +9 -2
  105. package/dist/client/error-format.js.map +1 -1
  106. package/dist/client/extensions/EmbeddedTool.d.ts +20 -0
  107. package/dist/client/extensions/EmbeddedTool.d.ts.map +1 -0
  108. package/dist/client/extensions/EmbeddedTool.js +199 -0
  109. package/dist/client/extensions/EmbeddedTool.js.map +1 -0
  110. package/dist/client/extensions/ExtensionViewer.d.ts.map +1 -1
  111. package/dist/client/extensions/ExtensionViewer.js +24 -2
  112. package/dist/client/extensions/ExtensionViewer.js.map +1 -1
  113. package/dist/client/extensions/ToolEditor.d.ts +5 -0
  114. package/dist/client/extensions/ToolEditor.d.ts.map +1 -0
  115. package/dist/client/extensions/ToolEditor.js +129 -0
  116. package/dist/client/extensions/ToolEditor.js.map +1 -0
  117. package/dist/client/extensions/ToolViewer.d.ts +5 -0
  118. package/dist/client/extensions/ToolViewer.d.ts.map +1 -0
  119. package/dist/client/extensions/ToolViewer.js +400 -0
  120. package/dist/client/extensions/ToolViewer.js.map +1 -0
  121. package/dist/client/extensions/ToolViewerPage.d.ts +2 -0
  122. package/dist/client/extensions/ToolViewerPage.d.ts.map +1 -0
  123. package/dist/client/extensions/ToolViewerPage.js +24 -0
  124. package/dist/client/extensions/ToolViewerPage.js.map +1 -0
  125. package/dist/client/extensions/ToolsListPage.d.ts +2 -0
  126. package/dist/client/extensions/ToolsListPage.d.ts.map +1 -0
  127. package/dist/client/extensions/ToolsListPage.js +67 -0
  128. package/dist/client/extensions/ToolsListPage.js.map +1 -0
  129. package/dist/client/extensions/ToolsSidebarSection.d.ts +2 -0
  130. package/dist/client/extensions/ToolsSidebarSection.d.ts.map +1 -0
  131. package/dist/client/extensions/ToolsSidebarSection.js +236 -0
  132. package/dist/client/extensions/ToolsSidebarSection.js.map +1 -0
  133. package/dist/client/extensions/tool-order.d.ts +7 -0
  134. package/dist/client/extensions/tool-order.d.ts.map +1 -0
  135. package/dist/client/extensions/tool-order.js +47 -0
  136. package/dist/client/extensions/tool-order.js.map +1 -0
  137. package/dist/client/index.d.ts +8 -1
  138. package/dist/client/index.d.ts.map +1 -1
  139. package/dist/client/index.js +7 -0
  140. package/dist/client/index.js.map +1 -1
  141. package/dist/client/onboarding/OnboardingPanel.js +1 -0
  142. package/dist/client/onboarding/OnboardingPanel.js.map +1 -1
  143. package/dist/client/org/InvitationBanner.d.ts.map +1 -1
  144. package/dist/client/org/InvitationBanner.js +23 -2
  145. package/dist/client/org/InvitationBanner.js.map +1 -1
  146. package/dist/client/org/OrgSwitcher.d.ts +5 -4
  147. package/dist/client/org/OrgSwitcher.d.ts.map +1 -1
  148. package/dist/client/org/OrgSwitcher.js +57 -9
  149. package/dist/client/org/OrgSwitcher.js.map +1 -1
  150. package/dist/client/org/hooks.d.ts.map +1 -1
  151. package/dist/client/org/hooks.js +10 -6
  152. package/dist/client/org/hooks.js.map +1 -1
  153. package/dist/client/org/workspace-app-links.d.ts +31 -0
  154. package/dist/client/org/workspace-app-links.d.ts.map +1 -0
  155. package/dist/client/org/workspace-app-links.js +268 -0
  156. package/dist/client/org/workspace-app-links.js.map +1 -0
  157. package/dist/client/resources/ResourcesPanel.d.ts.map +1 -1
  158. package/dist/client/resources/ResourcesPanel.js +18 -5
  159. package/dist/client/resources/ResourcesPanel.js.map +1 -1
  160. package/dist/client/resources/use-resources.d.ts +18 -13
  161. package/dist/client/resources/use-resources.d.ts.map +1 -1
  162. package/dist/client/resources/use-resources.js +24 -6
  163. package/dist/client/resources/use-resources.js.map +1 -1
  164. package/dist/client/settings/BackgroundAgentSection.d.ts.map +1 -1
  165. package/dist/client/settings/BackgroundAgentSection.js +9 -1
  166. package/dist/client/settings/BackgroundAgentSection.js.map +1 -1
  167. package/dist/client/settings/BrowserSection.d.ts.map +1 -1
  168. package/dist/client/settings/BrowserSection.js +16 -1
  169. package/dist/client/settings/BrowserSection.js.map +1 -1
  170. package/dist/client/settings/SettingsPanel.d.ts.map +1 -1
  171. package/dist/client/settings/SettingsPanel.js +4 -1
  172. package/dist/client/settings/SettingsPanel.js.map +1 -1
  173. package/dist/client/settings/VoiceTranscriptionSection.d.ts.map +1 -1
  174. package/dist/client/settings/VoiceTranscriptionSection.js +5 -5
  175. package/dist/client/settings/VoiceTranscriptionSection.js.map +1 -1
  176. package/dist/client/settings/useBuilderStatus.d.ts +8 -0
  177. package/dist/client/settings/useBuilderStatus.d.ts.map +1 -1
  178. package/dist/client/settings/useBuilderStatus.js +50 -13
  179. package/dist/client/settings/useBuilderStatus.js.map +1 -1
  180. package/dist/client/settings/useBuilderStatus.spec.d.ts +2 -0
  181. package/dist/client/settings/useBuilderStatus.spec.d.ts.map +1 -0
  182. package/dist/client/settings/useBuilderStatus.spec.js +64 -0
  183. package/dist/client/settings/useBuilderStatus.spec.js.map +1 -0
  184. package/dist/client/sharing/ShareButton.d.ts +5 -0
  185. package/dist/client/sharing/ShareButton.d.ts.map +1 -1
  186. package/dist/client/sharing/ShareButton.js +60 -6
  187. package/dist/client/sharing/ShareButton.js.map +1 -1
  188. package/dist/client/theme.js +1 -1
  189. package/dist/client/theme.js.map +1 -1
  190. package/dist/client/tools/EmbeddedTool.d.ts +20 -0
  191. package/dist/client/tools/EmbeddedTool.d.ts.map +1 -0
  192. package/dist/client/tools/EmbeddedTool.js +199 -0
  193. package/dist/client/tools/EmbeddedTool.js.map +1 -0
  194. package/dist/client/tools/ExtensionSlot.d.ts +27 -0
  195. package/dist/client/tools/ExtensionSlot.d.ts.map +1 -0
  196. package/dist/client/tools/ExtensionSlot.js +96 -0
  197. package/dist/client/tools/ExtensionSlot.js.map +1 -0
  198. package/dist/client/tools/ToolEditor.d.ts +5 -0
  199. package/dist/client/tools/ToolEditor.d.ts.map +1 -0
  200. package/dist/client/tools/ToolEditor.js +129 -0
  201. package/dist/client/tools/ToolEditor.js.map +1 -0
  202. package/dist/client/tools/ToolViewer.d.ts +5 -0
  203. package/dist/client/tools/ToolViewer.d.ts.map +1 -0
  204. package/dist/client/tools/ToolViewer.js +400 -0
  205. package/dist/client/tools/ToolViewer.js.map +1 -0
  206. package/dist/client/tools/ToolViewerPage.d.ts +2 -0
  207. package/dist/client/tools/ToolViewerPage.d.ts.map +1 -0
  208. package/dist/client/tools/ToolViewerPage.js +24 -0
  209. package/dist/client/tools/ToolViewerPage.js.map +1 -0
  210. package/dist/client/tools/ToolsListPage.d.ts +2 -0
  211. package/dist/client/tools/ToolsListPage.d.ts.map +1 -0
  212. package/dist/client/tools/ToolsListPage.js +67 -0
  213. package/dist/client/tools/ToolsListPage.js.map +1 -0
  214. package/dist/client/tools/ToolsSidebarSection.d.ts +2 -0
  215. package/dist/client/tools/ToolsSidebarSection.d.ts.map +1 -0
  216. package/dist/client/tools/ToolsSidebarSection.js +236 -0
  217. package/dist/client/tools/ToolsSidebarSection.js.map +1 -0
  218. package/dist/client/tools/iframe-bridge.d.ts +38 -0
  219. package/dist/client/tools/iframe-bridge.d.ts.map +1 -0
  220. package/dist/client/tools/iframe-bridge.js +207 -0
  221. package/dist/client/tools/iframe-bridge.js.map +1 -0
  222. package/dist/client/tools/index.d.ts +8 -0
  223. package/dist/client/tools/index.d.ts.map +1 -0
  224. package/dist/client/tools/index.js +8 -0
  225. package/dist/client/tools/index.js.map +1 -0
  226. package/dist/client/tools/tool-order.d.ts +7 -0
  227. package/dist/client/tools/tool-order.d.ts.map +1 -0
  228. package/dist/client/tools/tool-order.js +47 -0
  229. package/dist/client/tools/tool-order.js.map +1 -0
  230. package/dist/client/transcription/BuilderTranscriptionCta.d.ts.map +1 -1
  231. package/dist/client/transcription/BuilderTranscriptionCta.js +2 -3
  232. package/dist/client/transcription/BuilderTranscriptionCta.js.map +1 -1
  233. package/dist/client/use-change-version.d.ts +46 -0
  234. package/dist/client/use-change-version.d.ts.map +1 -0
  235. package/dist/client/use-change-version.js +135 -0
  236. package/dist/client/use-change-version.js.map +1 -0
  237. package/dist/client/use-chat-threads.d.ts +16 -2
  238. package/dist/client/use-chat-threads.d.ts.map +1 -1
  239. package/dist/client/use-chat-threads.js +87 -12
  240. package/dist/client/use-chat-threads.js.map +1 -1
  241. package/dist/client/use-chat-threads.spec.d.ts +2 -0
  242. package/dist/client/use-chat-threads.spec.d.ts.map +1 -0
  243. package/dist/client/use-chat-threads.spec.js +85 -0
  244. package/dist/client/use-chat-threads.spec.js.map +1 -0
  245. package/dist/client/use-db-sync.d.ts +5 -2
  246. package/dist/client/use-db-sync.d.ts.map +1 -1
  247. package/dist/client/use-db-sync.js +41 -16
  248. package/dist/client/use-db-sync.js.map +1 -1
  249. package/dist/client/use-pinch-zoom.d.ts +35 -0
  250. package/dist/client/use-pinch-zoom.d.ts.map +1 -0
  251. package/dist/client/use-pinch-zoom.js +105 -0
  252. package/dist/client/use-pinch-zoom.js.map +1 -0
  253. package/dist/deploy/workspace-deploy.d.ts.map +1 -1
  254. package/dist/deploy/workspace-deploy.js +99 -5
  255. package/dist/deploy/workspace-deploy.js.map +1 -1
  256. package/dist/extensions/actions.d.ts.map +1 -1
  257. package/dist/extensions/actions.js +3 -0
  258. package/dist/extensions/actions.js.map +1 -1
  259. package/dist/extensions/store.d.ts +5 -0
  260. package/dist/extensions/store.d.ts.map +1 -1
  261. package/dist/extensions/store.js +16 -1
  262. package/dist/extensions/store.js.map +1 -1
  263. package/dist/file-upload/actions/upload-image.d.ts +3 -0
  264. package/dist/file-upload/actions/upload-image.d.ts.map +1 -0
  265. package/dist/file-upload/actions/upload-image.js +145 -0
  266. package/dist/file-upload/actions/upload-image.js.map +1 -0
  267. package/dist/file-upload/builder.d.ts.map +1 -1
  268. package/dist/file-upload/builder.js +31 -11
  269. package/dist/file-upload/builder.js.map +1 -1
  270. package/dist/file-upload/index.d.ts +1 -0
  271. package/dist/file-upload/index.d.ts.map +1 -1
  272. package/dist/file-upload/index.js +1 -0
  273. package/dist/file-upload/index.js.map +1 -1
  274. package/dist/file-upload/pre-upload-attachments.d.ts +39 -0
  275. package/dist/file-upload/pre-upload-attachments.d.ts.map +1 -0
  276. package/dist/file-upload/pre-upload-attachments.js +110 -0
  277. package/dist/file-upload/pre-upload-attachments.js.map +1 -0
  278. package/dist/file-upload/registry.d.ts.map +1 -1
  279. package/dist/file-upload/registry.js +8 -7
  280. package/dist/file-upload/registry.js.map +1 -1
  281. package/dist/onboarding/default-steps.js +1 -1
  282. package/dist/onboarding/default-steps.js.map +1 -1
  283. package/dist/org/context.d.ts +15 -1
  284. package/dist/org/context.d.ts.map +1 -1
  285. package/dist/org/context.js +25 -0
  286. package/dist/org/context.js.map +1 -1
  287. package/dist/org/handlers.d.ts +2 -2
  288. package/dist/org/handlers.d.ts.map +1 -1
  289. package/dist/org/handlers.js +3 -17
  290. package/dist/org/handlers.js.map +1 -1
  291. package/dist/org/index.d.ts +1 -1
  292. package/dist/org/index.d.ts.map +1 -1
  293. package/dist/org/index.js +1 -1
  294. package/dist/org/index.js.map +1 -1
  295. package/dist/resources/handlers.d.ts +6 -0
  296. package/dist/resources/handlers.d.ts.map +1 -1
  297. package/dist/resources/handlers.js +30 -6
  298. package/dist/resources/handlers.js.map +1 -1
  299. package/dist/resources/script-helpers.d.ts +11 -2
  300. package/dist/resources/script-helpers.d.ts.map +1 -1
  301. package/dist/resources/script-helpers.js +20 -3
  302. package/dist/resources/script-helpers.js.map +1 -1
  303. package/dist/resources/store.d.ts +28 -3
  304. package/dist/resources/store.d.ts.map +1 -1
  305. package/dist/resources/store.js +170 -20
  306. package/dist/resources/store.js.map +1 -1
  307. package/dist/scripts/resources/list.d.ts +1 -1
  308. package/dist/scripts/resources/list.d.ts.map +1 -1
  309. package/dist/scripts/resources/list.js +16 -4
  310. package/dist/scripts/resources/list.js.map +1 -1
  311. package/dist/scripts/resources/write.d.ts +1 -1
  312. package/dist/scripts/resources/write.d.ts.map +1 -1
  313. package/dist/scripts/resources/write.js +47 -3
  314. package/dist/scripts/resources/write.js.map +1 -1
  315. package/dist/server/action-discovery.d.ts.map +1 -1
  316. package/dist/server/action-discovery.js +8 -3
  317. package/dist/server/action-discovery.js.map +1 -1
  318. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  319. package/dist/server/agent-chat-plugin.js +214 -25
  320. package/dist/server/agent-chat-plugin.js.map +1 -1
  321. package/dist/server/agent-discovery.d.ts +35 -0
  322. package/dist/server/agent-discovery.d.ts.map +1 -1
  323. package/dist/server/agent-discovery.js +139 -8
  324. package/dist/server/agent-discovery.js.map +1 -1
  325. package/dist/server/app-url.d.ts +12 -6
  326. package/dist/server/app-url.d.ts.map +1 -1
  327. package/dist/server/app-url.js +58 -11
  328. package/dist/server/app-url.js.map +1 -1
  329. package/dist/server/auth.d.ts +22 -0
  330. package/dist/server/auth.d.ts.map +1 -1
  331. package/dist/server/auth.js +316 -65
  332. package/dist/server/auth.js.map +1 -1
  333. package/dist/server/better-auth-instance.d.ts +0 -4
  334. package/dist/server/better-auth-instance.d.ts.map +1 -1
  335. package/dist/server/better-auth-instance.js +0 -3
  336. package/dist/server/better-auth-instance.js.map +1 -1
  337. package/dist/server/builder-browser.d.ts.map +1 -1
  338. package/dist/server/builder-browser.js +23 -0
  339. package/dist/server/builder-browser.js.map +1 -1
  340. package/dist/server/core-routes-plugin.d.ts.map +1 -1
  341. package/dist/server/core-routes-plugin.js +29 -14
  342. package/dist/server/core-routes-plugin.js.map +1 -1
  343. package/dist/server/credential-provider.d.ts +14 -0
  344. package/dist/server/credential-provider.d.ts.map +1 -1
  345. package/dist/server/credential-provider.js +88 -11
  346. package/dist/server/credential-provider.js.map +1 -1
  347. package/dist/server/google-auth-plugin.d.ts.map +1 -1
  348. package/dist/server/google-auth-plugin.js +65 -17
  349. package/dist/server/google-auth-plugin.js.map +1 -1
  350. package/dist/server/google-oauth.d.ts.map +1 -1
  351. package/dist/server/google-oauth.js +47 -17
  352. package/dist/server/google-oauth.js.map +1 -1
  353. package/dist/server/index.d.ts +1 -1
  354. package/dist/server/index.d.ts.map +1 -1
  355. package/dist/server/index.js +1 -1
  356. package/dist/server/index.js.map +1 -1
  357. package/dist/server/local-migration.d.ts +41 -0
  358. package/dist/server/local-migration.d.ts.map +1 -0
  359. package/dist/server/local-migration.js +235 -0
  360. package/dist/server/local-migration.js.map +1 -0
  361. package/dist/server/oauth-public-origin.d.ts.map +1 -1
  362. package/dist/server/oauth-public-origin.js +19 -1
  363. package/dist/server/oauth-public-origin.js.map +1 -1
  364. package/dist/server/onboarding-html.d.ts.map +1 -1
  365. package/dist/server/onboarding-html.js +74 -19
  366. package/dist/server/onboarding-html.js.map +1 -1
  367. package/dist/server/poll.d.ts.map +1 -1
  368. package/dist/server/poll.js +20 -5
  369. package/dist/server/poll.js.map +1 -1
  370. package/dist/server/request-context.d.ts +8 -0
  371. package/dist/server/request-context.d.ts.map +1 -1
  372. package/dist/server/request-context.js.map +1 -1
  373. package/dist/shared/index.d.ts +2 -0
  374. package/dist/shared/index.d.ts.map +1 -1
  375. package/dist/shared/index.js +2 -0
  376. package/dist/shared/index.js.map +1 -1
  377. package/dist/shared/llm-connection.d.ts +10 -0
  378. package/dist/shared/llm-connection.d.ts.map +1 -0
  379. package/dist/shared/llm-connection.js +29 -0
  380. package/dist/shared/llm-connection.js.map +1 -0
  381. package/dist/shared/workspace-app-audience.d.ts +25 -0
  382. package/dist/shared/workspace-app-audience.d.ts.map +1 -0
  383. package/dist/shared/workspace-app-audience.js +126 -0
  384. package/dist/shared/workspace-app-audience.js.map +1 -0
  385. package/dist/shared/workspace-app-id.d.ts +1 -1
  386. package/dist/shared/workspace-app-id.d.ts.map +1 -1
  387. package/dist/shared/workspace-app-id.js +1 -0
  388. package/dist/shared/workspace-app-id.js.map +1 -1
  389. package/dist/sharing/access.d.ts.map +1 -1
  390. package/dist/sharing/access.js +46 -5
  391. package/dist/sharing/access.js.map +1 -1
  392. package/dist/sharing/actions/list-resource-shares.d.ts.map +1 -1
  393. package/dist/sharing/actions/list-resource-shares.js +8 -1
  394. package/dist/sharing/actions/list-resource-shares.js.map +1 -1
  395. package/dist/sharing/actions/set-resource-visibility.d.ts.map +1 -1
  396. package/dist/sharing/actions/set-resource-visibility.js +12 -3
  397. package/dist/sharing/actions/set-resource-visibility.js.map +1 -1
  398. package/dist/sharing/actions/share-resource.d.ts.map +1 -1
  399. package/dist/sharing/actions/share-resource.js +50 -1
  400. package/dist/sharing/actions/share-resource.js.map +1 -1
  401. package/dist/sharing/registry.d.ts +26 -0
  402. package/dist/sharing/registry.d.ts.map +1 -1
  403. package/dist/sharing/registry.js.map +1 -1
  404. package/dist/styles/agent-native.css +91 -0
  405. package/dist/templates/default/.agents/skills/adding-a-feature/SKILL.md +72 -0
  406. package/dist/templates/default/.agents/skills/frontend-design/SKILL.md +60 -37
  407. package/dist/templates/default/.agents/skills/real-time-sync/SKILL.md +28 -17
  408. package/dist/templates/default/.agents/skills/shadcn-ui/SKILL.md +79 -0
  409. package/dist/templates/default/AGENTS.md +22 -19
  410. package/dist/templates/default/actions/navigate.ts +3 -0
  411. package/dist/templates/default/app/hooks/use-navigation-state.ts +29 -5
  412. package/dist/templates/workspace-core/.agents/skills/a2a-protocol/SKILL.md +251 -0
  413. package/dist/templates/workspace-core/.agents/skills/actions/SKILL.md +264 -0
  414. package/dist/templates/workspace-core/.agents/skills/adding-a-feature/SKILL.md +130 -0
  415. package/dist/templates/workspace-core/.agents/skills/address-feedback/SKILL.md +112 -0
  416. package/dist/templates/workspace-core/.agents/skills/authentication/SKILL.md +88 -0
  417. package/dist/templates/workspace-core/.agents/skills/automations/SKILL.md +191 -0
  418. package/dist/templates/workspace-core/.agents/skills/capture-learnings/SKILL.md +74 -0
  419. package/dist/templates/workspace-core/.agents/skills/client-side-routing/SKILL.md +75 -0
  420. package/dist/templates/workspace-core/.agents/skills/context-awareness/SKILL.md +190 -0
  421. package/dist/templates/workspace-core/.agents/skills/create-skill/SKILL.md +168 -0
  422. package/dist/templates/workspace-core/.agents/skills/delegate-to-agent/SKILL.md +163 -0
  423. package/dist/templates/workspace-core/.agents/skills/extension-points/SKILL.md +205 -0
  424. package/dist/templates/workspace-core/.agents/skills/extensions/SKILL.md +720 -0
  425. package/dist/templates/workspace-core/.agents/skills/frontend-design/SKILL.md +92 -0
  426. package/dist/templates/workspace-core/.agents/skills/integration-webhooks/SKILL.md +285 -0
  427. package/dist/templates/workspace-core/.agents/skills/observability/SKILL.md +192 -0
  428. package/dist/templates/workspace-core/.agents/skills/onboarding/SKILL.md +43 -0
  429. package/dist/templates/workspace-core/.agents/skills/portability/SKILL.md +84 -0
  430. package/dist/templates/workspace-core/.agents/skills/qa/SKILL.md +313 -0
  431. package/dist/templates/workspace-core/.agents/skills/real-time-collab/SKILL.md +112 -0
  432. package/dist/templates/workspace-core/.agents/skills/real-time-sync/SKILL.md +165 -0
  433. package/dist/templates/workspace-core/.agents/skills/recurring-jobs/SKILL.md +41 -0
  434. package/dist/templates/workspace-core/.agents/skills/secrets/SKILL.md +239 -0
  435. package/dist/templates/workspace-core/.agents/skills/security/SKILL.md +191 -0
  436. package/dist/templates/workspace-core/.agents/skills/self-modifying-code/SKILL.md +79 -0
  437. package/dist/templates/workspace-core/.agents/skills/server-plugins/SKILL.md +73 -0
  438. package/dist/templates/workspace-core/.agents/skills/shadcn-ui/SKILL.md +79 -0
  439. package/dist/templates/workspace-core/.agents/skills/sharing/SKILL.md +217 -0
  440. package/dist/templates/workspace-core/.agents/skills/storing-data/SKILL.md +132 -0
  441. package/dist/templates/workspace-core/.agents/skills/tracking/SKILL.md +150 -0
  442. package/dist/templates/workspace-core/.agents/skills/voice-transcription/SKILL.md +124 -0
  443. package/dist/templates/workspace-core/AGENTS.md +16 -1
  444. package/dist/templates/workspace-root/AGENTS.md +35 -0
  445. package/dist/templates/workspace-root/README.md +7 -0
  446. package/dist/tools/actions.d.ts +3 -0
  447. package/dist/tools/actions.d.ts.map +1 -0
  448. package/dist/tools/actions.js +272 -0
  449. package/dist/tools/actions.js.map +1 -0
  450. package/dist/tools/fetch-tool.d.ts +23 -0
  451. package/dist/tools/fetch-tool.d.ts.map +1 -0
  452. package/dist/tools/fetch-tool.js +178 -0
  453. package/dist/tools/fetch-tool.js.map +1 -0
  454. package/dist/tools/html-shell.d.ts +45 -0
  455. package/dist/tools/html-shell.d.ts.map +1 -0
  456. package/dist/tools/html-shell.js +514 -0
  457. package/dist/tools/html-shell.js.map +1 -0
  458. package/dist/tools/proxy-security.d.ts +12 -0
  459. package/dist/tools/proxy-security.d.ts.map +1 -0
  460. package/dist/tools/proxy-security.js +158 -0
  461. package/dist/tools/proxy-security.js.map +1 -0
  462. package/dist/tools/routes.d.ts +2 -0
  463. package/dist/tools/routes.d.ts.map +1 -0
  464. package/dist/tools/routes.js +627 -0
  465. package/dist/tools/routes.js.map +1 -0
  466. package/dist/tools/schema.d.ts +664 -0
  467. package/dist/tools/schema.d.ts.map +1 -0
  468. package/dist/tools/schema.js +146 -0
  469. package/dist/tools/schema.js.map +1 -0
  470. package/dist/tools/slots/routes.d.ts +15 -0
  471. package/dist/tools/slots/routes.d.ts.map +1 -0
  472. package/dist/tools/slots/routes.js +94 -0
  473. package/dist/tools/slots/routes.js.map +1 -0
  474. package/dist/tools/slots/schema.d.ts +303 -0
  475. package/dist/tools/slots/schema.d.ts.map +1 -0
  476. package/dist/tools/slots/schema.js +76 -0
  477. package/dist/tools/slots/schema.js.map +1 -0
  478. package/dist/tools/slots/store.d.ts +66 -0
  479. package/dist/tools/slots/store.d.ts.map +1 -0
  480. package/dist/tools/slots/store.js +227 -0
  481. package/dist/tools/slots/store.js.map +1 -0
  482. package/dist/tools/store.d.ts +40 -0
  483. package/dist/tools/store.d.ts.map +1 -0
  484. package/dist/tools/store.js +193 -0
  485. package/dist/tools/store.js.map +1 -0
  486. package/dist/tools/theme.d.ts +2 -0
  487. package/dist/tools/theme.d.ts.map +1 -0
  488. package/dist/tools/theme.js +67 -0
  489. package/dist/tools/theme.js.map +1 -0
  490. package/dist/tools/url-safety.d.ts +24 -0
  491. package/dist/tools/url-safety.d.ts.map +1 -0
  492. package/dist/tools/url-safety.js +224 -0
  493. package/dist/tools/url-safety.js.map +1 -0
  494. package/dist/vite/action-types-plugin.d.ts.map +1 -1
  495. package/dist/vite/action-types-plugin.js +4 -0
  496. package/dist/vite/action-types-plugin.js.map +1 -1
  497. package/docs/content/authentication.md +36 -0
  498. package/docs/content/creating-templates.md +15 -0
  499. package/docs/content/dispatch.md +3 -3
  500. package/docs/content/multi-app-workspace.md +5 -0
  501. package/docs/content/tracking.md +12 -0
  502. package/docs/content/workspace-management.md +39 -4
  503. package/package.json +15 -12
  504. package/src/templates/default/.agents/skills/adding-a-feature/SKILL.md +72 -0
  505. package/src/templates/default/.agents/skills/frontend-design/SKILL.md +60 -37
  506. package/src/templates/default/.agents/skills/real-time-sync/SKILL.md +28 -17
  507. package/src/templates/default/.agents/skills/shadcn-ui/SKILL.md +79 -0
  508. package/src/templates/default/AGENTS.md +22 -19
  509. package/src/templates/default/actions/navigate.ts +3 -0
  510. package/src/templates/default/app/hooks/use-navigation-state.ts +29 -5
  511. package/src/templates/workspace-core/.agents/skills/a2a-protocol/SKILL.md +251 -0
  512. package/src/templates/workspace-core/.agents/skills/actions/SKILL.md +264 -0
  513. package/src/templates/workspace-core/.agents/skills/adding-a-feature/SKILL.md +130 -0
  514. package/src/templates/workspace-core/.agents/skills/address-feedback/SKILL.md +112 -0
  515. package/src/templates/workspace-core/.agents/skills/authentication/SKILL.md +88 -0
  516. package/src/templates/workspace-core/.agents/skills/automations/SKILL.md +191 -0
  517. package/src/templates/workspace-core/.agents/skills/capture-learnings/SKILL.md +74 -0
  518. package/src/templates/workspace-core/.agents/skills/client-side-routing/SKILL.md +75 -0
  519. package/src/templates/workspace-core/.agents/skills/context-awareness/SKILL.md +190 -0
  520. package/src/templates/workspace-core/.agents/skills/create-skill/SKILL.md +168 -0
  521. package/src/templates/workspace-core/.agents/skills/delegate-to-agent/SKILL.md +163 -0
  522. package/src/templates/workspace-core/.agents/skills/extension-points/SKILL.md +205 -0
  523. package/src/templates/workspace-core/.agents/skills/extensions/SKILL.md +720 -0
  524. package/src/templates/workspace-core/.agents/skills/frontend-design/SKILL.md +92 -0
  525. package/src/templates/workspace-core/.agents/skills/integration-webhooks/SKILL.md +285 -0
  526. package/src/templates/workspace-core/.agents/skills/observability/SKILL.md +192 -0
  527. package/src/templates/workspace-core/.agents/skills/onboarding/SKILL.md +43 -0
  528. package/src/templates/workspace-core/.agents/skills/portability/SKILL.md +84 -0
  529. package/src/templates/workspace-core/.agents/skills/qa/SKILL.md +313 -0
  530. package/src/templates/workspace-core/.agents/skills/real-time-collab/SKILL.md +112 -0
  531. package/src/templates/workspace-core/.agents/skills/real-time-sync/SKILL.md +165 -0
  532. package/src/templates/workspace-core/.agents/skills/recurring-jobs/SKILL.md +41 -0
  533. package/src/templates/workspace-core/.agents/skills/secrets/SKILL.md +239 -0
  534. package/src/templates/workspace-core/.agents/skills/security/SKILL.md +191 -0
  535. package/src/templates/workspace-core/.agents/skills/self-modifying-code/SKILL.md +79 -0
  536. package/src/templates/workspace-core/.agents/skills/server-plugins/SKILL.md +73 -0
  537. package/src/templates/workspace-core/.agents/skills/shadcn-ui/SKILL.md +79 -0
  538. package/src/templates/workspace-core/.agents/skills/sharing/SKILL.md +217 -0
  539. package/src/templates/workspace-core/.agents/skills/storing-data/SKILL.md +132 -0
  540. package/src/templates/workspace-core/.agents/skills/tracking/SKILL.md +150 -0
  541. package/src/templates/workspace-core/.agents/skills/voice-transcription/SKILL.md +124 -0
  542. package/src/templates/workspace-core/AGENTS.md +16 -1
  543. package/src/templates/workspace-root/AGENTS.md +35 -0
  544. package/src/templates/workspace-root/README.md +7 -0
@@ -0,0 +1,720 @@
1
+ ---
2
+ name: extensions
3
+ description: >-
4
+ Creating, editing, and managing extensions — sandboxed Alpine.js mini-apps
5
+ that run inside iframes. Use when a user asks for a dashboard, widget,
6
+ calculator, or any interactive mini-app that calls external APIs. Distinct
7
+ from LLM "tools" (function calls) — see note below.
8
+ ---
9
+
10
+ # Extensions
11
+
12
+ > **Terminology note.** This skill is about **extensions** — the framework's
13
+ > user-authored mini-app primitive (sandboxed Alpine.js HTML rendered in an
14
+ > iframe). It is NOT the same thing as **LLM "tools"**, which are the
15
+ > function-calling primitives the AI agent uses (actions, MCP tools, etc.).
16
+ > Other skills still talk about "the agent calls actions as tools" — that's
17
+ > the LLM concept and stays as-is. When this doc says "tool" without
18
+ > qualification, it means LLM tool. When it says "extension", it means the
19
+ > sandboxed mini-app.
20
+ >
21
+ > Historical naming: extensions were previously called "tools". The physical
22
+ > SQL table names (`tools`, `tool_data`, `tool_shares`) and a few legacy
23
+ > in-iframe globals (`toolFetch`, `toolData`) are kept for back-compat — see
24
+ > the relevant sections below.
25
+
26
+ ## CRITICAL: What Extensions Are (and Are Not)
27
+
28
+ An Extension is a **self-contained Alpine.js HTML snippet** stored in the
29
+ SQL `tools` table (table name kept for back-compat; the Drizzle export is
30
+ `extensions`). It runs inside a sandboxed iframe with its own Tailwind CSS
31
+ and Alpine.js runtime.
32
+
33
+ **Extensions are NOT:**
34
+
35
+ - React components
36
+ - New source code files
37
+ - Database schema changes
38
+ - Action files in `actions/`
39
+ - Routes
40
+
41
+ **When a user asks to "make an extension", "create an extension", or "build
42
+ a ... extension" (or the older phrasings "make a tool" / "create a tool"):**
43
+
44
+ 1. Write the Alpine.js HTML
45
+ 2. Call `create-extension` with the HTML as `content`
46
+ 3. That's it — no files to create, no schema changes, no actions
47
+
48
+ Extensions have full access to app data via helpers injected into the iframe:
49
+
50
+ - `appAction(name, params)` — call any app action
51
+ - `appFetch(path, options)` — call allowed framework endpoints under
52
+ `/_agent-native/*`
53
+ - `dbQuery(sql, args)` — read from SQL
54
+ - `dbExec(sql, args)` — write to SQL
55
+ - `extensionFetch(url, options)` — call external APIs via proxy. Legacy
56
+ alias: `toolFetch` — kept for back-compat with extension bodies authored
57
+ before the rename; both names refer to the same helper.
58
+ - `extensionData.set/list/get/remove(collection, ...)` — persist custom data
59
+ per-extension (supports `{ scope: 'user' | 'org' | 'all' }` option). Legacy
60
+ alias: `toolData` — kept for back-compat; both names refer to the same
61
+ store.
62
+
63
+ ## Data Persistence is Built In
64
+
65
+ **Every extension has `extensionData` — a per-extension key-value store. NO
66
+ source code changes, NO Builder, NO new tables needed.**
67
+
68
+ When a user asks to "add persistence", "save data", "remember state", or
69
+ "store settings" in an extension, use `extensionData`. It handles table
70
+ creation, scoping, and upserts automatically. Data is organized into
71
+ collections per-extension:
72
+
73
+ ```javascript
74
+ // Save a private item (default — only the current user can see it)
75
+ await extensionData.set('notes', 'note-1', { title: 'My Note', body: 'Hello' });
76
+
77
+ // Save an org-shared item (visible to everyone in the org)
78
+ await extensionData.set('notes', 'note-1', { title: 'Team Note', body: 'Hello' }, { scope: 'org' });
79
+
80
+ // List items by scope
81
+ const myNotes = await extensionData.list('notes'); // user-scoped (default)
82
+ const orgNotes = await extensionData.list('notes', { scope: 'org' }); // org-scoped only
83
+ const allNotes = await extensionData.list('notes', { scope: 'all' }); // both user + org
84
+
85
+ // Get one item
86
+ const note = await extensionData.get('notes', 'note-1'); // user-scoped
87
+ const orgNote = await extensionData.get('notes', 'note-1', { scope: 'org' }); // org-scoped
88
+
89
+ // Delete an item
90
+ await extensionData.remove('notes', 'note-1'); // user-scoped
91
+ await extensionData.remove('notes', 'note-1', { scope: 'org' }); // org-scoped
92
+ ```
93
+
94
+ > The legacy global `toolData` is still injected and points at the same
95
+ > store — older extension bodies that reference `toolData.set(...)` continue
96
+ > to work without changes. Prefer `extensionData` in new code.
97
+
98
+ **Prefer `extensionData` over raw `dbExec` for extension-specific
99
+ persistence** — it handles everything automatically. Only use
100
+ `dbQuery`/`dbExec` when querying the app's existing tables.
101
+
102
+ ## What extensions are
103
+
104
+ Extensions are mini Alpine.js apps that run inside sandboxed iframes. They
105
+ can call external APIs via `extensionFetch()`, which routes through a
106
+ server-side proxy that injects secret values. Extensions share the main
107
+ app's Tailwind v4 theme automatically.
108
+
109
+ ## Creating an extension
110
+
111
+ Call the `create-extension` action:
112
+
113
+ ```bash
114
+ pnpm action create-extension \
115
+ --name "GitHub PR Dashboard" \
116
+ --description "Shows open PRs for the repo" \
117
+ --content '<div x-data="{ prs: [], loading: true }" x-init="extensionFetch('"'"'https://api.github.com/repos/OWNER/REPO/pulls'"'"', { headers: { '"'"'Authorization'"'"': '"'"'Bearer ${keys.GITHUB_TOKEN}'"'"' }}).then(r => r.json()).then(d => { prs = d; loading = false })"><template x-if="loading"><p>Loading...</p></template><div class="space-y-2"><template x-for="pr in prs" :key="pr.id"><a :href="pr.html_url" target="_blank" class="block rounded-lg border p-3 hover:bg-accent"><p class="font-medium" x-text="pr.title"></p><p class="text-sm text-muted-foreground" x-text="'"'"'#'"'"' + pr.number + '"'"' by '"'"' + pr.user.login"></p></a></template></div></div>'
118
+ ```
119
+
120
+ Or via the HTTP API:
121
+
122
+ ```
123
+ POST /_agent-native/extensions
124
+ { "name": "GitHub PR Dashboard", "description": "Shows open PRs", "content": "<div ...>...</div>" }
125
+ ```
126
+
127
+ The action accepts:
128
+
129
+ | Field | Type | Required | Purpose |
130
+ | ------------- | -------- | -------- | ----------------------------- |
131
+ | `name` | `string` | yes | Display name of the extension |
132
+ | `description` | `string` | no | Short summary |
133
+ | `content` | `string` | yes | Alpine.js HTML body |
134
+
135
+ ## Editing an extension
136
+
137
+ Use the `update-extension` action. Prefer `patches` for surgical edits
138
+ instead of regenerating the full HTML:
139
+
140
+ ```
141
+ PUT /_agent-native/extensions/:id
142
+ {
143
+ "patches": [
144
+ { "find": "old HTML fragment", "replace": "new HTML fragment" }
145
+ ]
146
+ }
147
+ ```
148
+
149
+ Each patch does a string find-and-replace on the current content. Use this
150
+ to change a single element, fix a URL, or update a class without rewriting
151
+ everything.
152
+
153
+ To replace the full content instead:
154
+
155
+ ```
156
+ PUT /_agent-native/extensions/:id
157
+ { "content": "full new HTML" }
158
+ ```
159
+
160
+ ## Alpine.js patterns
161
+
162
+ Extension HTML uses Alpine.js directives for reactivity. No build step, no
163
+ imports.
164
+
165
+ | Directive | Purpose | Example |
166
+ | --------------- | ----------------------------- | ------------------------------------------ |
167
+ | `x-data` | Reactive state object | `x-data="{ count: 0, items: [] }"` |
168
+ | `x-init` | Run on mount (fetch data) | `x-init="fetchData()"` |
169
+ | `x-show` | Toggle visibility | `x-show="isOpen"` |
170
+ | `x-if` | Conditional render (template) | `<template x-if="loaded">...</template>` |
171
+ | `x-for` | Loop | `<template x-for="item in items">...</template>` |
172
+ | `x-text` | Set text content | `x-text="item.name"` |
173
+ | `x-html` | Set inner HTML | `x-html="item.richContent"` |
174
+ | `x-on:click` | Event handler | `x-on:click="count++"` |
175
+ | `x-model` | Two-way binding | `x-model="searchQuery"` |
176
+ | `x-bind:class` | Dynamic classes | `x-bind:class="{ 'font-bold': active }"` |
177
+
178
+ Always wrap `x-if` and `x-for` in a `<template>` tag.
179
+
180
+ ## Component shape: inline `x-data` vs. `Alpine.data()`
181
+
182
+ For trivial components (a couple of state fields, no methods, no string
183
+ templating) inline `x-data="{ count: 0, items: [] }"` is fine. **For anything
184
+ beyond that — multiple methods, string formatting, classification logic,
185
+ async fetches with branching — put the component in a `<script>` block and
186
+ register it with `Alpine.data()`.** The inline form is a string inside an
187
+ HTML attribute; the longer it gets the more fragile it becomes (one stray
188
+ quote, one closing-tag-shaped substring, one template literal and the
189
+ attribute terminates early — Alpine then evaluates a half-parsed expression
190
+ and throws `ReferenceError: <var> is not defined`).
191
+
192
+ **Use this pattern for any non-trivial extension:**
193
+
194
+ ```html
195
+ <div x-data="customerAnalyzer" class="p-4">
196
+ <button @click="analyze()" class="rounded-md bg-primary px-4 py-2 text-sm text-primary-foreground cursor-pointer">
197
+ Analyze
198
+ </button>
199
+ <template x-if="error"><p class="text-red-500" x-text="error"></p></template>
200
+ <template x-if="results">
201
+ <div class="space-y-2">
202
+ <div class="rounded-lg border p-3">
203
+ <p class="font-medium">Action — Builder Side</p>
204
+ <p class="text-sm text-muted-foreground" x-text="results.builderActions.length + ' items'"></p>
205
+ </div>
206
+ <!-- ...other buckets... -->
207
+ </div>
208
+ </template>
209
+ </div>
210
+
211
+ <script>
212
+ document.addEventListener('alpine:init', () => {
213
+ Alpine.data('customerAnalyzer', () => ({
214
+ loading: false,
215
+ error: '',
216
+ results: null,
217
+ async analyze() {
218
+ this.loading = true;
219
+ this.error = '';
220
+ try {
221
+ const { emails } = await appAction('list-emails', { view: 'inbox', limit: 50 });
222
+ // ...categorize into 3 buckets...
223
+ this.results = {
224
+ builderActions: emails.filter((e) => /* ... */),
225
+ waitingOnCustomer: emails.filter((e) => /* ... */),
226
+ fyi: emails.filter((e) => /* ... */),
227
+ };
228
+ } catch (e) {
229
+ this.error = e?.message || 'Analysis failed';
230
+ } finally {
231
+ this.loading = false;
232
+ }
233
+ },
234
+ }));
235
+ });
236
+ </script>
237
+ ```
238
+
239
+ **Hard rules for `x-data` / `x-*` attributes:**
240
+
241
+ - Never put template literals (backticks) inside an HTML attribute. Use
242
+ string concatenation or pre-format in the script block. Backticks can
243
+ trip the HTML parser and the resulting string isn't a JS template literal
244
+ anyway — the attribute is read as plain text.
245
+ - Never put a multi-method object literal inline. Move methods into
246
+ `Alpine.data()`.
247
+ - In the `<script>` block, write normal JS — template literals, async/await,
248
+ optional chaining all work.
249
+ - One source of truth for state: define every variable referenced from any
250
+ `x-text`, `x-show`, `x-if`, `x-for`, `:class`, etc. on the `Alpine.data()`
251
+ object's initial state. If `x-text="results.foo"` references `results`,
252
+ `results` must be a property of the data object — null is a fine initial
253
+ value as long as you guard with `<template x-if="results">`.
254
+ - When showing an error, render `error.message`-style text, never a raw
255
+ boolean. `x-text="error"` is correct only when `error` is a string;
256
+ if it's `true` the user sees the literal word "true".
257
+
258
+ ## AI / LLM features in extensions
259
+
260
+ Extensions can do AI work two ways. Pick deliberately — silent fallbacks
261
+ end up rendering nonsense like the literal text `true`.
262
+
263
+ 1. **Delegate to the agent chat.** If the user says "analyze my emails",
264
+ "summarize this", "categorize these tickets" and there is no API key
265
+ already configured for the relevant provider, prefer doing the work in
266
+ the agent chat instead of inside the extension. The extension can have
267
+ a button that calls `parent.postMessage({ type: 'agent-native-send-to-chat', message: '...' })`,
268
+ or you can just answer in chat and skip the extension. Don't ship an
269
+ extension with a stubbed AI step that returns a placeholder — that's
270
+ how you end up rendering `true` in red.
271
+ 2. **Call an LLM directly via `extensionFetch`.** Requires a real key the
272
+ user has set up. Reference it via `${keys.OPENAI_API_KEY}` /
273
+ `${keys.ANTHROPIC_API_KEY}` and surface a clear error if the proxy
274
+ reports the key isn't configured. Tell the user where to add the key
275
+ (Settings → Secrets) before the extension can work.
276
+
277
+ If you're not sure a key is configured, ask the user before generating an
278
+ extension whose primary value is the AI step.
279
+
280
+ ## Accessing app data
281
+
282
+ Extensions can call the host app's actions and API endpoints directly. The
283
+ iframe shares the session cookie, so authentication is automatic.
284
+
285
+ ### `appAction(name, params)` — Call app actions
286
+
287
+ Call any action defined in the app's `actions/` directory. Actions are
288
+ auto-mounted at `/_agent-native/actions/:name`.
289
+
290
+ ```html
291
+ <div x-data="{ emails: [], loading: true }" x-init="
292
+ appAction('list-emails', { view: 'inbox', limit: 10 })
293
+ .then(d => { emails = d.emails || d; loading = false })
294
+ .catch(e => { console.error(e); loading = false })
295
+ ">
296
+ <h2 class='text-lg font-semibold mb-4'>My Inbox</h2>
297
+ <template x-for='email in emails' :key='email.id'>
298
+ <div class='rounded-lg border p-3 mb-2'>
299
+ <p class='font-medium text-sm' x-text='email.subject'></p>
300
+ <p class='text-xs text-muted-foreground' x-text='email.from?.name || email.from?.email'></p>
301
+ </div>
302
+ </template>
303
+ </div>
304
+ ```
305
+
306
+ ### `appFetch(path, options)` — Call allowed framework endpoints
307
+
308
+ General-purpose fetch to allowed framework endpoints (for example,
309
+ `/_agent-native/application-state/navigation`). Automatically adds credentials
310
+ and JSON content type. Template `/api/*` routes are intentionally blocked by
311
+ the extension bridge; use `appAction(name, params)` for app data instead.
312
+
313
+ ```javascript
314
+ // Read application state
315
+ const nav = await appFetch('/_agent-native/application-state/navigation');
316
+
317
+ // Call a framework route
318
+ const nav = await appFetch('/_agent-native/application-state/navigation');
319
+ ```
320
+
321
+ ### `dbQuery(sql)` — Read from the app's database
322
+
323
+ Run a read-only SELECT query against the app's SQL database. Results are
324
+ auto-scoped to the current user/org.
325
+
326
+ ```html
327
+ <div x-data="{ rows: [] }" x-init="
328
+ dbQuery('SELECT id, name FROM tools ORDER BY created_at DESC LIMIT 10')
329
+ .then(d => rows = d.rows || d)
330
+ ">
331
+ <template x-for="row in rows" :key="row.id">
332
+ <div class="border-b p-2 text-sm" x-text="row.name"></div>
333
+ </template>
334
+ </div>
335
+ ```
336
+
337
+ > The physical SQL table is still named `tools` (and `tool_data`,
338
+ > `tool_shares`) for back-compat. The Drizzle exports are `extensions`,
339
+ > `extensionData`, and `extensionShares` — use those when you query via the
340
+ > ORM. When writing raw SQL inside an extension (as above), use the
341
+ > physical names.
342
+
343
+ ### `dbExec(sql)` — Write to the app's database
344
+
345
+ Run an INSERT, UPDATE, or DELETE statement. Writes are auto-scoped to the
346
+ current user/org, and `owner_email` / `org_id` are auto-injected on INSERT.
347
+
348
+ ```javascript
349
+ // Insert a new record
350
+ await dbExec("INSERT INTO notes (id, title, body) VALUES ('abc', 'My Note', 'Hello world')");
351
+
352
+ // Update an existing record
353
+ await dbExec("UPDATE notes SET title = 'Updated Title' WHERE id = 'abc'");
354
+ ```
355
+
356
+ ### All helpers summary
357
+
358
+ | Helper | Use for | Example |
359
+ |--------|---------|---------|
360
+ | `appAction(name, params)` | Call app actions (CRUD, queries) | `appAction('list-emails', { view: 'inbox' })` |
361
+ | `appFetch(path, options)` | Call allowed framework endpoints | `appFetch('/_agent-native/application-state/navigation')` |
362
+ | `dbQuery(sql)` | Read from the app's SQL database | `dbQuery('SELECT * FROM notes LIMIT 10')` |
363
+ | `dbExec(sql)` | Write to the app's SQL database | `dbExec("INSERT INTO notes ...")` |
364
+ | `extensionFetch(url, options)` | Call external APIs via proxy (alias `toolFetch`) | `extensionFetch('https://api.github.com/user', { headers: { 'Authorization': 'Bearer ${keys.GITHUB_TOKEN}' } })` |
365
+ | `extensionData.set(collection, id, data, opts?)` | Save an item to extension storage (alias `toolData.set`) | `extensionData.set('todos', 'todo-1', { title: 'Buy milk' })` |
366
+ | `extensionData.list(collection, opts?)` | List items in a collection | `extensionData.list('todos', { scope: 'all' })` |
367
+ | `extensionData.get(collection, id, opts?)` | Get a single item by id | `extensionData.get('todos', 'todo-1')` |
368
+ | `extensionData.remove(collection, id, opts?)` | Delete an item | `extensionData.remove('todos', 'todo-1')` |
369
+
370
+ ## Persisting Custom Data
371
+
372
+ Extensions have a built-in key-value store via `extensionData` (legacy alias:
373
+ `toolData`). Each extension gets its own isolated storage, organized into
374
+ collections. Every method accepts an optional `{ scope }` option:
375
+
376
+ - `'user'` (default) — private to the current user
377
+ - `'org'` — visible to everyone in the user's org
378
+ - `'all'` (list/get only) — returns both user and org items
379
+
380
+ ```javascript
381
+ // Save a private item (default scope: 'user')
382
+ await extensionData.set('todos', 'todo-1', { title: 'Buy milk', done: false });
383
+
384
+ // Save an org-shared item
385
+ await extensionData.set('todos', 'team-todo-1', { title: 'Ship v2', done: false }, { scope: 'org' });
386
+
387
+ // List user items (default)
388
+ const myTodos = await extensionData.list('todos');
389
+
390
+ // List org items
391
+ const orgTodos = await extensionData.list('todos', { scope: 'org' });
392
+
393
+ // List both user + org items
394
+ const allTodos = await extensionData.list('todos', { scope: 'all' });
395
+ // Returns: [{ id, toolId, collection, data (JSON string), ownerEmail, scope, orgId, createdAt, updatedAt }]
396
+ // (the row column is still named `toolId` for back-compat — it's the extension id)
397
+
398
+ // Parse the JSON data
399
+ const parsed = allTodos.map(t => ({ ...JSON.parse(t.data), id: t.id, scope: t.scope }));
400
+
401
+ // Get/delete with scope
402
+ const item = await extensionData.get('todos', 'team-todo-1', { scope: 'org' });
403
+ await extensionData.remove('todos', 'team-todo-1', { scope: 'org' });
404
+ ```
405
+
406
+ Data is scoped per-extension. User-scoped items are private per-user;
407
+ org-scoped items are shared across the org. Any org member can read,
408
+ update, or delete org-scoped items. **Prefer `extensionData` over raw
409
+ `dbExec` for extension-specific persistence** — it handles table creation,
410
+ scoping, and upserts automatically.
411
+
412
+ ## Using `extensionFetch()` for API calls
413
+
414
+ `extensionFetch()` (legacy alias `toolFetch()`) is a drop-in replacement for
415
+ `fetch()` that proxies requests through the server. The server injects
416
+ secret values before the request leaves.
417
+
418
+ ```javascript
419
+ // Basic GET
420
+ const res = await extensionFetch('https://api.example.com/data');
421
+ const data = await res.json();
422
+
423
+ // With secret injection
424
+ const res = await extensionFetch('https://api.openai.com/v1/models', {
425
+ headers: {
426
+ 'Authorization': 'Bearer ${keys.OPENAI_API_KEY}'
427
+ }
428
+ });
429
+
430
+ // POST with body
431
+ const res = await extensionFetch('https://api.example.com/items', {
432
+ method: 'POST',
433
+ headers: { 'Content-Type': 'application/json' },
434
+ body: JSON.stringify({ name: 'New Item' })
435
+ });
436
+ ```
437
+
438
+ **Important:** Use single quotes around strings containing `${keys.NAME}`
439
+ to prevent JavaScript template literal evaluation. The substitution
440
+ happens server-side, not in the browser.
441
+
442
+ ## Tailwind classes
443
+
444
+ Extensions inherit the main app's Tailwind v4 theme. Use the same utility
445
+ classes:
446
+
447
+ - **Colors:** `bg-background`, `text-foreground`, `bg-primary`, `text-primary-foreground`, `text-muted-foreground`, `border-border`, `bg-accent`, `bg-destructive`
448
+ - **Layout:** `flex`, `grid`, `space-y-2`, `gap-4`, `p-4`, `m-2`
449
+ - **Typography:** `text-sm`, `text-lg`, `font-medium`, `font-bold`
450
+ - **Borders:** `border`, `rounded-lg`, `rounded-md`, `rounded-sm`
451
+ - **Dark mode:** automatic via `.dark` class on the html element
452
+
453
+ ## Managing secrets
454
+
455
+ Extensions reference secrets via `${keys.NAME}` inside `extensionFetch()`
456
+ calls. Create secrets via:
457
+
458
+ ```
459
+ POST /_agent-native/secrets/adhoc
460
+ { "name": "GITHUB_TOKEN", "value": "ghp_xxxx", "description": "GitHub PAT", "urlAllowlist": ["https://api.github.com"] }
461
+ ```
462
+
463
+ Or the user can add them in the settings UI. If an extension needs an API
464
+ key that isn't configured yet, tell the user what key is needed and where
465
+ to get it.
466
+
467
+ See the `secrets` skill for the full secrets API.
468
+
469
+ ## Sharing
470
+
471
+ Use the framework sharing actions:
472
+
473
+ ```bash
474
+ # Make an extension visible to the org
475
+ pnpm action set-resource-visibility --resourceType=tool --resourceId=EXTENSION_ID --visibility=org
476
+
477
+ # Share with a specific user
478
+ pnpm action share-resource --resourceType=tool --resourceId=EXTENSION_ID --principalType=user --principalId=user@example.com --role=editor
479
+
480
+ # List current shares
481
+ pnpm action list-resource-shares --resourceType=tool --resourceId=EXTENSION_ID
482
+ ```
483
+
484
+ > The `resourceType` value is still `tool` for back-compat with the
485
+ > `tool_shares` table. The variable name `EXTENSION_ID` is the canonical
486
+ > name for the value going into the call.
487
+
488
+ See the `sharing` skill for visibility levels and roles.
489
+
490
+ ## Navigation
491
+
492
+ ```bash
493
+ # Navigate to the extensions list
494
+ pnpm action navigate --view=extensions
495
+
496
+ # Navigate to a specific extension
497
+ pnpm action navigate --view=extensions --extensionId=EXTENSION_ID
498
+
499
+ # Or directly:
500
+ set-url-path({ "pathname": "/extensions/EXTENSION_ID" })
501
+ ```
502
+
503
+ ## Example extensions
504
+
505
+ ### API Status Dashboard
506
+
507
+ Checks the health of multiple endpoints and shows green/red status:
508
+
509
+ ```html
510
+ <div class="p-6" x-data="{
511
+ endpoints: [
512
+ { name: 'API', url: 'https://api.example.com/health' },
513
+ { name: 'Auth', url: 'https://auth.example.com/health' },
514
+ { name: 'CDN', url: 'https://cdn.example.com/health' }
515
+ ],
516
+ results: [],
517
+ loading: true
518
+ }" x-init="
519
+ Promise.all(endpoints.map(ep =>
520
+ extensionFetch(ep.url).then(r => ({ ...ep, ok: r.ok })).catch(() => ({ ...ep, ok: false }))
521
+ )).then(r => { results = r; loading = false })
522
+ ">
523
+ <h2 class="text-lg font-bold mb-4">Service Status</h2>
524
+ <template x-if="loading"><p class="text-muted-foreground">Checking...</p></template>
525
+ <div class="space-y-2">
526
+ <template x-for="r in results" :key="r.name">
527
+ <div class="flex items-center justify-between rounded-lg border p-3">
528
+ <span class="font-medium" x-text="r.name"></span>
529
+ <span x-bind:class="r.ok ? 'text-green-600' : 'text-red-600'" x-text="r.ok ? 'Healthy' : 'Down'"></span>
530
+ </div>
531
+ </template>
532
+ </div>
533
+ </div>
534
+ ```
535
+
536
+ ### Weather Widget
537
+
538
+ Fetches current weather for a city:
539
+
540
+ ```html
541
+ <div class="p-6" x-data="{ city: 'San Francisco', weather: null, loading: false }" x-init="
542
+ loading = true;
543
+ extensionFetch('https://api.weatherapi.com/v1/current.json?q=' + encodeURIComponent(city) + '&key=${keys.WEATHER_API_KEY}')
544
+ .then(r => r.json()).then(d => { weather = d; loading = false })
545
+ ">
546
+ <div class="space-y-4">
547
+ <div class="flex gap-2">
548
+ <input type="text" x-model="city" class="flex-1 rounded-md border bg-background px-3 py-2 text-sm" placeholder="City name" />
549
+ <button x-on:click="loading = true; extensionFetch('https://api.weatherapi.com/v1/current.json?q=' + encodeURIComponent(city) + '&key=${keys.WEATHER_API_KEY}').then(r => r.json()).then(d => { weather = d; loading = false })" class="rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-foreground cursor-pointer">Search</button>
550
+ </div>
551
+ <template x-if="loading"><p class="text-muted-foreground">Loading...</p></template>
552
+ <template x-if="weather && !loading">
553
+ <div class="rounded-lg border p-4">
554
+ <p class="text-2xl font-bold" x-text="weather.current.temp_f + '°F'"></p>
555
+ <p class="text-muted-foreground" x-text="weather.current.condition.text"></p>
556
+ <p class="text-sm text-muted-foreground" x-text="weather.location.name + ', ' + weather.location.region"></p>
557
+ </div>
558
+ </template>
559
+ </div>
560
+ </div>
561
+ ```
562
+
563
+ ### Todo List (using extensionData)
564
+
565
+ Full CRUD app using the built-in `extensionData` store — no SQL, no schema
566
+ files, no actions. Data is automatically scoped per-extension and per-user:
567
+
568
+ ```html
569
+ <div class="p-6" x-data="{
570
+ todos: [],
571
+ newTodo: '',
572
+ loading: true,
573
+ async init() {
574
+ const items = await extensionData.list('todos');
575
+ this.todos = items.map(i => ({ id: i.id, ...JSON.parse(i.data) }));
576
+ this.loading = false;
577
+ },
578
+ async addTodo() {
579
+ if (!this.newTodo.trim()) return;
580
+ const id = crypto.randomUUID();
581
+ const data = { title: this.newTodo.trim(), completed: false };
582
+ await extensionData.set('todos', id, data);
583
+ this.todos.unshift({ id, ...data });
584
+ this.newTodo = '';
585
+ },
586
+ async toggle(todo) {
587
+ todo.completed = !todo.completed;
588
+ await extensionData.set('todos', todo.id, { title: todo.title, completed: todo.completed });
589
+ },
590
+ async remove(id) {
591
+ await extensionData.remove('todos', id);
592
+ this.todos = this.todos.filter(t => t.id !== id);
593
+ }
594
+ }">
595
+ <h2 class="text-lg font-semibold mb-4">Todo List</h2>
596
+ <div class="flex gap-2 mb-4">
597
+ <input x-model="newTodo" type="text" placeholder="What needs to be done?"
598
+ class="flex-1 rounded-md border border-input bg-background px-3 py-2 text-sm"
599
+ @keydown.enter="addTodo()">
600
+ <button @click="addTodo()"
601
+ class="rounded-md bg-primary px-4 py-2 text-sm text-primary-foreground cursor-pointer hover:bg-primary/90">
602
+ Add
603
+ </button>
604
+ </div>
605
+ <div x-show="loading" class="text-sm text-muted-foreground">Loading...</div>
606
+ <div class="space-y-2">
607
+ <template x-for="todo in todos" :key="todo.id">
608
+ <div class="flex items-center gap-3 rounded-md border p-3">
609
+ <button @click="toggle(todo)" class="cursor-pointer"
610
+ :class="todo.completed ? 'text-green-500' : 'text-muted-foreground'">
611
+ <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
612
+ <template x-if="todo.completed"><path d="M22 11.08V12a10 10 0 1 1-5.93-9.14M22 4 12 14.01l-3-3"/></template>
613
+ <template x-if="!todo.completed"><circle cx="12" cy="12" r="10"/></template>
614
+ </svg>
615
+ </button>
616
+ <span class="flex-1 text-sm" :class="todo.completed && 'line-through text-muted-foreground'" x-text="todo.title"></span>
617
+ <button @click="remove(todo.id)" class="text-muted-foreground hover:text-destructive cursor-pointer text-xs">Remove</button>
618
+ </div>
619
+ </template>
620
+ </div>
621
+ <p x-show="!loading && todos.length === 0" class="text-sm text-muted-foreground text-center py-8">No todos yet. Add one above!</p>
622
+ </div>
623
+ ```
624
+
625
+ ### Quick Notes
626
+
627
+ Persistent notes using localStorage -- no API key needed:
628
+
629
+ ```html
630
+ <div class="p-6" x-data="{
631
+ notes: JSON.parse(localStorage.getItem('quick-notes') || '[]'),
632
+ draft: '',
633
+ save() {
634
+ if (!this.draft.trim()) return;
635
+ this.notes.unshift({ id: Date.now(), text: this.draft, date: new Date().toLocaleDateString() });
636
+ this.draft = '';
637
+ localStorage.setItem('quick-notes', JSON.stringify(this.notes));
638
+ },
639
+ remove(id) {
640
+ this.notes = this.notes.filter(n => n.id !== id);
641
+ localStorage.setItem('quick-notes', JSON.stringify(this.notes));
642
+ }
643
+ }">
644
+ <div class="space-y-4">
645
+ <div class="flex gap-2">
646
+ <input type="text" x-model="draft" x-on:keydown.enter="save()" class="flex-1 rounded-md border bg-background px-3 py-2 text-sm" placeholder="Add a note..." />
647
+ <button x-on:click="save()" class="rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-foreground cursor-pointer">Add</button>
648
+ </div>
649
+ <div class="space-y-2">
650
+ <template x-for="note in notes" :key="note.id">
651
+ <div class="flex items-start justify-between rounded-lg border p-3">
652
+ <div>
653
+ <p class="text-sm" x-text="note.text"></p>
654
+ <p class="text-xs text-muted-foreground" x-text="note.date"></p>
655
+ </div>
656
+ <button x-on:click="remove(note.id)" class="text-muted-foreground hover:text-destructive text-sm cursor-pointer">Remove</button>
657
+ </div>
658
+ </template>
659
+ <template x-if="notes.length === 0">
660
+ <p class="text-sm text-muted-foreground">No notes yet.</p>
661
+ </template>
662
+ </div>
663
+ </div>
664
+ </div>
665
+ ```
666
+
667
+ ## Guidelines
668
+
669
+ - **Rely on the default canvas padding.** The iframe shell adds modest body padding so simple extensions do not hug the edge. Do not add outer `p-4` / `p-6` unless the design needs extra breathing room. For full-bleed extensions such as maps, canvases, or custom editors, put `data-tool-layout="full-bleed"` or `data-tool-padding="none"` on the outermost element. (The `data-tool-*` attribute names are kept for back-compat with the iframe runtime.)
670
+ - **Use semantic Tailwind colors for native theming.** Always use `bg-background`, `text-foreground`, `bg-primary`, `text-primary-foreground`, `border-border`, `bg-muted`, `text-muted-foreground`, etc. The extension inherits the parent app's exact theme variables, so it will look fully native in both light and dark modes.
671
+ - **Keep extensions focused.** One extension, one job. A "GitHub PR Dashboard" should show PRs, not also manage issues.
672
+ - **Handle loading and error states.** Always show a loading indicator during fetch and handle failures gracefully.
673
+ - **All functions referenced in Alpine expressions must be defined in `x-data`.** If you use `@click="add()"`, there must be an `add()` method in the component's `x-data` object. Undefined references cause runtime errors.
674
+ - **For non-trivial components, use a `<script>` + `Alpine.data('name', () => ({...}))` block and reference it with `x-data="name"`.** Inline `x-data="{ ...big object... }"` is brittle: stuffing many methods, branching logic, or any backtick template literal into an HTML attribute leads to half-parsed expressions and `ReferenceError` failures. See the "Component shape" section above.
675
+ - **Don't ship a stubbed AI step.** If the extension's value is "AI analysis" and no LLM key is configured, either route the work to the agent chat or tell the user which key to add — never render a placeholder/boolean as the result.
676
+ - **Use the right fetch helper.** `appAction()` for app actions and app data, `appFetch()` for allowed framework `/_agent-native/*` endpoints, and `extensionFetch()` for external APIs. Never call template `/api/*` routes from an extension and never use raw `fetch()` -- secrets won't be injected and CORS will block external APIs.
677
+ - **Single quotes around `${keys.*}`** to prevent browser-side template literal evaluation.
678
+ - **Prefer patches over full rewrites** when editing existing extensions. Smaller diffs are less error-prone.
679
+
680
+ ## Routes
681
+
682
+ | Method | Path | Purpose |
683
+ | ------ | -------------------------------------- | --------------------------------------------- |
684
+ | GET | `/_agent-native/extensions` | List extensions (filtered by ownership/share) |
685
+ | POST | `/_agent-native/extensions` | Create an extension |
686
+ | GET | `/_agent-native/extensions/:id` | Get an extension |
687
+ | PUT | `/_agent-native/extensions/:id` | Update (supports `patches` for diffing) |
688
+ | DELETE | `/_agent-native/extensions/:id` | Delete an extension |
689
+ | GET | `/_agent-native/extensions/:id/render` | Render HTML for iframe |
690
+ | POST | `/_agent-native/extensions/proxy` | Authenticated proxy with secret injection |
691
+
692
+ ## Database & API names — back-compat reference
693
+
694
+ The rename from "tools" to "extensions" is mostly user-facing. Several
695
+ under-the-hood names are kept to avoid breaking existing data and code:
696
+
697
+ | Surface | Stays as | Rationale |
698
+ | ------------------------------------ | --------------------- | ------------------------------------------------------ |
699
+ | SQL table for extensions | `tools` | Renaming a table = drop+create; data must not move |
700
+ | SQL table for per-ext data | `tool_data` | Same |
701
+ | SQL table for ext shares | `tool_shares` | Same |
702
+ | Drizzle schema export | `extensions` | Code-side rename — no data migration needed |
703
+ | Drizzle schema export | `extensionData` | Same |
704
+ | Drizzle schema export | `extensionShares` | Same |
705
+ | Iframe global (legacy alias) | `toolFetch` | Kept so older extension bodies keep working |
706
+ | Iframe global (legacy alias) | `toolData` | Same |
707
+ | Iframe global (canonical) | `extensionFetch` | Use this in new extensions |
708
+ | Iframe global (canonical) | `extensionData` | Same |
709
+ | `data-tool-layout` HTML attribute | unchanged | Runtime contract; not worth churning |
710
+ | `resourceType` for sharing | `tool` | Matches `tool_shares` table |
711
+ | Slot-system table | `tool_slots` | Drizzle export is `extensionSlots` (see `extension-points`) |
712
+ | Slot-installs table | `tool_slot_installs` | Drizzle export is `extensionSlotInstalls` |
713
+
714
+ ## Related skills
715
+
716
+ - `extension-points` -- how an extension renders as a widget inside another app via named UI slots.
717
+ - `secrets` -- creating and managing API keys for `${keys.NAME}` substitution.
718
+ - `sharing` -- visibility and access control for extensions.
719
+ - `actions` -- the `create-extension` and `update-extension` actions that back extension CRUD.
720
+ - `frontend-design` -- design guidance when styling extension HTML.