@agent-native/core 0.37.3 → 0.38.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (377) hide show
  1. package/README.md +19 -6
  2. package/dist/action.d.ts +60 -2
  3. package/dist/action.d.ts.map +1 -1
  4. package/dist/action.js +6 -2
  5. package/dist/action.js.map +1 -1
  6. package/dist/agent/production-agent.d.ts +12 -6
  7. package/dist/agent/production-agent.d.ts.map +1 -1
  8. package/dist/agent/production-agent.js +161 -11
  9. package/dist/agent/production-agent.js.map +1 -1
  10. package/dist/agent/types.d.ts +2 -0
  11. package/dist/agent/types.d.ts.map +1 -1
  12. package/dist/agent/types.js.map +1 -1
  13. package/dist/catalog.json +2 -2
  14. package/dist/cli/connect.d.ts.map +1 -1
  15. package/dist/cli/connect.js +15 -0
  16. package/dist/cli/connect.js.map +1 -1
  17. package/dist/cli/index.js +10 -6
  18. package/dist/cli/index.js.map +1 -1
  19. package/dist/cli/plan-publish-store.d.ts +52 -0
  20. package/dist/cli/plan-publish-store.d.ts.map +1 -0
  21. package/dist/cli/plan-publish-store.js +103 -0
  22. package/dist/cli/plan-publish-store.js.map +1 -0
  23. package/dist/cli/skills.d.ts +29 -4
  24. package/dist/cli/skills.d.ts.map +1 -1
  25. package/dist/cli/skills.js +851 -275
  26. package/dist/cli/skills.js.map +1 -1
  27. package/dist/cli/templates-meta.js +12 -12
  28. package/dist/cli/templates-meta.js.map +1 -1
  29. package/dist/client/AssistantChat.d.ts +3 -1
  30. package/dist/client/AssistantChat.d.ts.map +1 -1
  31. package/dist/client/AssistantChat.js +65 -15
  32. package/dist/client/AssistantChat.js.map +1 -1
  33. package/dist/client/MultiTabAssistantChat.d.ts.map +1 -1
  34. package/dist/client/MultiTabAssistantChat.js +20 -2
  35. package/dist/client/MultiTabAssistantChat.js.map +1 -1
  36. package/dist/client/agent-chat-adapter.d.ts.map +1 -1
  37. package/dist/client/agent-chat-adapter.js +12 -0
  38. package/dist/client/agent-chat-adapter.js.map +1 -1
  39. package/dist/client/agent-engine-key.d.ts +24 -0
  40. package/dist/client/agent-engine-key.d.ts.map +1 -0
  41. package/dist/client/agent-engine-key.js +49 -0
  42. package/dist/client/agent-engine-key.js.map +1 -0
  43. package/dist/client/analytics.d.ts.map +1 -1
  44. package/dist/client/analytics.js +34 -0
  45. package/dist/client/analytics.js.map +1 -1
  46. package/dist/client/blocks/BlockView.d.ts +26 -0
  47. package/dist/client/blocks/BlockView.d.ts.map +1 -0
  48. package/dist/client/blocks/BlockView.js +24 -0
  49. package/dist/client/blocks/BlockView.js.map +1 -0
  50. package/dist/client/blocks/SchemaBlockEditor.d.ts +25 -0
  51. package/dist/client/blocks/SchemaBlockEditor.d.ts.map +1 -0
  52. package/dist/client/blocks/SchemaBlockEditor.js +72 -0
  53. package/dist/client/blocks/SchemaBlockEditor.js.map +1 -0
  54. package/dist/client/blocks/agent.d.ts +30 -0
  55. package/dist/client/blocks/agent.d.ts.map +1 -0
  56. package/dist/client/blocks/agent.js +61 -0
  57. package/dist/client/blocks/agent.js.map +1 -0
  58. package/dist/client/blocks/index.d.ts +34 -0
  59. package/dist/client/blocks/index.d.ts.map +1 -0
  60. package/dist/client/blocks/index.js +42 -0
  61. package/dist/client/blocks/index.js.map +1 -0
  62. package/dist/client/blocks/library/checklist.config.d.ts +36 -0
  63. package/dist/client/blocks/library/checklist.config.d.ts.map +1 -0
  64. package/dist/client/blocks/library/checklist.config.js +25 -0
  65. package/dist/client/blocks/library/checklist.config.js.map +1 -0
  66. package/dist/client/blocks/library/checklist.d.ts +26 -0
  67. package/dist/client/blocks/library/checklist.d.ts.map +1 -0
  68. package/dist/client/blocks/library/checklist.js +76 -0
  69. package/dist/client/blocks/library/checklist.js.map +1 -0
  70. package/dist/client/blocks/library/code-tabs.config.d.ts +36 -0
  71. package/dist/client/blocks/library/code-tabs.config.d.ts.map +1 -0
  72. package/dist/client/blocks/library/code-tabs.config.js +30 -0
  73. package/dist/client/blocks/library/code-tabs.config.js.map +1 -0
  74. package/dist/client/blocks/library/code-tabs.d.ts +3 -0
  75. package/dist/client/blocks/library/code-tabs.d.ts.map +1 -0
  76. package/dist/client/blocks/library/code-tabs.js +165 -0
  77. package/dist/client/blocks/library/code-tabs.js.map +1 -0
  78. package/dist/client/blocks/library/html.config.d.ts +37 -0
  79. package/dist/client/blocks/library/html.config.d.ts.map +1 -0
  80. package/dist/client/blocks/library/html.config.js +46 -0
  81. package/dist/client/blocks/library/html.config.js.map +1 -0
  82. package/dist/client/blocks/library/html.d.ts +21 -0
  83. package/dist/client/blocks/library/html.d.ts.map +1 -0
  84. package/dist/client/blocks/library/html.js +69 -0
  85. package/dist/client/blocks/library/html.js.map +1 -0
  86. package/dist/client/blocks/library/table.config.d.ts +30 -0
  87. package/dist/client/blocks/library/table.config.d.ts.map +1 -0
  88. package/dist/client/blocks/library/table.config.js +22 -0
  89. package/dist/client/blocks/library/table.config.js.map +1 -0
  90. package/dist/client/blocks/library/table.d.ts +8 -0
  91. package/dist/client/blocks/library/table.d.ts.map +1 -0
  92. package/dist/client/blocks/library/table.js +107 -0
  93. package/dist/client/blocks/library/table.js.map +1 -0
  94. package/dist/client/blocks/library/tabs.config.d.ts +56 -0
  95. package/dist/client/blocks/library/tabs.config.d.ts.map +1 -0
  96. package/dist/client/blocks/library/tabs.config.js +36 -0
  97. package/dist/client/blocks/library/tabs.config.js.map +1 -0
  98. package/dist/client/blocks/library/tabs.d.ts +20 -0
  99. package/dist/client/blocks/library/tabs.d.ts.map +1 -0
  100. package/dist/client/blocks/library/tabs.js +123 -0
  101. package/dist/client/blocks/library/tabs.js.map +1 -0
  102. package/dist/client/blocks/mdx.d.ts +74 -0
  103. package/dist/client/blocks/mdx.d.ts.map +1 -0
  104. package/dist/client/blocks/mdx.js +205 -0
  105. package/dist/client/blocks/mdx.js.map +1 -0
  106. package/dist/client/blocks/provider.d.ts +25 -0
  107. package/dist/client/blocks/provider.d.ts.map +1 -0
  108. package/dist/client/blocks/provider.js +19 -0
  109. package/dist/client/blocks/provider.js.map +1 -0
  110. package/dist/client/blocks/registry.d.ts +24 -0
  111. package/dist/client/blocks/registry.d.ts.map +1 -0
  112. package/dist/client/blocks/registry.js +50 -0
  113. package/dist/client/blocks/registry.js.map +1 -0
  114. package/dist/client/blocks/schema-form/introspect.d.ts +31 -0
  115. package/dist/client/blocks/schema-form/introspect.d.ts.map +1 -0
  116. package/dist/client/blocks/schema-form/introspect.js +164 -0
  117. package/dist/client/blocks/schema-form/introspect.js.map +1 -0
  118. package/dist/client/blocks/server.d.ts +22 -0
  119. package/dist/client/blocks/server.d.ts.map +1 -0
  120. package/dist/client/blocks/server.js +25 -0
  121. package/dist/client/blocks/server.js.map +1 -0
  122. package/dist/client/blocks/types.d.ts +212 -0
  123. package/dist/client/blocks/types.d.ts.map +1 -0
  124. package/dist/client/blocks/types.js +5 -0
  125. package/dist/client/blocks/types.js.map +1 -0
  126. package/dist/client/composer/ComposerPlusMenu.js +10 -1
  127. package/dist/client/composer/ComposerPlusMenu.js.map +1 -1
  128. package/dist/client/guided-questions.d.ts +68 -0
  129. package/dist/client/guided-questions.d.ts.map +1 -1
  130. package/dist/client/guided-questions.js +158 -3
  131. package/dist/client/guided-questions.js.map +1 -1
  132. package/dist/client/index.d.ts +5 -1
  133. package/dist/client/index.d.ts.map +1 -1
  134. package/dist/client/index.js +15 -1
  135. package/dist/client/index.js.map +1 -1
  136. package/dist/client/rich-markdown-editor/BubbleToolbar.d.ts +37 -0
  137. package/dist/client/rich-markdown-editor/BubbleToolbar.d.ts.map +1 -0
  138. package/dist/client/rich-markdown-editor/BubbleToolbar.js +161 -0
  139. package/dist/client/rich-markdown-editor/BubbleToolbar.js.map +1 -0
  140. package/dist/client/rich-markdown-editor/ImageExtension.d.ts +63 -0
  141. package/dist/client/rich-markdown-editor/ImageExtension.d.ts.map +1 -0
  142. package/dist/client/rich-markdown-editor/ImageExtension.js +242 -0
  143. package/dist/client/rich-markdown-editor/ImageExtension.js.map +1 -0
  144. package/dist/client/rich-markdown-editor/RichMarkdownEditor.d.ts +51 -0
  145. package/dist/client/rich-markdown-editor/RichMarkdownEditor.d.ts.map +1 -0
  146. package/dist/client/rich-markdown-editor/RichMarkdownEditor.js +37 -0
  147. package/dist/client/rich-markdown-editor/RichMarkdownEditor.js.map +1 -0
  148. package/dist/client/rich-markdown-editor/SharedRichEditor.d.ts +61 -0
  149. package/dist/client/rich-markdown-editor/SharedRichEditor.d.ts.map +1 -0
  150. package/dist/client/rich-markdown-editor/SharedRichEditor.js +121 -0
  151. package/dist/client/rich-markdown-editor/SharedRichEditor.js.map +1 -0
  152. package/dist/client/rich-markdown-editor/SlashCommandMenu.d.ts +36 -0
  153. package/dist/client/rich-markdown-editor/SlashCommandMenu.d.ts.map +1 -0
  154. package/dist/client/rich-markdown-editor/SlashCommandMenu.js +193 -0
  155. package/dist/client/rich-markdown-editor/SlashCommandMenu.js.map +1 -0
  156. package/dist/client/rich-markdown-editor/extensions.d.ts +166 -0
  157. package/dist/client/rich-markdown-editor/extensions.d.ts.map +1 -0
  158. package/dist/client/rich-markdown-editor/extensions.js +222 -0
  159. package/dist/client/rich-markdown-editor/extensions.js.map +1 -0
  160. package/dist/client/rich-markdown-editor/index.d.ts +9 -0
  161. package/dist/client/rich-markdown-editor/index.d.ts.map +1 -0
  162. package/dist/client/rich-markdown-editor/index.js +9 -0
  163. package/dist/client/rich-markdown-editor/index.js.map +1 -0
  164. package/dist/client/rich-markdown-editor/uploadEditorImage.d.ts +18 -0
  165. package/dist/client/rich-markdown-editor/uploadEditorImage.d.ts.map +1 -0
  166. package/dist/client/rich-markdown-editor/uploadEditorImage.js +57 -0
  167. package/dist/client/rich-markdown-editor/uploadEditorImage.js.map +1 -0
  168. package/dist/client/rich-markdown-editor/useCollabReconcile.d.ts +91 -0
  169. package/dist/client/rich-markdown-editor/useCollabReconcile.d.ts.map +1 -0
  170. package/dist/client/rich-markdown-editor/useCollabReconcile.js +342 -0
  171. package/dist/client/rich-markdown-editor/useCollabReconcile.js.map +1 -0
  172. package/dist/client/track.d.ts +25 -0
  173. package/dist/client/track.d.ts.map +1 -0
  174. package/dist/client/track.js +53 -0
  175. package/dist/client/track.js.map +1 -0
  176. package/dist/client/use-action.d.ts.map +1 -1
  177. package/dist/client/use-action.js +6 -0
  178. package/dist/client/use-action.js.map +1 -1
  179. package/dist/client/use-session.d.ts +3 -2
  180. package/dist/client/use-session.d.ts.map +1 -1
  181. package/dist/client/use-session.js +3 -2
  182. package/dist/client/use-session.js.map +1 -1
  183. package/dist/deploy/build.d.ts +5 -0
  184. package/dist/deploy/build.d.ts.map +1 -1
  185. package/dist/deploy/build.js +67 -1
  186. package/dist/deploy/build.js.map +1 -1
  187. package/dist/extensions/schema.d.ts +1 -1
  188. package/dist/mcp/build-server.d.ts.map +1 -1
  189. package/dist/mcp/build-server.js +9 -2
  190. package/dist/mcp/build-server.js.map +1 -1
  191. package/dist/mcp/server.d.ts +1 -1
  192. package/dist/mcp/server.d.ts.map +1 -1
  193. package/dist/mcp/server.js +35 -2
  194. package/dist/mcp/server.js.map +1 -1
  195. package/dist/provider-api/index.d.ts +1 -1
  196. package/dist/provider-api/index.d.ts.map +1 -1
  197. package/dist/scripts/docs/search.d.ts.map +1 -1
  198. package/dist/scripts/docs/search.js +5 -2
  199. package/dist/scripts/docs/search.js.map +1 -1
  200. package/dist/scripts/runner.d.ts.map +1 -1
  201. package/dist/scripts/runner.js +16 -3
  202. package/dist/scripts/runner.js.map +1 -1
  203. package/dist/server/action-discovery.d.ts.map +1 -1
  204. package/dist/server/action-discovery.js +2 -0
  205. package/dist/server/action-discovery.js.map +1 -1
  206. package/dist/server/action-routes.d.ts.map +1 -1
  207. package/dist/server/action-routes.js +30 -4
  208. package/dist/server/action-routes.js.map +1 -1
  209. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  210. package/dist/server/agent-chat-plugin.js +65 -19
  211. package/dist/server/agent-chat-plugin.js.map +1 -1
  212. package/dist/server/agent-teams.d.ts.map +1 -1
  213. package/dist/server/agent-teams.js +8 -1
  214. package/dist/server/agent-teams.js.map +1 -1
  215. package/dist/server/agents-bundle.d.ts +27 -1
  216. package/dist/server/agents-bundle.d.ts.map +1 -1
  217. package/dist/server/agents-bundle.js +41 -3
  218. package/dist/server/agents-bundle.js.map +1 -1
  219. package/dist/server/auth.d.ts.map +1 -1
  220. package/dist/server/auth.js +76 -3
  221. package/dist/server/auth.js.map +1 -1
  222. package/dist/server/core-routes-plugin.d.ts.map +1 -1
  223. package/dist/server/core-routes-plugin.js +60 -0
  224. package/dist/server/core-routes-plugin.js.map +1 -1
  225. package/dist/server/onboarding-html.d.ts.map +1 -1
  226. package/dist/server/onboarding-html.js +160 -22
  227. package/dist/server/onboarding-html.js.map +1 -1
  228. package/dist/server/sentry.d.ts.map +1 -1
  229. package/dist/server/sentry.js +6 -0
  230. package/dist/server/sentry.js.map +1 -1
  231. package/dist/server/social-og-image.d.ts +2 -1
  232. package/dist/server/social-og-image.d.ts.map +1 -1
  233. package/dist/server/social-og-image.js +24 -4
  234. package/dist/server/social-og-image.js.map +1 -1
  235. package/dist/sharing/schema.d.ts +1 -1
  236. package/dist/styles/agent-native.css +1 -0
  237. package/dist/styles/rich-markdown-editor.css +439 -0
  238. package/dist/templates/default/.agents/skills/actions/SKILL.md +4 -1
  239. package/dist/templates/default/.agents/skills/security/SKILL.md +13 -4
  240. package/dist/templates/default/.agents/skills/storing-data/SKILL.md +15 -3
  241. package/dist/templates/default/AGENTS.md +1 -0
  242. package/dist/templates/default/DEVELOPING.md +2 -0
  243. package/dist/templates/workspace-core/.agents/skills/a2a-protocol/SKILL.md +10 -3
  244. package/dist/templates/workspace-core/.agents/skills/actions/SKILL.md +98 -10
  245. package/dist/templates/workspace-core/.agents/skills/adding-a-feature/SKILL.md +45 -3
  246. package/dist/templates/workspace-core/.agents/skills/address-feedback/SKILL.md +2 -0
  247. package/dist/templates/workspace-core/.agents/skills/authentication/SKILL.md +37 -4
  248. package/dist/templates/workspace-core/.agents/skills/automations/SKILL.md +9 -4
  249. package/dist/templates/workspace-core/.agents/skills/capture-learnings/SKILL.md +2 -0
  250. package/dist/templates/workspace-core/.agents/skills/client-methods/SKILL.md +106 -0
  251. package/dist/templates/workspace-core/.agents/skills/client-methods/references/legacy-client-fetch-audit-2026-06-03.md +53 -0
  252. package/dist/templates/workspace-core/.agents/skills/client-side-routing/SKILL.md +2 -0
  253. package/dist/templates/workspace-core/.agents/skills/context-awareness/SKILL.md +62 -61
  254. package/dist/templates/workspace-core/.agents/skills/context-xray/SKILL.md +47 -0
  255. package/dist/templates/workspace-core/.agents/skills/create-skill/SKILL.md +28 -0
  256. package/dist/templates/workspace-core/.agents/skills/delegate-to-agent/SKILL.md +52 -1
  257. package/dist/templates/workspace-core/.agents/skills/extension-points/SKILL.md +2 -0
  258. package/dist/templates/workspace-core/.agents/skills/extensions/SKILL.md +95 -433
  259. package/dist/templates/workspace-core/.agents/skills/extensions/references/api.md +285 -0
  260. package/dist/templates/workspace-core/.agents/skills/extensions/references/examples.md +259 -0
  261. package/dist/templates/workspace-core/.agents/skills/external-agents/SKILL.md +398 -0
  262. package/dist/templates/workspace-core/.agents/skills/external-agents/references/mcp-apps-embedding.md +157 -0
  263. package/dist/templates/workspace-core/.agents/skills/frontend-design/SKILL.md +17 -0
  264. package/dist/templates/workspace-core/.agents/skills/integration-webhooks/SKILL.md +13 -2
  265. package/dist/templates/workspace-core/.agents/skills/mvp-followup/SKILL.md +51 -0
  266. package/dist/templates/workspace-core/.agents/skills/observability/SKILL.md +14 -4
  267. package/dist/templates/workspace-core/.agents/skills/onboarding/SKILL.md +13 -1
  268. package/dist/templates/workspace-core/.agents/skills/portability/SKILL.md +27 -5
  269. package/dist/templates/workspace-core/.agents/skills/qa/SKILL.md +24 -8
  270. package/dist/templates/workspace-core/.agents/skills/real-time-collab/SKILL.md +53 -7
  271. package/dist/templates/workspace-core/.agents/skills/real-time-sync/SKILL.md +43 -10
  272. package/dist/templates/workspace-core/.agents/skills/recurring-jobs/SKILL.md +2 -0
  273. package/dist/templates/workspace-core/.agents/skills/secrets/SKILL.md +43 -14
  274. package/dist/templates/workspace-core/.agents/skills/security/SKILL.md +50 -1
  275. package/dist/templates/workspace-core/.agents/skills/self-modifying-code/SKILL.md +4 -2
  276. package/dist/templates/workspace-core/.agents/skills/server-plugins/SKILL.md +11 -1
  277. package/dist/templates/workspace-core/.agents/skills/shadcn-ui/SKILL.md +15 -0
  278. package/dist/templates/workspace-core/.agents/skills/sharing/SKILL.md +5 -1
  279. package/dist/templates/workspace-core/.agents/skills/storing-data/SKILL.md +48 -19
  280. package/dist/templates/workspace-core/.agents/skills/tracking/SKILL.md +7 -3
  281. package/dist/templates/workspace-core/.agents/skills/voice-transcription/SKILL.md +13 -6
  282. package/dist/templates/workspace-core/.agents/skills/writing-agent-instructions/SKILL.md +236 -0
  283. package/dist/templates/workspace-core/AGENTS.md +5 -1
  284. package/dist/templates/workspace-root/AGENTS.md +5 -2
  285. package/dist/tracking/route.d.ts +43 -0
  286. package/dist/tracking/route.d.ts.map +1 -0
  287. package/dist/tracking/route.js +85 -0
  288. package/dist/tracking/route.js.map +1 -0
  289. package/dist/vite/client.d.ts.map +1 -1
  290. package/dist/vite/client.js +15 -0
  291. package/dist/vite/client.js.map +1 -1
  292. package/docs/content/a2a-protocol.md +18 -4
  293. package/docs/content/actions.md +87 -0
  294. package/docs/content/agent-mentions.md +2 -1
  295. package/docs/content/authentication.md +2 -1
  296. package/docs/content/client.md +64 -13
  297. package/docs/content/cloneable-saas.md +1 -1
  298. package/docs/content/code-agents-ui.md +17 -11
  299. package/docs/content/context-awareness.md +23 -28
  300. package/docs/content/creating-templates.md +1 -1
  301. package/docs/content/drop-in-agent.md +2 -0
  302. package/docs/content/getting-started.md +2 -2
  303. package/docs/content/key-concepts.md +2 -2
  304. package/docs/content/messaging.md +57 -15
  305. package/docs/content/migration-workbench.md +1 -1
  306. package/docs/content/multi-app-workspace.md +1 -1
  307. package/docs/content/multi-tenancy.md +17 -15
  308. package/docs/content/real-time-collaboration.md +1 -1
  309. package/docs/content/recurring-jobs.md +1 -1
  310. package/docs/content/security.md +2 -2
  311. package/docs/content/server.md +4 -4
  312. package/docs/content/skills-guide.md +30 -0
  313. package/docs/content/template-analytics.md +2 -2
  314. package/docs/content/template-assets.md +17 -1
  315. package/docs/content/template-brain.md +2 -2
  316. package/docs/content/template-calendar.md +1 -1
  317. package/docs/content/template-clips.md +3 -3
  318. package/docs/content/template-content.md +2 -2
  319. package/docs/content/template-design.md +2 -2
  320. package/docs/content/template-dispatch.md +3 -3
  321. package/docs/content/template-forms.md +14 -2
  322. package/docs/content/template-mail.md +1 -3
  323. package/docs/content/template-plan.md +118 -0
  324. package/docs/content/template-slides.md +5 -4
  325. package/docs/content/template-starter.md +4 -4
  326. package/docs/content/template-videos.md +6 -11
  327. package/docs/content/tracking.md +21 -1
  328. package/docs/content/visual-plans.md +72 -0
  329. package/docs/content/workspace.md +9 -9
  330. package/package.json +26 -11
  331. package/src/templates/default/.agents/skills/actions/SKILL.md +4 -1
  332. package/src/templates/default/.agents/skills/security/SKILL.md +13 -4
  333. package/src/templates/default/.agents/skills/storing-data/SKILL.md +15 -3
  334. package/src/templates/default/AGENTS.md +1 -0
  335. package/src/templates/default/DEVELOPING.md +2 -0
  336. package/src/templates/workspace-core/.agents/skills/a2a-protocol/SKILL.md +10 -3
  337. package/src/templates/workspace-core/.agents/skills/actions/SKILL.md +98 -10
  338. package/src/templates/workspace-core/.agents/skills/adding-a-feature/SKILL.md +45 -3
  339. package/src/templates/workspace-core/.agents/skills/address-feedback/SKILL.md +2 -0
  340. package/src/templates/workspace-core/.agents/skills/authentication/SKILL.md +37 -4
  341. package/src/templates/workspace-core/.agents/skills/automations/SKILL.md +9 -4
  342. package/src/templates/workspace-core/.agents/skills/capture-learnings/SKILL.md +2 -0
  343. package/src/templates/workspace-core/.agents/skills/client-methods/SKILL.md +106 -0
  344. package/src/templates/workspace-core/.agents/skills/client-methods/references/legacy-client-fetch-audit-2026-06-03.md +53 -0
  345. package/src/templates/workspace-core/.agents/skills/client-side-routing/SKILL.md +2 -0
  346. package/src/templates/workspace-core/.agents/skills/context-awareness/SKILL.md +62 -61
  347. package/src/templates/workspace-core/.agents/skills/context-xray/SKILL.md +47 -0
  348. package/src/templates/workspace-core/.agents/skills/create-skill/SKILL.md +28 -0
  349. package/src/templates/workspace-core/.agents/skills/delegate-to-agent/SKILL.md +52 -1
  350. package/src/templates/workspace-core/.agents/skills/extension-points/SKILL.md +2 -0
  351. package/src/templates/workspace-core/.agents/skills/extensions/SKILL.md +95 -433
  352. package/src/templates/workspace-core/.agents/skills/extensions/references/api.md +285 -0
  353. package/src/templates/workspace-core/.agents/skills/extensions/references/examples.md +259 -0
  354. package/src/templates/workspace-core/.agents/skills/external-agents/SKILL.md +398 -0
  355. package/src/templates/workspace-core/.agents/skills/external-agents/references/mcp-apps-embedding.md +157 -0
  356. package/src/templates/workspace-core/.agents/skills/frontend-design/SKILL.md +17 -0
  357. package/src/templates/workspace-core/.agents/skills/integration-webhooks/SKILL.md +13 -2
  358. package/src/templates/workspace-core/.agents/skills/mvp-followup/SKILL.md +51 -0
  359. package/src/templates/workspace-core/.agents/skills/observability/SKILL.md +14 -4
  360. package/src/templates/workspace-core/.agents/skills/onboarding/SKILL.md +13 -1
  361. package/src/templates/workspace-core/.agents/skills/portability/SKILL.md +27 -5
  362. package/src/templates/workspace-core/.agents/skills/qa/SKILL.md +24 -8
  363. package/src/templates/workspace-core/.agents/skills/real-time-collab/SKILL.md +53 -7
  364. package/src/templates/workspace-core/.agents/skills/real-time-sync/SKILL.md +43 -10
  365. package/src/templates/workspace-core/.agents/skills/recurring-jobs/SKILL.md +2 -0
  366. package/src/templates/workspace-core/.agents/skills/secrets/SKILL.md +43 -14
  367. package/src/templates/workspace-core/.agents/skills/security/SKILL.md +50 -1
  368. package/src/templates/workspace-core/.agents/skills/self-modifying-code/SKILL.md +4 -2
  369. package/src/templates/workspace-core/.agents/skills/server-plugins/SKILL.md +11 -1
  370. package/src/templates/workspace-core/.agents/skills/shadcn-ui/SKILL.md +15 -0
  371. package/src/templates/workspace-core/.agents/skills/sharing/SKILL.md +5 -1
  372. package/src/templates/workspace-core/.agents/skills/storing-data/SKILL.md +48 -19
  373. package/src/templates/workspace-core/.agents/skills/tracking/SKILL.md +7 -3
  374. package/src/templates/workspace-core/.agents/skills/voice-transcription/SKILL.md +13 -6
  375. package/src/templates/workspace-core/.agents/skills/writing-agent-instructions/SKILL.md +236 -0
  376. package/src/templates/workspace-core/AGENTS.md +5 -1
  377. package/src/templates/workspace-root/AGENTS.md +5 -2
@@ -0,0 +1,285 @@
1
+ # Extension API Reference
2
+
3
+ This is the exhaustive reference for the helpers and globals injected into
4
+ every extension iframe, plus the back-compat naming table. For the model +
5
+ when-to-use overview, see `../SKILL.md`. For worked HTML examples, see
6
+ `examples.md`.
7
+
8
+ ## Accessing app data
9
+
10
+ Extensions can call the host app's actions and API endpoints directly. The
11
+ iframe shares the session cookie, so authentication is automatic.
12
+
13
+ ### `appAction(name, params)` — Call app actions
14
+
15
+ Call any action defined in the app's `actions/` directory. Actions are
16
+ auto-mounted at `/_agent-native/actions/:name`.
17
+
18
+ ```html
19
+ <div
20
+ x-data="{ emails: [], loading: true }"
21
+ x-init="
22
+ appAction('list-emails', { view: 'inbox', limit: 10 })
23
+ .then(d => { emails = d.emails || d; loading = false })
24
+ .catch(e => { console.error(e); loading = false })
25
+ "
26
+ >
27
+ <h2 class="text-lg font-semibold mb-4">My Inbox</h2>
28
+ <template x-for="email in emails" :key="email.id">
29
+ <div class="rounded-lg border p-3 mb-2">
30
+ <p class="font-medium text-sm" x-text="email.subject"></p>
31
+ <p
32
+ class="text-xs text-muted-foreground"
33
+ x-text="email.from?.name || email.from?.email"
34
+ ></p>
35
+ </div>
36
+ </template>
37
+ </div>
38
+ ```
39
+
40
+ ### `appFetch(path, options)` — Call allowed framework endpoints
41
+
42
+ General-purpose fetch to allowed framework endpoints (for example,
43
+ `/_agent-native/application-state/navigation`). Automatically adds credentials
44
+ and JSON content type. Template `/api/*` routes are intentionally blocked by
45
+ the extension bridge; use `appAction(name, params)` for app data instead.
46
+
47
+ ```javascript
48
+ // Read application state
49
+ const nav = await appFetch("/_agent-native/application-state/navigation");
50
+
51
+ // Call a framework route
52
+ const nav = await appFetch("/_agent-native/application-state/navigation");
53
+ ```
54
+
55
+ ### `dbQuery(sql)` — Read from the app's database
56
+
57
+ Run a read-only SELECT query against the app's SQL database. Results are
58
+ auto-scoped to the current user/org.
59
+
60
+ ```html
61
+ <div
62
+ x-data="{ rows: [] }"
63
+ x-init="
64
+ dbQuery('SELECT id, name FROM tools ORDER BY created_at DESC LIMIT 10')
65
+ .then(d => rows = d.rows || d)
66
+ "
67
+ >
68
+ <template x-for="row in rows" :key="row.id">
69
+ <div class="border-b p-2 text-sm" x-text="row.name"></div>
70
+ </template>
71
+ </div>
72
+ ```
73
+
74
+ > The physical SQL table is still named `tools` (and `tool_data`,
75
+ > `tool_shares`) for back-compat. The Drizzle exports are `extensions`,
76
+ > `extensionData`, and `extensionShares` — use those when you query via the
77
+ > ORM. When writing raw SQL inside an extension (as above), use the
78
+ > physical names.
79
+
80
+ ### `dbExec(sql)` — Write to the app's database
81
+
82
+ Run an INSERT, UPDATE, or DELETE statement. Writes are auto-scoped to the
83
+ current user/org, and `owner_email` / `org_id` are auto-injected on INSERT.
84
+
85
+ ```javascript
86
+ // Insert a new record
87
+ await dbExec(
88
+ "INSERT INTO notes (id, title, body) VALUES ('abc', 'My Note', 'Hello world')",
89
+ );
90
+
91
+ // Update an existing record
92
+ await dbExec("UPDATE notes SET title = 'Updated Title' WHERE id = 'abc'");
93
+ ```
94
+
95
+ ### All helpers summary
96
+
97
+ | Helper | Use for | Example |
98
+ | ------------------------------------------------ | -------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- |
99
+ | `appAction(name, params)` | Call app actions (CRUD, queries) | `appAction('list-emails', { view: 'inbox' })` |
100
+ | `appFetch(path, options)` | Call allowed framework endpoints | `appFetch('/_agent-native/application-state/navigation')` |
101
+ | `dbQuery(sql)` | Read from the app's SQL database | `dbQuery('SELECT * FROM notes LIMIT 10')` |
102
+ | `dbExec(sql)` | Write to the app's SQL database | `dbExec("INSERT INTO notes ...")` |
103
+ | `extensionFetch(url, options)` | Call external APIs via proxy (alias `toolFetch`) | `extensionFetch('https://api.github.com/user', { headers: { 'Authorization': 'Bearer ${keys.GITHUB_TOKEN}' } })` |
104
+ | `extensionData.set(collection, id, data, opts?)` | Save an item to extension storage (alias `toolData.set`) | `extensionData.set('todos', 'todo-1', { title: 'Buy milk' })` |
105
+ | `extensionData.list(collection, opts?)` | List items in a collection | `extensionData.list('todos', { scope: 'all' })` |
106
+ | `extensionData.get(collection, id, opts?)` | Get a single item by id | `extensionData.get('todos', 'todo-1')` |
107
+ | `extensionData.remove(collection, id, opts?)` | Delete an item | `extensionData.remove('todos', 'todo-1')` |
108
+
109
+ ## Persisting Custom Data
110
+
111
+ Extensions have a built-in key-value store via `extensionData` (legacy alias:
112
+ `toolData`). Each extension gets its own isolated storage, organized into
113
+ collections. Every method accepts an optional `{ scope }` option:
114
+
115
+ - `'user'` (default) — private to the current user
116
+ - `'org'` — visible to everyone in the user's org
117
+ - `'all'` (list/get only) — returns both user and org items
118
+
119
+ ```javascript
120
+ // Save a private item (default scope: 'user')
121
+ await extensionData.set("todos", "todo-1", { title: "Buy milk", done: false });
122
+
123
+ // Save an org-shared item
124
+ await extensionData.set(
125
+ "todos",
126
+ "team-todo-1",
127
+ { title: "Ship v2", done: false },
128
+ { scope: "org" },
129
+ );
130
+
131
+ // List user items (default)
132
+ const myTodos = await extensionData.list("todos");
133
+
134
+ // List org items
135
+ const orgTodos = await extensionData.list("todos", { scope: "org" });
136
+
137
+ // List both user + org items
138
+ const allTodos = await extensionData.list("todos", { scope: "all" });
139
+ // Returns: [{ id, toolId, collection, data (JSON string), ownerEmail, scope, orgId, createdAt, updatedAt }]
140
+ // (the row column is still named `toolId` for back-compat — it's the extension id)
141
+
142
+ // Parse the JSON data
143
+ const parsed = allTodos.map((t) => ({
144
+ ...JSON.parse(t.data),
145
+ id: t.id,
146
+ scope: t.scope,
147
+ }));
148
+
149
+ // Get/delete with scope
150
+ const item = await extensionData.get("todos", "team-todo-1", { scope: "org" });
151
+ await extensionData.remove("todos", "team-todo-1", { scope: "org" });
152
+ ```
153
+
154
+ Data is scoped per-extension. User-scoped items are private per-user;
155
+ org-scoped items are shared across the org. Any org member can read,
156
+ update, or delete org-scoped items. **Prefer `extensionData` over raw
157
+ `dbExec` for extension-specific persistence** — it handles table creation,
158
+ scoping, and upserts automatically.
159
+
160
+ ## Using `extensionFetch()` for API calls
161
+
162
+ `extensionFetch()` (legacy alias `toolFetch()`) is a drop-in replacement for
163
+ `fetch()` that proxies requests through the server. The server injects
164
+ secret values before the request leaves.
165
+
166
+ ```javascript
167
+ // Basic GET
168
+ const res = await extensionFetch("https://api.example.com/data");
169
+ const data = await res.json();
170
+
171
+ // With secret injection
172
+ const res = await extensionFetch("https://api.openai.com/v1/models", {
173
+ headers: {
174
+ Authorization: "Bearer ${keys.OPENAI_API_KEY}",
175
+ },
176
+ });
177
+
178
+ // POST with body
179
+ const res = await extensionFetch("https://api.example.com/items", {
180
+ method: "POST",
181
+ headers: { "Content-Type": "application/json" },
182
+ body: JSON.stringify({ name: "New Item" }),
183
+ });
184
+ ```
185
+
186
+ **Important:** Use single quotes around strings containing `${keys.NAME}`
187
+ to prevent JavaScript template literal evaluation. The substitution
188
+ happens server-side, not in the browser.
189
+
190
+ ## Tailwind classes
191
+
192
+ Extensions inherit the main app's Tailwind v4 theme. Use the same utility
193
+ classes:
194
+
195
+ - **Colors:** `bg-background`, `text-foreground`, `bg-primary`, `text-primary-foreground`, `text-muted-foreground`, `border-border`, `bg-accent`, `bg-destructive`
196
+ - **Layout:** `flex`, `grid`, `space-y-2`, `gap-4`, `p-4`, `m-2`
197
+ - **Typography:** `text-sm`, `text-lg`, `font-medium`, `font-bold`
198
+ - **Borders:** `border`, `rounded-lg`, `rounded-md`, `rounded-sm`
199
+ - **Dark mode:** automatic via `.dark` class on the html element
200
+
201
+ ## Managing secrets
202
+
203
+ Extensions reference secrets via `${keys.NAME}` inside `extensionFetch()`
204
+ calls. Create secrets via:
205
+
206
+ ```
207
+ POST /_agent-native/secrets/adhoc
208
+ { "name": "GITHUB_TOKEN", "value": "<TOKEN_VALUE_FROM_USER_SETTINGS>", "description": "GitHub PAT", "urlAllowlist": ["https://api.github.com"] }
209
+ ```
210
+
211
+ Or the user can add them in the settings UI. If an extension needs an API
212
+ key that isn't configured yet, tell the user what key is needed and where
213
+ to get it. Never invent PAT-shaped values or store keys in extension HTML,
214
+ `extensionData`, or examples.
215
+
216
+ See the `secrets` skill for the full secrets API.
217
+
218
+ ## Sharing
219
+
220
+ Use the framework sharing actions:
221
+
222
+ ```bash
223
+ # Make an extension visible to the org
224
+ pnpm action set-resource-visibility --resourceType=tool --resourceId=EXTENSION_ID --visibility=org
225
+
226
+ # Share with a specific user
227
+ pnpm action share-resource --resourceType=tool --resourceId=EXTENSION_ID --principalType=user --principalId=user@example.com --role=editor
228
+
229
+ # List current shares
230
+ pnpm action list-resource-shares --resourceType=tool --resourceId=EXTENSION_ID
231
+ ```
232
+
233
+ > The `resourceType` value is still `tool` for back-compat with the
234
+ > `tool_shares` table. The variable name `EXTENSION_ID` is the canonical
235
+ > name for the value going into the call.
236
+
237
+ See the `sharing` skill for visibility levels and roles.
238
+
239
+ ## Navigation
240
+
241
+ ```bash
242
+ # Navigate to the extensions list
243
+ pnpm action navigate --view=extensions
244
+
245
+ # Navigate to a specific extension
246
+ pnpm action navigate --view=extensions --extensionId=EXTENSION_ID
247
+
248
+ # Or directly:
249
+ set-url-path({ "pathname": "/extensions/EXTENSION_ID" })
250
+ ```
251
+
252
+ ## Routes
253
+
254
+ | Method | Path | Purpose |
255
+ | ------ | -------------------------------------- | --------------------------------------------- |
256
+ | GET | `/_agent-native/extensions` | List extensions (filtered by ownership/share) |
257
+ | POST | `/_agent-native/extensions` | Create an extension |
258
+ | GET | `/_agent-native/extensions/:id` | Get an extension |
259
+ | PUT | `/_agent-native/extensions/:id` | Update (supports `patches` for diffing) |
260
+ | DELETE | `/_agent-native/extensions/:id` | Delete an extension |
261
+ | GET | `/_agent-native/extensions/:id/render` | Render HTML for iframe |
262
+ | POST | `/_agent-native/extensions/proxy` | Authenticated proxy with secret injection |
263
+
264
+ ## Database & API names — back-compat reference
265
+
266
+ The rename from "tools" to "extensions" is mostly user-facing. Several
267
+ under-the-hood names are kept to avoid breaking existing data and code:
268
+
269
+ | Surface | Stays as | Rationale |
270
+ | --------------------------------- | -------------------- | ----------------------------------------------------------- |
271
+ | SQL table for extensions | `tools` | Renaming a table = drop+create; data must not move |
272
+ | SQL table for per-ext data | `tool_data` | Same |
273
+ | SQL table for ext shares | `tool_shares` | Same |
274
+ | SQL table for ext history | `tool_history` | Same DB naming family |
275
+ | Drizzle schema export | `extensions` | Code-side rename — no data migration needed |
276
+ | Drizzle schema export | `extensionData` | Same |
277
+ | Drizzle schema export | `extensionShares` | Same |
278
+ | Iframe global (legacy alias) | `toolFetch` | Kept so older extension bodies keep working |
279
+ | Iframe global (legacy alias) | `toolData` | Same |
280
+ | Iframe global (canonical) | `extensionFetch` | Use this in new extensions |
281
+ | Iframe global (canonical) | `extensionData` | Same |
282
+ | `data-tool-layout` HTML attribute | unchanged | Runtime contract; not worth churning |
283
+ | `resourceType` for sharing | `tool` | Matches `tool_shares` table |
284
+ | Slot-system table | `tool_slots` | Drizzle export is `extensionSlots` (see `extension-points`) |
285
+ | Slot-installs table | `tool_slot_installs` | Drizzle export is `extensionSlotInstalls` |
@@ -0,0 +1,259 @@
1
+ # Extension Examples
2
+
3
+ Worked HTML examples for extensions. For the model + when-to-use overview, see
4
+ `../SKILL.md`. For the full helper/global API tables, see `api.md`.
5
+
6
+ ## API Status Dashboard
7
+
8
+ Checks the health of multiple endpoints and shows green/red status:
9
+
10
+ ```html
11
+ <div
12
+ class="p-6"
13
+ x-data="{
14
+ endpoints: [
15
+ { name: 'API', url: 'https://api.example.com/health' },
16
+ { name: 'Auth', url: 'https://auth.example.com/health' },
17
+ { name: 'CDN', url: 'https://cdn.example.com/health' }
18
+ ],
19
+ results: [],
20
+ loading: true
21
+ }"
22
+ x-init="
23
+ Promise.all(endpoints.map(ep =>
24
+ extensionFetch(ep.url).then(r => ({ ...ep, ok: r.ok })).catch(() => ({ ...ep, ok: false }))
25
+ )).then(r => { results = r; loading = false })
26
+ "
27
+ >
28
+ <h2 class="text-lg font-bold mb-4">Service Status</h2>
29
+ <template x-if="loading"
30
+ ><p class="text-muted-foreground">Checking...</p></template
31
+ >
32
+ <div class="space-y-2">
33
+ <template x-for="r in results" :key="r.name">
34
+ <div class="flex items-center justify-between rounded-lg border p-3">
35
+ <span class="font-medium" x-text="r.name"></span>
36
+ <span
37
+ x-bind:class="r.ok ? 'text-green-600' : 'text-red-600'"
38
+ x-text="r.ok ? 'Healthy' : 'Down'"
39
+ ></span>
40
+ </div>
41
+ </template>
42
+ </div>
43
+ </div>
44
+ ```
45
+
46
+ ## Weather Widget
47
+
48
+ Fetches current weather for a city:
49
+
50
+ ```html
51
+ <div
52
+ class="p-6"
53
+ x-data="{ city: 'San Francisco', weather: null, loading: false }"
54
+ x-init="
55
+ loading = true;
56
+ extensionFetch('https://api.weatherapi.com/v1/current.json?q=' + encodeURIComponent(city) + '&key=${keys.WEATHER_API_KEY}')
57
+ .then(r => r.json()).then(d => { weather = d; loading = false })
58
+ "
59
+ >
60
+ <div class="space-y-4">
61
+ <div class="flex gap-2">
62
+ <input
63
+ type="text"
64
+ x-model="city"
65
+ class="flex-1 rounded-md border bg-background px-3 py-2 text-sm"
66
+ placeholder="City name"
67
+ />
68
+ <button
69
+ 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 })"
70
+ class="rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-foreground cursor-pointer"
71
+ >
72
+ Search
73
+ </button>
74
+ </div>
75
+ <template x-if="loading"
76
+ ><p class="text-muted-foreground">Loading...</p></template
77
+ >
78
+ <template x-if="weather && !loading">
79
+ <div class="rounded-lg border p-4">
80
+ <p
81
+ class="text-2xl font-bold"
82
+ x-text="weather.current.temp_f + '°F'"
83
+ ></p>
84
+ <p
85
+ class="text-muted-foreground"
86
+ x-text="weather.current.condition.text"
87
+ ></p>
88
+ <p
89
+ class="text-sm text-muted-foreground"
90
+ x-text="weather.location.name + ', ' + weather.location.region"
91
+ ></p>
92
+ </div>
93
+ </template>
94
+ </div>
95
+ </div>
96
+ ```
97
+
98
+ ## Todo List (using extensionData)
99
+
100
+ Full CRUD app using the built-in `extensionData` store — no SQL, no schema
101
+ files, no actions. Data is automatically scoped per-extension and per-user:
102
+
103
+ ```html
104
+ <div
105
+ class="p-6"
106
+ x-data="{
107
+ todos: [],
108
+ newTodo: '',
109
+ loading: true,
110
+ async init() {
111
+ const items = await extensionData.list('todos');
112
+ this.todos = items.map(i => ({ id: i.id, ...JSON.parse(i.data) }));
113
+ this.loading = false;
114
+ },
115
+ async addTodo() {
116
+ if (!this.newTodo.trim()) return;
117
+ const id = crypto.randomUUID();
118
+ const data = { title: this.newTodo.trim(), completed: false };
119
+ await extensionData.set('todos', id, data);
120
+ this.todos.unshift({ id, ...data });
121
+ this.newTodo = '';
122
+ },
123
+ async toggle(todo) {
124
+ todo.completed = !todo.completed;
125
+ await extensionData.set('todos', todo.id, { title: todo.title, completed: todo.completed });
126
+ },
127
+ async remove(id) {
128
+ await extensionData.remove('todos', id);
129
+ this.todos = this.todos.filter(t => t.id !== id);
130
+ }
131
+ }"
132
+ >
133
+ <h2 class="text-lg font-semibold mb-4">Todo List</h2>
134
+ <div class="flex gap-2 mb-4">
135
+ <input
136
+ x-model="newTodo"
137
+ type="text"
138
+ placeholder="What needs to be done?"
139
+ class="flex-1 rounded-md border border-input bg-background px-3 py-2 text-sm"
140
+ @keydown.enter="addTodo()"
141
+ />
142
+ <button
143
+ @click="addTodo()"
144
+ class="rounded-md bg-primary px-4 py-2 text-sm text-primary-foreground cursor-pointer hover:bg-primary/90"
145
+ >
146
+ Add
147
+ </button>
148
+ </div>
149
+ <div x-show="loading" class="text-sm text-muted-foreground">Loading...</div>
150
+ <div class="space-y-2">
151
+ <template x-for="todo in todos" :key="todo.id">
152
+ <div class="flex items-center gap-3 rounded-md border p-3">
153
+ <button
154
+ @click="toggle(todo)"
155
+ class="cursor-pointer"
156
+ :class="todo.completed ? 'text-green-500' : 'text-muted-foreground'"
157
+ >
158
+ <svg
159
+ xmlns="http://www.w3.org/2000/svg"
160
+ width="18"
161
+ height="18"
162
+ viewBox="0 0 24 24"
163
+ fill="none"
164
+ stroke="currentColor"
165
+ stroke-width="2"
166
+ stroke-linecap="round"
167
+ stroke-linejoin="round"
168
+ >
169
+ <template x-if="todo.completed">
170
+ <path d="M22 11.08V12a10 10 0 1 1-5.93-9.14M22 4 12 14.01l-3-3" />
171
+ </template>
172
+ <template x-if="!todo.completed">
173
+ <circle cx="12" cy="12" r="10" />
174
+ </template>
175
+ </svg>
176
+ </button>
177
+ <span
178
+ class="flex-1 text-sm"
179
+ :class="todo.completed && 'line-through text-muted-foreground'"
180
+ x-text="todo.title"
181
+ ></span>
182
+ <button
183
+ @click="remove(todo.id)"
184
+ class="text-muted-foreground hover:text-destructive cursor-pointer text-xs"
185
+ >
186
+ Remove
187
+ </button>
188
+ </div>
189
+ </template>
190
+ </div>
191
+ <p
192
+ x-show="!loading && todos.length === 0"
193
+ class="text-sm text-muted-foreground text-center py-8"
194
+ >
195
+ No todos yet. Add one above!
196
+ </p>
197
+ </div>
198
+ ```
199
+
200
+ ## Quick Notes
201
+
202
+ Persistent notes using localStorage -- no API key needed:
203
+
204
+ ```html
205
+ <div
206
+ class="p-6"
207
+ x-data="{
208
+ notes: JSON.parse(localStorage.getItem('quick-notes') || '[]'),
209
+ draft: '',
210
+ save() {
211
+ if (!this.draft.trim()) return;
212
+ this.notes.unshift({ id: Date.now(), text: this.draft, date: new Date().toLocaleDateString() });
213
+ this.draft = '';
214
+ localStorage.setItem('quick-notes', JSON.stringify(this.notes));
215
+ },
216
+ remove(id) {
217
+ this.notes = this.notes.filter(n => n.id !== id);
218
+ localStorage.setItem('quick-notes', JSON.stringify(this.notes));
219
+ }
220
+ }"
221
+ >
222
+ <div class="space-y-4">
223
+ <div class="flex gap-2">
224
+ <input
225
+ type="text"
226
+ x-model="draft"
227
+ x-on:keydown.enter="save()"
228
+ class="flex-1 rounded-md border bg-background px-3 py-2 text-sm"
229
+ placeholder="Add a note..."
230
+ />
231
+ <button
232
+ x-on:click="save()"
233
+ class="rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-foreground cursor-pointer"
234
+ >
235
+ Add
236
+ </button>
237
+ </div>
238
+ <div class="space-y-2">
239
+ <template x-for="note in notes" :key="note.id">
240
+ <div class="flex items-start justify-between rounded-lg border p-3">
241
+ <div>
242
+ <p class="text-sm" x-text="note.text"></p>
243
+ <p class="text-xs text-muted-foreground" x-text="note.date"></p>
244
+ </div>
245
+ <button
246
+ x-on:click="remove(note.id)"
247
+ class="text-muted-foreground hover:text-destructive text-sm cursor-pointer"
248
+ >
249
+ Remove
250
+ </button>
251
+ </div>
252
+ </template>
253
+ <template x-if="notes.length === 0">
254
+ <p class="text-sm text-muted-foreground">No notes yet.</p>
255
+ </template>
256
+ </div>
257
+ </div>
258
+ </div>
259
+ ```