@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,51 @@
1
+ ---
2
+ name: mvp-followup
3
+ description: >-
4
+ Use when asking what to do next after a feature pass while avoiding bloat and
5
+ checking for unfinished MVP work.
6
+ metadata:
7
+ internal: true
8
+ ---
9
+
10
+ # MVP Follow-Up
11
+
12
+ ## Rule
13
+
14
+ Recommend or execute only closeout work that makes the current MVP more real,
15
+ verified, documented, or shippable. Do not propose new product scope unless
16
+ there is a clear blocker to the MVP working for real users.
17
+
18
+ ## Workflow
19
+
20
+ 1. Identify the current feature or thread outcome.
21
+ 2. Check for unfinished work in this order:
22
+ - failing or skipped verification
23
+ - unreviewed real-data pilot results
24
+ - pending review/proposals/approval queues
25
+ - docs that no longer match behavior
26
+ - unrelated dirty files that block full prep/ship hygiene
27
+ 3. Recommend the smallest next batch that closes those gaps.
28
+ 4. Explicitly skip tempting bloat: new integrations, dashboards, settings,
29
+ abstractions, or extra UI unless they directly unblock real use.
30
+ 5. If the user says "do it", run the closeout work in parallel where safe and
31
+ keep edits minimal.
32
+
33
+ ## Output Shape
34
+
35
+ Lead with the concrete next step. Keep the list short. Separate:
36
+
37
+ - **Do now**: validation, real pilot, docs, or bug fixes.
38
+ - **Defer**: useful ideas that should wait for real user feedback.
39
+ - **Blocker**: any specific user/manual action needed.
40
+
41
+ ## Verification Bias
42
+
43
+ Prefer non-mutating checks when the worktree has unrelated dirty files. Use full
44
+ `pnpm prep` only when it will not rewrite someone else's concurrent work.
45
+
46
+ ## Related Skills
47
+
48
+ - `qa`
49
+ - `ship`
50
+ - `adding-a-feature`
51
+ - `capture-learnings`
@@ -4,6 +4,8 @@ description: >-
4
4
  Agent observability, evals, feedback, and experiments. Use when adding
5
5
  observability dashboards, configuring trace capture, setting up evals,
6
6
  creating A/B experiments, or collecting user feedback on agent responses.
7
+ metadata:
8
+ internal: true
7
9
  ---
8
10
 
9
11
  # Agent Observability
@@ -78,17 +80,25 @@ const criteria: EvalCriteria = {
78
80
  A/B testing with sticky user-level assignment:
79
81
 
80
82
  ```ts
81
- import { createExperiment, startExperiment } from "@agent-native/core/observability";
83
+ import { insertExperiment, updateExperiment } from "@agent-native/core/observability";
82
84
 
83
- const exp = await createExperiment({
85
+ const exp = {
86
+ id: crypto.randomUUID(),
84
87
  name: "sonnet-vs-haiku",
88
+ status: "draft" as const,
85
89
  variants: [
86
90
  { id: "control", weight: 50, config: { model: "claude-sonnet-4-6" } },
87
91
  { id: "treatment", weight: 50, config: { model: "claude-haiku-4-5-20251001" } },
88
92
  ],
89
93
  metrics: ["cost", "latency", "satisfaction"],
90
- });
91
- await startExperiment(exp.id);
94
+ assignmentLevel: "user" as const,
95
+ startedAt: null,
96
+ endedAt: null,
97
+ createdAt: Date.now(),
98
+ };
99
+ await insertExperiment(exp);
100
+ // Move it to "running" when ready to start collecting assignments.
101
+ await updateExperiment(exp.id, { status: "running" });
92
102
  ```
93
103
 
94
104
  The agent loop reads active experiments via `resolveActiveExperimentConfig()` and applies the variant's `model` override automatically. Assignment uses consistent hashing — same user always gets the same variant.
@@ -4,6 +4,8 @@ description: >-
4
4
  How to register user-facing setup steps (API keys, OAuth, connecting
5
5
  third-party services) for the sidebar setup checklist. Use when adding a
6
6
  feature that needs initial user configuration.
7
+ metadata:
8
+ internal: true
7
9
  ---
8
10
 
9
11
  # Onboarding Steps
@@ -12,10 +14,19 @@ description: >-
12
14
 
13
15
  If a feature requires user-facing setup (API keys, OAuth, connecting a third-party service), register an onboarding step so it appears in the agent sidebar's setup checklist.
14
16
 
17
+ Onboarding must point users to a secure credential path; it must never encode
18
+ the credential value in source, docs, fixtures, prompts, or generated content.
19
+ For API keys and service tokens, prefer `registerRequiredSecret()` from the
20
+ `secrets` skill so the settings UI, encrypted storage, validation, and
21
+ onboarding checklist stay in one place. For OAuth, check the scoped OAuth token
22
+ store. Use deployment env vars only for deploy-level configuration, not
23
+ per-user credentials.
24
+
15
25
  ## Registering a Step
16
26
 
17
27
  ```ts
18
28
  import { registerOnboardingStep } from "@agent-native/core/onboarding";
29
+ import { hasOAuthTokens } from "@agent-native/core/oauth-tokens";
19
30
 
20
31
  registerOnboardingStep({
21
32
  id: "gmail",
@@ -31,7 +42,8 @@ registerOnboardingStep({
31
42
  payload: { url: "/_agent-native/google/auth-url" },
32
43
  },
33
44
  ],
34
- isComplete: () => !!process.env.GMAIL_REFRESH_TOKEN,
45
+ isComplete: async (ctx) =>
46
+ ctx?.userEmail ? hasOAuthTokens("google", ctx.userEmail) : false,
35
47
  });
36
48
  ```
37
49
 
@@ -4,17 +4,19 @@ description: >-
4
4
  How to keep template code database-agnostic and hosting-agnostic. Use when
5
5
  defining schemas, writing raw SQL, creating server routes, or anything that
6
6
  could leak a SQLite-only, Postgres-only, or Node-only assumption.
7
+ metadata:
8
+ internal: true
7
9
  ---
8
10
 
9
11
  # Portability
10
12
 
11
13
  ## Rule
12
14
 
13
- **Never write code that only works on one database or one hosting platform.** Templates must run on any SQL database (SQLite, Postgres, D1, Turso, Supabase, Neon) and any Nitro deploy target (Node, Cloudflare, Netlify, Vercel, Deno, Lambda, Bun) without code changes.
15
+ **Never write code that only works on one database or one hosting platform.** Templates must run on portable SQL backends (SQLite, Postgres, D1, Turso/libSQL, Supabase, Neon, managed platform SQL environments when available) and any Nitro deploy target (Node, Cloudflare, Netlify, Vercel, Deno, Lambda, Bun) without code changes.
14
16
 
15
17
  ## Database Agnostic
16
18
 
17
- Use the dialect-agnostic schema helpers from `@agent-native/core/db/schema`:
19
+ Use the dialect-agnostic schema helpers from `@agent-native/core/db/schema` for schemas and Drizzle's query builder for reads/writes:
18
20
 
19
21
  ```ts
20
22
  import {
@@ -47,6 +49,20 @@ export const meals = table("meals", {
47
49
 
48
50
  **Never import from `drizzle-orm/sqlite-core` or `drizzle-orm/pg-core` directly in template code.** Always use `@agent-native/core/db/schema` instead.
49
51
 
52
+ Use Drizzle's portable query DSL for app code:
53
+
54
+ ```ts
55
+ import { and, desc, eq } from "drizzle-orm";
56
+
57
+ const rows = await db
58
+ .select()
59
+ .from(meals)
60
+ .where(and(eq(meals.ownerEmail, userEmail), eq(meals.archived, false)))
61
+ .orderBy(desc(meals.createdAt));
62
+ ```
63
+
64
+ Avoid `db.execute(...)`, `getDbExec()`, and handwritten SQL in actions, handlers, and stores when Drizzle can express the query. Raw SQL should be limited to additive migrations, health checks, carefully reviewed advanced queries, or one-off maintenance scripts. For timestamps in Drizzle schemas, use `.default(now())`; for migration SQL, use `runMigrations()` so framework-supported compatibility rewrites and dialect-gated statements stay centralized.
65
+
50
66
  ### Raw SQL helpers
51
67
 
52
68
  - `getDbExec()` — auto-converts `?` params to `$1` for Postgres
@@ -55,7 +71,11 @@ export const meals = table("meals", {
55
71
 
56
72
  ### Never
57
73
 
58
- Never write SQLite-only syntax: `INSERT OR REPLACE`, `AUTOINCREMENT`, `datetime('now')`. When writing docs, say "SQL database" — not "SQLite".
74
+ Never write SQLite-only syntax in product code or docs examples: `INSERT OR REPLACE`, `AUTOINCREMENT`, `datetime('now')`. When writing docs, say "SQL database" — not "SQLite".
75
+
76
+ Never write Postgres-only syntax in shared app code either: `ILIKE`, `::type` casts, `jsonb_*`, `RETURNING` assumptions, serial/identity syntax, `ON CONFLICT` upserts, or `ALTER ... TYPE` unless the code is inside a dialect-gated migration block. Prefer Drizzle APIs or framework helpers.
77
+
78
+ When giving deployment guidance, be precise about durability: local SQLite is the development fallback, while production needs a persistent `DATABASE_URL`. Do not steer users to Turso as the only path; it is one option among Neon, Supabase, Turso/libSQL, plain Postgres, durable SQLite, D1 bindings, and managed platform SQL environments when available.
59
79
 
60
80
  ## Hosting Agnostic
61
81
 
@@ -65,9 +85,11 @@ The server runs on **Nitro** with **H3** as the HTTP framework. Templates must b
65
85
 
66
86
  All server code uses H3/Nitro: `defineEventHandler`, `readBody`, `getMethod`, `setResponseHeader`, etc. Express is not a dependency. If you see Express types or patterns anywhere, replace them with H3 equivalents.
67
87
 
68
- ### No platform-specific config in templates
88
+ ### No platform-specific config in scaffolded template source
89
+
90
+ Files like `netlify.toml`, `wrangler.toml`, `vercel.json`, and `netlify/functions/` must NOT appear in the CLI scaffold source (`packages/core/src/templates/`) — apps generated for users stay hosting-agnostic, with platform configuration living in CI/hosting dashboards.
69
91
 
70
- Files like `netlify.toml`, `wrangler.toml`, `vercel.json`, and `netlify/functions/` do not belong in template source. Platform configuration lives in CI/hosting dashboards or in deployment-specific repos.
92
+ **Exception:** this monorepo's own first-party deployed apps (`templates/*/netlify.toml`, the root `wrangler-*.toml` files) are deployment artifacts of _this_ repo (mail.agent-native.com, etc.) and are expected to exist. Do not delete them as if they were accidental cruft the rule above is about what gets scaffolded into a new app, not about this repo's deploy configs.
71
93
 
72
94
  ### No Node APIs in server routes/plugins
73
95
 
@@ -5,6 +5,8 @@ description: >-
5
5
  apps end-to-end, finding and fixing bugs, or running a QA sweep. Invoke as
6
6
  /qa with optional --apps and --focus args.
7
7
  user-invocable: true
8
+ metadata:
9
+ internal: true
8
10
  ---
9
11
 
10
12
  # QA Testing
@@ -19,6 +21,15 @@ Autonomous QA testing that spins up template apps, tests them with Playwright in
19
21
  /qa --focus "test form submission and compose" # prioritize specific flows
20
22
  ```
21
23
 
24
+ ## Browser MCP Readiness
25
+
26
+ QA can use the framework's built-in browser MCP capabilities instead of a hand-written `mcp.config.json`. The built-ins are off by default and are toggled through `/_agent-native/mcp/builtin`.
27
+
28
+ - Prefer `browser-playwright` for automated QA sweeps: it runs `npx -y @playwright/mcp@0.0.75`.
29
+ - Use `browser-chrome-devtools` only when the test specifically needs to attach to a live Chrome session. It runs `npx -y chrome-devtools-mcp@0.26.0 --autoConnect --no-usage-statistics` and requires Chrome 144+ with remote debugging enabled. Do not assume it signs into the user's Chrome profile.
30
+ - Browser built-ins are exclusive per scope: enabling Chrome disables Playwright and enabling Playwright disables Chrome.
31
+ - `computer-use` runs `npx -y computer-use-mcp@1.8.0` and is macOS-only.
32
+
22
33
  **Args:**
23
34
 
24
35
  - `--apps` — comma-separated app names (default: `mail,calendar,content,forms`)
@@ -39,14 +50,16 @@ Parse the user's invocation to determine:
39
50
 
40
51
  For each app, check if required credentials exist:
41
52
 
42
- | App | Check | Can test without? |
43
- |----------|-------------------------------------------------|-------------------|
44
- | forms | No credentials needed | Yes |
45
- | content | No credentials needed (Notion is opt-in) | Yes |
46
- | calendar | `templates/calendar/.env` has GOOGLE_CLIENT_ID | Partially — local events work, Google sync won't |
47
- | mail | `templates/mail/.env` has GOOGLE_CLIENT_ID | Partially — UI renders, Gmail features won't |
53
+ | App | Check | Can test without? |
54
+ | -------- | -------------------------------------------------------- | ----------------- |
55
+ | forms | No credentials needed | Yes |
56
+ | content | No credentials needed (Notion is opt-in) | Yes |
57
+ | calendar | `templates/calendar/.env` has `GOOGLE_CLIENT_ID` present | Partially — local events work, Google sync won't |
58
+ | mail | `templates/mail/.env` has `GOOGLE_CLIENT_ID` present | Partially — UI renders, Gmail features won't |
48
59
 
49
- Read each app's `.env` file (if it exists) to check. If credentials are missing:
60
+ Read each app's `.env` file (if it exists) only to check whether required names
61
+ are present. Never print, copy, summarize, paste, or pass `.env` values into
62
+ tester prompts, reports, screenshots, logs, or chat. If credentials are missing:
50
63
 
51
64
  - Still test the app — many features work without external APIs
52
65
  - Include in the tester's instructions: "No Google credentials found. Test local features. Flag any feature that crashes without credentials as 'needs credentials' rather than a bug."
@@ -79,7 +92,8 @@ For each app, read these files to understand what to test:
79
92
 
80
93
  1. `templates/<app>/app/routes/` or `templates/<app>/app/routes.ts` — discover all pages
81
94
  2. `templates/<app>/CLAUDE.md` — features, API routes, data model
82
- 3. `templates/<app>/server/routes/api/` — API endpoints
95
+ 3. `templates/<app>/actions/` — domain operations the UI and agent share
96
+ 4. `templates/<app>/server/routes/api/` — route-only endpoints such as uploads, streaming, webhooks, and OAuth callbacks
83
97
 
84
98
  Combine with any `--focus` guidance to produce a test plan. The test plan is a numbered list of user-facing flows to verify. Example:
85
99
 
@@ -311,3 +325,5 @@ This is a known issue. The tester should:
311
325
  3. Check the server plugin that loads credentials
312
326
  4. Try to fix the credential detection logic
313
327
  5. If unfixable, report as "needs review" with details about what the app expects vs. what's configured
328
+
329
+ Only report variable names and presence/absence. Do not include secret values.
@@ -4,6 +4,8 @@ description: >-
4
4
  Multi-user collaborative editing with Yjs CRDT and live cursors. Use when
5
5
  adding real-time collaborative editing to a template, debugging sync issues,
6
6
  or understanding how the agent and humans edit documents simultaneously.
7
+ metadata:
8
+ internal: true
7
9
  ---
8
10
 
9
11
  # Real-Time Collaboration
@@ -23,11 +25,55 @@ Collaborative editing uses Yjs CRDT via TipTap. The agent and human users are eq
23
25
  ## Agent + Human Editing
24
26
 
25
27
  1. **Human edits** → TipTap → ySyncPlugin → Y.XmlFragment → `POST /_agent-native/collab/:docId/update`
26
- 2. **Agent edits** → `edit-document` action server search-replace → Y.XmlFragment mutation → poll update → all clients
28
+ 2. **Agent edits** → action edits canonical SQL content + bumps `updatedAt` → change-sync refetch the open editor reconciles the new content into the live Y.Doc (see below) → poll update → all clients
27
29
 
28
- Both produce minimal Yjs operations that merge cleanly. Agent edits appear without destroying cursor position, selection, or undo history.
30
+ Both produce Yjs operations that merge cleanly. Agent edits appear without destroying cursor position, selection, or undo history.
29
31
 
30
- The `edit-document` action uses surgical search-and-replace on Y.XmlText nodes more efficient than regenerating the entire document.
32
+ This is how content (documents) and slides now work. The agent does **not** push edits into Yjs in-process, and it does **not** call any `findCollabOrigin()` / localhost probe — that approach silently no-op'd on serverless (the action runs in a different process), so agent edits didn't show up live until the user navigated away and back. Nor does it search-and-replace inside existing Y.XmlText nodes, which could never create new block structure (lists, headings, tables). The peer-editor model below replaces both.
33
+
34
+ ## Agent Edits As A Real-Time Peer Editor
35
+
36
+ The agent edits documents the same way a human collaborator does: its change lands in the shared Y.Doc, propagates to every connected client, and persists. It gets there without any in-process Yjs push from the action.
37
+
38
+ **SQL is the durable source of truth for document body content.** The agent action edits the canonical content (e.g. `documents.content`) and bumps `updatedAt`. That's the whole server side — no localhost calls, no Yjs mutation from the action.
39
+
40
+ **The open editor reconciles authoritative external content into the live Y.Doc.** The action's `updatedAt` bump flows through the change-sync system (see `real-time-sync`), which refetches the record. The editor applies the new content through its real markdown/HTML pipeline via `setContent`, so new block structure (lists, headings, tables) renders correctly and merges with concurrent human edits through the Yjs CRDT diff. The result: the agent's edit propagates to every connected client and persists, exactly like a human collaborator's edit.
41
+
42
+ ### The `updatedAt` gate
43
+
44
+ The editor only adopts content that is genuinely **newer** than what it already reflects. An older-or-equal `updatedAt` is a lagging poll or a stale snapshot and is **ignored**.
45
+
46
+ ```ts
47
+ // Pseudocode in the editor's reconcile effect
48
+ if (loaded.updatedAt > lastAppliedUpdatedAt.current) {
49
+ applyAuthoritativeContent(loaded.content); // adopt
50
+ lastAppliedUpdatedAt.current = loaded.updatedAt;
51
+ }
52
+ // else: lagging poll / stale snapshot → ignore
53
+ ```
54
+
55
+ **Why:** without the gate, a slightly-behind poll response re-applies old content right after the agent's edit, so the edit "reverts on the next poll" / "doesn't show until refresh" — the whack-a-mole we kept hitting. A **fresh mount or doc-switch has no baseline**, so it always adopts whatever content it loaded — which is why a manual refresh is always correct.
56
+
57
+ ### Lead-client election
58
+
59
+ Exactly ONE connected client applies an authoritative snapshot into the shared Y.Doc; the rest receive it through normal Yjs sync. The lead is the present client with the lowest Yjs `clientID`, decided by the core helper:
60
+
61
+ ```ts
62
+ import { isReconcileLeadClient } from "@agent-native/core/client";
63
+
64
+ if (
65
+ loaded.updatedAt > lastAppliedUpdatedAt.current &&
66
+ isReconcileLeadClient(provider.awareness, ydoc.clientID)
67
+ ) {
68
+ applyAuthoritativeContent(loaded.content);
69
+ }
70
+ ```
71
+
72
+ **Why:** if every open editor independently diffed the same snapshot into the CRDT, each would insert the changed region at the same position, duplicating it N times (concurrent inserts → duplicated text). Electing one lead avoids that. The agent's awareness id (`AGENT_CLIENT_ID`, max int) can never win, and a client editing alone is always the lead. The election is deterministic across clients with no coordination round-trip.
73
+
74
+ ### v1 limitation
75
+
76
+ A full-content reconcile is **last-writer-wins for the rare case** where a human has unsaved edits in the exact region the agent simultaneously rewrites — the agent's snapshot can clobber that in-flight human edit. Inline and structural edits in **different** regions merge fine through the CRDT; only same-region simultaneous rewrites are at risk.
31
77
 
32
78
  ## Enabling Collaboration
33
79
 
@@ -101,12 +147,12 @@ optimizeDeps: {
101
147
  ## Common Pitfalls
102
148
 
103
149
  - **Don't pass `content` as a TipTap prop** when Collaboration is enabled — Yjs owns the content. Set initial content via the Y.Doc instead.
104
- - **Don't use `editor.setContent()`** for agent edits — it bypasses Yjs and causes conflicts. Use the `search-replace` route or `edit-document` action.
150
+ - **Don't call `editor.setContent()` ad hoc for agent edits.** The only sanctioned `setContent` is the editor's reconcile path described above gated by `updatedAt` and guarded by `isReconcileLeadClient`. Calling it from elsewhere (e.g. on every poll, or from every client) re-applies stale content or duplicates the changed region across the CRDT.
105
151
  - **Add packages to `optimizeDeps`** — Vite won't pre-bundle Yjs packages correctly otherwise, causing runtime errors in dev.
106
152
  - **One `Y.Doc` per document** — Don't create multiple Y.Doc instances for the same document ID. Use the `useCollaborativeDoc` hook which caches by ID.
107
153
 
108
154
  ## Related Skills
109
155
 
110
- - `real-time-sync` — Polling infrastructure that delivers Y.Doc updates
111
- - `storing-data` — The `_collab_docs` table where Yjs state is persisted
112
- - `self-modifying-code` — Agent edits to collaborative documents go through `edit-document`, not raw SQL
156
+ - `real-time-sync` — The change-sync system that delivers the `updatedAt` bump driving editor reconciliation; also `useReconciledState` for non-collaborative "copy a server value into local edit state" surfaces
157
+ - `storing-data` — The `_collab_docs` table where Yjs state is persisted; SQL holds the canonical document body that the editor reconciles from
158
+ - `self-modifying-code` — Agent edits to collaborative documents edit canonical SQL content, not raw Yjs
@@ -4,6 +4,8 @@ description: >-
4
4
  How to keep the UI in sync with agent changes via SSE plus polling fallback.
5
5
  Use when wiring query invalidation for new data models, debugging UI not
6
6
  updating, or understanding jitter prevention.
7
+ metadata:
8
+ internal: true
7
9
  ---
8
10
 
9
11
  # Real-Time Sync
@@ -20,7 +22,7 @@ The agent modifies data in SQL, but the UI runs in the browser. SSE bridges same
20
22
 
21
23
  1. **Server** increments a version counter on every database write. In-process events stream through the authenticated `/_agent-native/events` endpoint.
22
24
 
23
- 2. **Client** listens for SSE/poll events and updates per-source change counters:
25
+ 2. **Client** listens for sync events and updates per-source change counters:
24
26
 
25
27
  ```ts
26
28
  import { useDbSync } from "@agent-native/core";
@@ -47,9 +49,9 @@ The agent modifies data in SQL, but the UI runs in the browser. SSE bridges same
47
49
 
48
50
  For list/sidebar queries, use the same pattern — pass the counter into the queryKey of every list query you want to keep fresh.
49
51
 
50
- 3. **Fallback** polling calls `/_agent-native/poll?since=N`. It runs every 2 seconds until SSE is connected, then relaxes to 15 seconds. If SSE is disabled or unavailable, polling continues at the normal cadence.
52
+ 4. **Fallback** polling calls `/_agent-native/poll?since=N`. It runs every 2 seconds until SSE is connected, then relaxes to 15 seconds. If SSE is disabled or unavailable, polling continues at the normal cadence.
51
53
 
52
- 4. When the agent writes to the database, the version increments, SSE/polling detects it, and React Query refetches the affected queries.
54
+ 5. When the agent writes to the database, the version increments, SSE/polling detects it, and React Query refetches the affected queries.
53
55
 
54
56
  ## Don't
55
57
 
@@ -132,9 +134,9 @@ The `use-navigation-state.ts` hook sends the same `TAB_ID` in the `X-Request-Sou
132
134
 
133
135
  Without jitter prevention, a cycle occurs: the UI writes state, sync detects the change, the UI refetches and re-renders, potentially overwriting what the user is actively editing. With `ignoreSource`, the UI only reacts to changes from other sources (agent scripts, other browser tabs, other users).
134
136
 
135
- ## Action Routes and Polling
137
+ ## Action Routes and Live Sync
136
138
 
137
- Action routes (`/_agent-native/actions/:name`) work with the same sync system. When a POST/PUT/DELETE action writes to the database, the version counter increments and `useDbSync` picks up the change. Frontend mutations via `useActionMutation` automatically invalidate `["action"]` query keys on success, triggering refetches of `useActionQuery` hooks.
139
+ Actions work with the same sync system. When a mutating action writes to the database, the version counter increments and `useDbSync` picks up the change. Frontend mutations via `useActionMutation` automatically invalidate `["action"]` query keys on success, triggering refetches of `useActionQuery` hooks. Client components should call actions through those hooks, not with raw action-route fetches.
138
140
 
139
141
  For custom apps, the best out-of-the-box path is:
140
142
 
@@ -146,14 +148,13 @@ This avoids duplicate `/api/*` JSON CRUD routes and makes agent-created records
146
148
 
147
149
  ### Auto-emit on mutating actions
148
150
 
149
- The framework emits a poll event with `source: "action"` whenever any non-read-only action runs to completion — whether called via HTTP (`/_agent-native/actions/:name`) or as an agent tool call. Read-only actions (`http: { method: "GET" }` or explicit `readOnly: true`) are skipped.
151
+ The framework emits a change event with `source: "action"` whenever any non-read-only action runs to completion — whether called via HTTP (`/_agent-native/actions/:name`) or as an agent tool call. Read-only actions (`http: { method: "GET" }` or explicit `readOnly: true`) are skipped.
150
152
 
151
153
  This means UIs don't need the agent to remember to call `refresh-screen` after every mutation. A listener like this (used in the `macros` template) will refresh after any mutating agent call:
152
154
 
153
155
  ```ts
154
156
  useDbSync({
155
157
  queryClient,
156
- queryKeys: [],
157
158
  ignoreSource: TAB_ID,
158
159
  onEvent: (data) => {
159
160
  if (data.requestSource === TAB_ID) return;
@@ -165,9 +166,41 @@ useDbSync({
165
166
 
166
167
  `refresh-screen` remains available for unusual cases — e.g. the agent mutated data via a path the framework can't see (external system the app mirrors), or the agent wants to pass a `scope` hint for narrower invalidation.
167
168
 
169
+ ## Keeping Stateful Components In Sync
170
+
171
+ The `useChangeVersion` / `useActionQuery` pattern above keeps the **query layer** fresh. But components that copy a server value into local React state still go stale on agent edits — refetching the query updates the prop, yet the local copy never re-adopts it. This is a recurring bug.
172
+
173
+ **Never do this** for a value the agent can mutate:
174
+
175
+ ```ts
176
+ // BUG: `title` is captured once and never re-reads the prop.
177
+ const [title, setTitle] = useState(props.title);
178
+ ```
179
+
180
+ When the agent renames the record, the query refetches, `props.title` updates, but the input still shows the stale value until the component remounts.
181
+
182
+ **Derived-state surfaces (form fields, inline editors, popovers): use `useReconciledState`.** It re-adopts the authoritative external value when it changes, except while the user is actively editing that field — so agent mutations show up live without clobbering in-progress typing:
183
+
184
+ ```ts
185
+ import { useReconciledState } from "@agent-native/core/client";
186
+
187
+ // `active` = true while the user is editing this field (focused / dirty).
188
+ const [title, setTitle] = useReconciledState(props.title, { active: isEditing });
189
+ ```
190
+
191
+ **Collaborative rich-text editors are different** — they don't copy a value into `useState`. They reconcile authoritative SQL content into a shared Y.Doc under an `updatedAt` gate with lead-client election. See `real-time-collab` → "Agent edits as a real-time peer editor". Don't reach for `useReconciledState` for a Yjs-backed editor.
192
+
193
+ | Surface | Keep it fresh with |
194
+ | ------- | ------------------ |
195
+ | React Query reads | `useChangeVersion` / `useActionQuery` (above) |
196
+ | Local edit state copied from a server value (inputs, popovers, inline editors) | `useReconciledState(externalValue, { active })` |
197
+ | Collaborative rich-text editor (Yjs) | `updatedAt`-gated reconcile + `isReconcileLeadClient` — see `real-time-collab` |
198
+
168
199
  ## Related Skills
169
200
 
170
- - **storing-data** — Application-state and settings are the data stores that sync via polling
201
+ - **storing-data** — Application-state and settings are data stores that sync through change events
171
202
  - **context-awareness** — Navigation state writes use jitter prevention to avoid overwriting active edits
172
- - **actions** — Action routes auto-expose actions as HTTP endpoints; database writes trigger poll events
173
- - **self-modifying-code** — Agent code edits trigger poll events; rapid edits can cause event storms
203
+ - **actions** — Mutating actions trigger change events
204
+ - **client-methods** — Route details belong in helpers/hooks, not components
205
+ - **self-modifying-code** — Agent code edits trigger change events; rapid edits can cause event storms
206
+ - **real-time-collab** — Collaborative editors reconcile agent edits into a shared Y.Doc, driven by the same change-sync `updatedAt` bump
@@ -4,6 +4,8 @@ description: >-
4
4
  Scheduled tasks the agent runs on a cron schedule. Use when a user asks for
5
5
  something recurring ("every morning", "daily", "weekly"), when creating or
6
6
  updating jobs, or when debugging the job scheduler.
7
+ metadata:
8
+ internal: true
7
9
  ---
8
10
 
9
11
  # Recurring Jobs
@@ -5,10 +5,24 @@ description: >-
5
5
  they appear in the agent sidebar settings UI and the onboarding checklist.
6
6
  Use for any third-party API key (OpenAI, Stripe, Twilio, etc.) and for
7
7
  surfacing OAuth connections in the unified settings UI.
8
+ metadata:
9
+ internal: true
8
10
  ---
9
11
 
10
12
  # Secrets Registry
11
13
 
14
+ ## Non-negotiable rule
15
+
16
+ Never hardcode credential values. Source, docs, tests, fixtures, prompts, seed
17
+ data, and generated extension/app content may mention credential **names** such
18
+ as `OPENAI_API_KEY`, but must not contain real API keys, tokens, webhook URLs,
19
+ signing secrets, OAuth refresh tokens, or private Builder/customer data.
20
+
21
+ Secret values are supplied at runtime through deployment configuration, the
22
+ encrypted `app_secrets` vault, `saveCredential` / `resolveCredential`, OAuth, or
23
+ `${keys.NAME}` substitution. Examples must use obvious placeholders such as
24
+ `<OPENAI_API_KEY>` or `${keys.SLACK_WEBHOOK}`, not real-looking copied values.
25
+
12
26
  ## When to use
13
27
 
14
28
  Use this for any external credential your template needs: API keys, service
@@ -96,25 +110,24 @@ row is written — status is derived from `hasOAuthTokens("google")`.
96
110
  ## Reading a secret from an action
97
111
 
98
112
  ```ts
113
+ import { z } from "zod";
99
114
  import { defineAction } from "@agent-native/core";
100
115
  import { readAppSecret } from "@agent-native/core/secrets";
101
- import { getSession } from "@agent-native/core/server";
116
+ import { getRequestUserEmail } from "@agent-native/core/server";
102
117
 
103
118
  export default defineAction({
104
- name: "transcribe-audio",
105
119
  description: "Transcribe an audio file with Whisper",
106
- input: { fileUrl: "string" },
107
- handler: async ({ fileUrl }, ctx) => {
108
- const session = await getSession(ctx.event);
109
- if (!session?.email) throw new Error("Not signed in");
120
+ schema: z.object({ fileUrl: z.string() }),
121
+ run: async ({ fileUrl }) => {
122
+ const email = await getRequestUserEmail();
123
+ if (!email) throw new Error("Not signed in");
110
124
 
111
125
  const stored = await readAppSecret({
112
126
  key: "OPENAI_API_KEY",
113
127
  scope: "user",
114
- scopeId: session.email,
128
+ scopeId: email,
115
129
  });
116
- // Env var wins if set (useful for hosted deployments).
117
- const apiKey = process.env.OPENAI_API_KEY ?? stored?.value;
130
+ const apiKey = stored?.value;
118
131
  if (!apiKey) {
119
132
  throw new Error(
120
133
  "OPENAI_API_KEY is not set. Configure it in the sidebar settings.",
@@ -130,8 +143,10 @@ Rules:
130
143
 
131
144
  - **Never log the value.** The read layer enforces this server-side; your
132
145
  code must do the same.
133
- - **Check `process.env[key]` first.** Env vars win so ops teams can set keys
134
- via deploy configuration without the user ever visiting the sidebar.
146
+ - **Use env vars only for deploy-level secrets.** If a credential is
147
+ user-scoped, org-scoped, or workspace-scoped, read the scoped vault/credential
148
+ store. Do not add a `process.env` fallback that makes every user inherit one
149
+ deployment's key.
135
150
  - **Scope matches the registration.** `scope: "user"` → pass the user email.
136
151
  `scope: "workspace"` → pass the active `orgId` from
137
152
  `getOrgContext(event).orgId`.
@@ -187,7 +202,7 @@ with any URL.
187
202
  POST /_agent-native/secrets/adhoc
188
203
  {
189
204
  "name": "SLACK_WEBHOOK",
190
- "value": "https://hooks.slack.com/services/T00/B00/xxxx",
205
+ "value": "<SLACK_WEBHOOK_URL_FROM_SETTINGS>",
191
206
  "urlAllowlist": ["https://hooks.slack.com"]
192
207
  }
193
208
  ```
@@ -208,12 +223,12 @@ import {
208
223
  const { resolved, usedKeys } = await resolveKeyReferences(
209
224
  "Bearer ${keys.API_TOKEN}",
210
225
  "user",
211
- "owner@example.com",
226
+ "user@example.com",
212
227
  );
213
228
 
214
229
  // Validate a URL against a key's allowlist
215
230
  const allowed = validateUrlAllowlist(
216
- "https://hooks.slack.com/services/T00/B00/xxxx",
231
+ "https://hooks.slack.com/services/<WORKSPACE>/<CHANNEL>/<SECRET>",
217
232
  ["https://hooks.slack.com"],
218
233
  );
219
234
  ```
@@ -222,6 +237,20 @@ Key resolution falls back from user scope to workspace scope, so users can
222
237
  override shared keys without breaking automations that reference workspace
223
238
  defaults.
224
239
 
240
+ ## Dispatch Vault Access
241
+
242
+ Dispatch workspaces have a vault access policy for workspace app credentials:
243
+
244
+ - `all-apps` is the default. Every saved Dispatch vault key is available to
245
+ every workspace app; `sync-vault-to-app` pushes all vault keys to the target
246
+ app.
247
+ - `manual` requires explicit per-app grants. Use
248
+ `create-vault-grant` / `grant-vault-secrets-to-app`, then
249
+ `sync-vault-to-app`.
250
+
251
+ Use `get-vault-access-settings` before deciding whether to create grants, and
252
+ use `set-vault-access-settings` only when the user asks to change the policy.
253
+
225
254
  ### Key Files (ad-hoc)
226
255
 
227
256
  | File | Purpose |