@agent-native/core 0.127.1 → 0.128.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 (431) hide show
  1. package/corpus/README.md +2 -2
  2. package/corpus/core/CHANGELOG.md +92 -0
  3. package/corpus/core/README.md +5 -26
  4. package/corpus/core/docs/content/actions.mdx +47 -4
  5. package/corpus/core/docs/content/native-chat-ui.mdx +7 -0
  6. package/corpus/core/docs/content/organizations-teams-permissions.mdx +109 -3
  7. package/corpus/core/docs/content/template-design-collaboration-and-full-apps.mdx +15 -0
  8. package/corpus/core/docs/content/toolkit-org-team.mdx +72 -12
  9. package/corpus/core/package.json +1 -1
  10. package/corpus/core/src/a2a/artifact-response.ts +36 -29
  11. package/corpus/core/src/action.ts +83 -2
  12. package/corpus/core/src/chat-threads/store.ts +48 -43
  13. package/corpus/core/src/cli/skills-content/design-visual-edit-skill.ts +46 -3
  14. package/corpus/core/src/cli/template-sync.ts +96 -0
  15. package/corpus/core/src/client/AgentPanel.tsx +26 -6
  16. package/corpus/core/src/client/AssistantChat.tsx +63 -7
  17. package/corpus/core/src/client/DefaultSpinner.tsx +29 -0
  18. package/corpus/core/src/client/org/TeamPage.tsx +161 -6
  19. package/corpus/core/src/client/org/hooks.ts +67 -0
  20. package/corpus/core/src/client/org/index.ts +9 -0
  21. package/corpus/core/src/client/transcription/use-live-transcription.ts +62 -10
  22. package/corpus/core/src/db/client.ts +42 -3
  23. package/corpus/core/src/db/ensure-additive-columns.ts +60 -33
  24. package/corpus/core/src/deploy/build.ts +31 -2
  25. package/corpus/core/src/mcp-client/routes.ts +10 -1
  26. package/corpus/core/src/org/app-roles-handlers.ts +152 -0
  27. package/corpus/core/src/org/app-roles.ts +355 -0
  28. package/corpus/core/src/org/index.ts +27 -1
  29. package/corpus/core/src/org/migrations.ts +22 -0
  30. package/corpus/core/src/org/plugin.ts +27 -0
  31. package/corpus/core/src/org/schema.ts +15 -0
  32. package/corpus/core/src/scripts/docs/search.ts +17 -0
  33. package/corpus/core/src/scripts/docs/source-search.ts +10 -0
  34. package/corpus/core/src/server/agent-chat/script-entries.ts +3 -0
  35. package/corpus/core/src/server/agent-chat-plugin.ts +53 -52
  36. package/corpus/core/src/server/builder-design-systems.ts +1 -1
  37. package/corpus/core/src/server/core-routes-plugin.ts +6 -1
  38. package/corpus/core/src/server/framework-request-handler.ts +44 -6
  39. package/corpus/core/src/templates/default/.agents/skills/actions/SKILL.md +32 -0
  40. package/corpus/core/src/templates/default/.agents/skills/adding-a-feature/SKILL.md +7 -0
  41. package/corpus/core/src/templates/default/.agents/skills/security/SKILL.md +31 -0
  42. package/corpus/core/src/templates/headless/.agents/skills/actions/SKILL.md +32 -0
  43. package/corpus/core/src/templates/workspace-core/.agents/skills/actions/SKILL.md +32 -0
  44. package/corpus/core/src/templates/workspace-core/.agents/skills/adding-a-feature/SKILL.md +7 -0
  45. package/corpus/core/src/templates/workspace-core/.agents/skills/authentication/SKILL.md +40 -0
  46. package/corpus/core/src/templates/workspace-core/.agents/skills/security/SKILL.md +31 -0
  47. package/corpus/core/src/templates/workspace-core/.agents/skills/sharing/SKILL.md +4 -0
  48. package/corpus/templates/analytics/.agents/skills/actions/SKILL.md +32 -0
  49. package/corpus/templates/analytics/.agents/skills/security/SKILL.md +31 -0
  50. package/corpus/templates/analytics/.agents/skills/sharing/SKILL.md +4 -0
  51. package/corpus/templates/analytics/actions/data-source-status.ts +21 -12
  52. package/corpus/templates/analytics/app/global.css +7 -7
  53. package/corpus/templates/analytics/app/i18n-data.ts +30 -0
  54. package/corpus/templates/analytics/app/lib/data-source-status.ts +2 -1
  55. package/corpus/templates/analytics/app/pages/DataSources.tsx +54 -10
  56. package/corpus/templates/analytics/changelog/2026-07-28-analytics-pages-load-reliably-with-large-dashboard-workspaces.md +6 -0
  57. package/corpus/templates/analytics/changelog/2026-07-28-dashboard-loading-shimmer-now-flows-smoothly-in-one-directi.md +6 -0
  58. package/corpus/templates/analytics/server/lib/first-party-dashboard-repair.ts +5 -4
  59. package/corpus/templates/analytics/server/plugins/agent-chat.ts +54 -42
  60. package/corpus/templates/analytics/server/plugins/db.ts +1 -18
  61. package/corpus/templates/assets/.agents/skills/actions/SKILL.md +32 -0
  62. package/corpus/templates/assets/.agents/skills/security/SKILL.md +31 -0
  63. package/corpus/templates/assets/.agents/skills/sharing/SKILL.md +4 -0
  64. package/corpus/templates/brain/.agents/skills/actions/SKILL.md +32 -0
  65. package/corpus/templates/brain/.agents/skills/adding-a-feature/SKILL.md +7 -0
  66. package/corpus/templates/brain/.agents/skills/security/SKILL.md +31 -0
  67. package/corpus/templates/brain/.agents/skills/sharing/SKILL.md +4 -0
  68. package/corpus/templates/calendar/.agents/skills/actions/SKILL.md +32 -0
  69. package/corpus/templates/calendar/.agents/skills/security/SKILL.md +31 -0
  70. package/corpus/templates/calendar/.agents/skills/sharing/SKILL.md +4 -0
  71. package/corpus/templates/chat/.agents/skills/actions/SKILL.md +32 -0
  72. package/corpus/templates/chat/.agents/skills/adding-a-feature/SKILL.md +7 -0
  73. package/corpus/templates/chat/.agents/skills/security/SKILL.md +31 -0
  74. package/corpus/templates/chat/.agents/skills/sharing/SKILL.md +4 -0
  75. package/corpus/templates/chat/_gitignore +2 -0
  76. package/corpus/templates/clips/.agents/skills/actions/SKILL.md +32 -0
  77. package/corpus/templates/clips/.agents/skills/security/SKILL.md +31 -0
  78. package/corpus/templates/clips/actions/request-transcript.ts +77 -11
  79. package/corpus/templates/clips/actions/save-browser-transcript.ts +28 -7
  80. package/corpus/templates/clips/app/routes/record.tsx +11 -3
  81. package/corpus/templates/clips/changelog/2026-07-28-browser-recordings-no-longer-save-a-truncated-transcript-as-.md +6 -0
  82. package/corpus/templates/clips/changelog/2026-07-28-browser-recordings-no-longer-stop-transcribing-partway-throu.md +6 -0
  83. package/corpus/templates/clips/changelog/2026-07-28-desktop-full-screen-clips-now-get-an-instant-local-transcrip.md +6 -0
  84. package/corpus/templates/clips/changelog/2026-07-28-long-transcriptions-no-longer-show-a-false-transcription-sto.md +6 -0
  85. package/corpus/templates/clips/changelog/2026-07-28-restarting-for-an-update-now-installs-the-newest-release-ins.md +6 -0
  86. package/corpus/templates/clips/changelog/2026-07-28-the-meeting-recording-pill-now-anchors-to-the-right-edge-of-.md +6 -0
  87. package/corpus/templates/clips/desktop/src/lib/audio-meter.ts +31 -2
  88. package/corpus/templates/clips/desktop/src/lib/recorder.ts +114 -13
  89. package/corpus/templates/clips/desktop/src/lib/updater.ts +12 -4
  90. package/corpus/templates/clips/desktop/src/overlays/live-audio-bars.tsx +40 -15
  91. package/corpus/templates/clips/desktop/src/styles.css +10 -7
  92. package/corpus/templates/clips/desktop/src-tauri/src/recording_indicator.rs +21 -14
  93. package/corpus/templates/clips/shared/transcript-status.ts +10 -0
  94. package/corpus/templates/content/.agents/skills/actions/SKILL.md +32 -0
  95. package/corpus/templates/content/.agents/skills/security/SKILL.md +31 -0
  96. package/corpus/templates/content/.agents/skills/sharing/SKILL.md +4 -0
  97. package/corpus/templates/crm/.agents/skills/sharing/SKILL.md +4 -0
  98. package/corpus/templates/design/.agents/skills/actions/SKILL.md +32 -0
  99. package/corpus/templates/design/.agents/skills/design-generation/SKILL.md +23 -0
  100. package/corpus/templates/design/.agents/skills/security/SKILL.md +31 -0
  101. package/corpus/templates/design/.agents/skills/sharing/SKILL.md +4 -0
  102. package/corpus/templates/design/.agents/skills/visual-edit/SKILL.md +46 -3
  103. package/corpus/templates/design/.generated/bridge/editor-chrome.generated.ts +7 -5
  104. package/corpus/templates/design/actions/create-file.ts +15 -0
  105. package/corpus/templates/design/actions/generate-design.ts +40 -0
  106. package/corpus/templates/design/actions/present-design-variants.ts +16 -0
  107. package/corpus/templates/design/app/components/design/CanvasContextMenu.tsx +2 -2
  108. package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +7 -4
  109. package/corpus/templates/design/app/components/design/keyboard-shortcuts.ts +1 -1
  110. package/corpus/templates/design/app/hooks/useDesignHotkeys.ts +10 -4
  111. package/corpus/templates/design/app/lib/design-ui-events.ts +5 -0
  112. package/corpus/templates/design/app/pages/design-editor/save-failure.ts +7 -1
  113. package/corpus/templates/design/app/root.tsx +18 -1
  114. package/corpus/templates/design/changelog/2026-07-28-generated-designs-with-malformed-html-are-now-rejected-at-sa.md +6 -0
  115. package/corpus/templates/design/changelog/2026-07-28-show-or-hide-design-editing-chrome-with-cmd-on-apple-devices.md +6 -0
  116. package/corpus/templates/design/server/source-workspace.ts +1 -0
  117. package/corpus/templates/design/shared/html-integrity.ts +608 -18
  118. package/corpus/templates/dispatch/.agents/skills/actions/SKILL.md +32 -0
  119. package/corpus/templates/dispatch/.agents/skills/security/SKILL.md +31 -0
  120. package/corpus/templates/dispatch/.agents/skills/sharing/SKILL.md +4 -0
  121. package/corpus/templates/forms/.agents/skills/actions/SKILL.md +32 -0
  122. package/corpus/templates/forms/.agents/skills/security/SKILL.md +31 -0
  123. package/corpus/templates/forms/.agents/skills/sharing/SKILL.md +4 -0
  124. package/corpus/templates/macros/.agents/skills/security/SKILL.md +31 -0
  125. package/corpus/templates/macros/.agents/skills/sharing/SKILL.md +4 -0
  126. package/corpus/templates/mail/.agents/skills/actions/SKILL.md +32 -0
  127. package/corpus/templates/mail/.agents/skills/security/SKILL.md +31 -0
  128. package/corpus/templates/mail/.agents/skills/sharing/SKILL.md +4 -0
  129. package/corpus/templates/plan/.agents/skills/actions/SKILL.md +32 -0
  130. package/corpus/templates/plan/.agents/skills/adding-a-feature/SKILL.md +7 -0
  131. package/corpus/templates/plan/.agents/skills/security/SKILL.md +31 -0
  132. package/corpus/templates/plan/.agents/skills/sharing/SKILL.md +4 -0
  133. package/corpus/templates/slides/.agents/skills/actions/SKILL.md +32 -0
  134. package/corpus/templates/slides/.agents/skills/security/SKILL.md +31 -0
  135. package/corpus/templates/slides/.agents/skills/sharing/SKILL.md +4 -0
  136. package/corpus/templates/slides/app/components/deck/DeckCard.tsx +2 -6
  137. package/corpus/templates/tasks/.agents/skills/actions/SKILL.md +32 -0
  138. package/corpus/templates/tasks/.agents/skills/adding-a-feature/SKILL.md +7 -0
  139. package/corpus/templates/tasks/.agents/skills/security/SKILL.md +31 -0
  140. package/corpus/templates/tasks/.agents/skills/sharing/SKILL.md +4 -0
  141. package/dist/a2a/artifact-response.d.ts.map +1 -1
  142. package/dist/a2a/artifact-response.js +30 -29
  143. package/dist/a2a/artifact-response.js.map +1 -1
  144. package/dist/action.d.ts +36 -0
  145. package/dist/action.d.ts.map +1 -1
  146. package/dist/action.js +37 -2
  147. package/dist/action.js.map +1 -1
  148. package/dist/chat-threads/store.d.ts +12 -0
  149. package/dist/chat-threads/store.d.ts.map +1 -1
  150. package/dist/chat-threads/store.js +48 -42
  151. package/dist/chat-threads/store.js.map +1 -1
  152. package/dist/cli/skills-content/design-visual-edit-skill.d.ts +1 -1
  153. package/dist/cli/skills-content/design-visual-edit-skill.d.ts.map +1 -1
  154. package/dist/cli/skills-content/design-visual-edit-skill.js +46 -3
  155. package/dist/cli/skills-content/design-visual-edit-skill.js.map +1 -1
  156. package/dist/cli/template-sync.d.ts.map +1 -1
  157. package/dist/cli/template-sync.js +88 -0
  158. package/dist/cli/template-sync.js.map +1 -1
  159. package/dist/client/AgentPanel.d.ts +3 -1
  160. package/dist/client/AgentPanel.d.ts.map +1 -1
  161. package/dist/client/AgentPanel.js +11 -9
  162. package/dist/client/AgentPanel.js.map +1 -1
  163. package/dist/client/AssistantChat.d.ts.map +1 -1
  164. package/dist/client/AssistantChat.js +57 -6
  165. package/dist/client/AssistantChat.js.map +1 -1
  166. package/dist/client/DefaultSpinner.d.ts +7 -0
  167. package/dist/client/DefaultSpinner.d.ts.map +1 -1
  168. package/dist/client/DefaultSpinner.js +25 -1
  169. package/dist/client/DefaultSpinner.js.map +1 -1
  170. package/dist/client/org/TeamPage.d.ts +13 -1
  171. package/dist/client/org/TeamPage.d.ts.map +1 -1
  172. package/dist/client/org/TeamPage.js +41 -11
  173. package/dist/client/org/TeamPage.js.map +1 -1
  174. package/dist/client/org/hooks.d.ts +37 -0
  175. package/dist/client/org/hooks.d.ts.map +1 -1
  176. package/dist/client/org/hooks.js +37 -0
  177. package/dist/client/org/hooks.js.map +1 -1
  178. package/dist/client/org/index.d.ts +3 -2
  179. package/dist/client/org/index.d.ts.map +1 -1
  180. package/dist/client/org/index.js +1 -1
  181. package/dist/client/org/index.js.map +1 -1
  182. package/dist/client/transcription/use-live-transcription.d.ts +8 -0
  183. package/dist/client/transcription/use-live-transcription.d.ts.map +1 -1
  184. package/dist/client/transcription/use-live-transcription.js +38 -11
  185. package/dist/client/transcription/use-live-transcription.js.map +1 -1
  186. package/dist/collab/routes.d.ts +1 -1
  187. package/dist/collab/struct-routes.d.ts +1 -1
  188. package/dist/db/client.d.ts +12 -0
  189. package/dist/db/client.d.ts.map +1 -1
  190. package/dist/db/client.js +40 -3
  191. package/dist/db/client.js.map +1 -1
  192. package/dist/db/ensure-additive-columns.d.ts.map +1 -1
  193. package/dist/db/ensure-additive-columns.js +54 -32
  194. package/dist/db/ensure-additive-columns.js.map +1 -1
  195. package/dist/deploy/build.d.ts +1 -0
  196. package/dist/deploy/build.d.ts.map +1 -1
  197. package/dist/deploy/build.js +23 -2
  198. package/dist/deploy/build.js.map +1 -1
  199. package/dist/mcp-client/routes.d.ts +3 -1
  200. package/dist/mcp-client/routes.d.ts.map +1 -1
  201. package/dist/mcp-client/routes.js +8 -2
  202. package/dist/mcp-client/routes.js.map +1 -1
  203. package/dist/notifications/routes.d.ts +1 -1
  204. package/dist/observability/routes.d.ts +3 -3
  205. package/dist/org/app-roles-handlers.d.ts +27 -0
  206. package/dist/org/app-roles-handlers.d.ts.map +1 -0
  207. package/dist/org/app-roles-handlers.js +125 -0
  208. package/dist/org/app-roles-handlers.js.map +1 -0
  209. package/dist/org/app-roles.d.ts +136 -0
  210. package/dist/org/app-roles.d.ts.map +1 -0
  211. package/dist/org/app-roles.js +216 -0
  212. package/dist/org/app-roles.js.map +1 -0
  213. package/dist/org/index.d.ts +4 -1
  214. package/dist/org/index.d.ts.map +1 -1
  215. package/dist/org/index.js +3 -1
  216. package/dist/org/index.js.map +1 -1
  217. package/dist/org/migrations.d.ts.map +1 -1
  218. package/dist/org/migrations.js +22 -0
  219. package/dist/org/migrations.js.map +1 -1
  220. package/dist/org/plugin.d.ts +2 -0
  221. package/dist/org/plugin.d.ts.map +1 -1
  222. package/dist/org/plugin.js +20 -0
  223. package/dist/org/plugin.js.map +1 -1
  224. package/dist/org/schema.d.ts +143 -0
  225. package/dist/org/schema.d.ts.map +1 -1
  226. package/dist/org/schema.js +14 -0
  227. package/dist/org/schema.js.map +1 -1
  228. package/dist/provider-api/actions/custom-provider-registration.d.ts +4 -4
  229. package/dist/provider-api/actions/provider-api.d.ts +12 -12
  230. package/dist/resources/handlers.d.ts +1 -1
  231. package/dist/scripts/docs/search.d.ts.map +1 -1
  232. package/dist/scripts/docs/search.js +15 -0
  233. package/dist/scripts/docs/search.js.map +1 -1
  234. package/dist/scripts/docs/source-search.d.ts +7 -0
  235. package/dist/scripts/docs/source-search.d.ts.map +1 -1
  236. package/dist/scripts/docs/source-search.js +9 -0
  237. package/dist/scripts/docs/source-search.js.map +1 -1
  238. package/dist/server/agent-chat/script-entries.d.ts.map +1 -1
  239. package/dist/server/agent-chat/script-entries.js +3 -0
  240. package/dist/server/agent-chat/script-entries.js.map +1 -1
  241. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  242. package/dist/server/agent-chat-plugin.js +46 -48
  243. package/dist/server/agent-chat-plugin.js.map +1 -1
  244. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  245. package/dist/server/builder-design-systems.js +1 -1
  246. package/dist/server/builder-design-systems.js.map +1 -1
  247. package/dist/server/core-routes-plugin.d.ts.map +1 -1
  248. package/dist/server/core-routes-plugin.js +6 -1
  249. package/dist/server/core-routes-plugin.js.map +1 -1
  250. package/dist/server/framework-request-handler.d.ts.map +1 -1
  251. package/dist/server/framework-request-handler.js +42 -6
  252. package/dist/server/framework-request-handler.js.map +1 -1
  253. package/dist/server/transcribe-voice.d.ts +1 -1
  254. package/dist/templates/chat/.agents/skills/actions/SKILL.md +32 -0
  255. package/dist/templates/chat/.agents/skills/adding-a-feature/SKILL.md +7 -0
  256. package/dist/templates/chat/.agents/skills/security/SKILL.md +31 -0
  257. package/dist/templates/chat/.agents/skills/sharing/SKILL.md +4 -0
  258. package/dist/templates/chat/_gitignore +2 -0
  259. package/dist/templates/default/.agents/skills/actions/SKILL.md +32 -0
  260. package/dist/templates/default/.agents/skills/adding-a-feature/SKILL.md +7 -0
  261. package/dist/templates/default/.agents/skills/security/SKILL.md +31 -0
  262. package/dist/templates/headless/.agents/skills/actions/SKILL.md +32 -0
  263. package/dist/templates/workspace-core/.agents/skills/actions/SKILL.md +32 -0
  264. package/dist/templates/workspace-core/.agents/skills/adding-a-feature/SKILL.md +7 -0
  265. package/dist/templates/workspace-core/.agents/skills/authentication/SKILL.md +40 -0
  266. package/dist/templates/workspace-core/.agents/skills/security/SKILL.md +31 -0
  267. package/dist/templates/workspace-core/.agents/skills/sharing/SKILL.md +4 -0
  268. package/docs/content/actions.mdx +47 -4
  269. package/docs/content/native-chat-ui.mdx +7 -0
  270. package/docs/content/organizations-teams-permissions.mdx +109 -3
  271. package/docs/content/template-design-collaboration-and-full-apps.mdx +15 -0
  272. package/docs/content/toolkit-org-team.mdx +72 -12
  273. package/package.json +1 -1
  274. package/src/a2a/artifact-response.ts +36 -29
  275. package/src/action.ts +83 -2
  276. package/src/chat-threads/store.ts +48 -43
  277. package/src/cli/skills-content/design-visual-edit-skill.ts +46 -3
  278. package/src/cli/template-sync.ts +96 -0
  279. package/src/client/AgentPanel.tsx +26 -6
  280. package/src/client/AssistantChat.tsx +63 -7
  281. package/src/client/DefaultSpinner.tsx +29 -0
  282. package/src/client/org/TeamPage.tsx +161 -6
  283. package/src/client/org/hooks.ts +67 -0
  284. package/src/client/org/index.ts +9 -0
  285. package/src/client/transcription/use-live-transcription.ts +62 -10
  286. package/src/db/client.ts +42 -3
  287. package/src/db/ensure-additive-columns.ts +60 -33
  288. package/src/deploy/build.ts +31 -2
  289. package/src/mcp-client/routes.ts +10 -1
  290. package/src/org/app-roles-handlers.ts +152 -0
  291. package/src/org/app-roles.ts +355 -0
  292. package/src/org/index.ts +27 -1
  293. package/src/org/migrations.ts +22 -0
  294. package/src/org/plugin.ts +27 -0
  295. package/src/org/schema.ts +15 -0
  296. package/src/scripts/docs/search.ts +17 -0
  297. package/src/scripts/docs/source-search.ts +10 -0
  298. package/src/server/agent-chat/script-entries.ts +3 -0
  299. package/src/server/agent-chat-plugin.ts +53 -52
  300. package/src/server/builder-design-systems.ts +1 -1
  301. package/src/server/core-routes-plugin.ts +6 -1
  302. package/src/server/framework-request-handler.ts +44 -6
  303. package/src/templates/chat/.agents/skills/actions/SKILL.md +32 -0
  304. package/src/templates/chat/.agents/skills/adding-a-feature/SKILL.md +7 -0
  305. package/src/templates/chat/.agents/skills/security/SKILL.md +31 -0
  306. package/src/templates/chat/.agents/skills/sharing/SKILL.md +4 -0
  307. package/src/templates/chat/_gitignore +2 -0
  308. package/src/templates/default/.agents/skills/actions/SKILL.md +32 -0
  309. package/src/templates/default/.agents/skills/adding-a-feature/SKILL.md +7 -0
  310. package/src/templates/default/.agents/skills/security/SKILL.md +31 -0
  311. package/src/templates/headless/.agents/skills/actions/SKILL.md +32 -0
  312. package/src/templates/workspace-core/.agents/skills/actions/SKILL.md +32 -0
  313. package/src/templates/workspace-core/.agents/skills/adding-a-feature/SKILL.md +7 -0
  314. package/src/templates/workspace-core/.agents/skills/authentication/SKILL.md +40 -0
  315. package/src/templates/workspace-core/.agents/skills/security/SKILL.md +31 -0
  316. package/src/templates/workspace-core/.agents/skills/sharing/SKILL.md +4 -0
  317. package/corpus/core/src/templates/chat/.agents/skills/actions/SKILL.md +0 -530
  318. package/corpus/core/src/templates/chat/.agents/skills/adding-a-feature/SKILL.md +0 -191
  319. package/corpus/core/src/templates/chat/.agents/skills/agent-native-docs/SKILL.md +0 -115
  320. package/corpus/core/src/templates/chat/.agents/skills/agent-native-toolkit/SKILL.md +0 -177
  321. package/corpus/core/src/templates/chat/.agents/skills/capture-learnings/SKILL.md +0 -89
  322. package/corpus/core/src/templates/chat/.agents/skills/create-skill/SKILL.md +0 -221
  323. package/corpus/core/src/templates/chat/.agents/skills/customizing-agent-native/SKILL.md +0 -220
  324. package/corpus/core/src/templates/chat/.agents/skills/delegate-to-agent/SKILL.md +0 -263
  325. package/corpus/core/src/templates/chat/.agents/skills/feature-flags/SKILL.md +0 -169
  326. package/corpus/core/src/templates/chat/.agents/skills/frontend-design/SKILL.md +0 -174
  327. package/corpus/core/src/templates/chat/.agents/skills/real-time-sync/SKILL.md +0 -232
  328. package/corpus/core/src/templates/chat/.agents/skills/security/SKILL.md +0 -282
  329. package/corpus/core/src/templates/chat/.agents/skills/self-modifying-code/SKILL.md +0 -119
  330. package/corpus/core/src/templates/chat/.agents/skills/shadcn-ui/SKILL.md +0 -123
  331. package/corpus/core/src/templates/chat/.agents/skills/upgrade-agent-native/SKILL.md +0 -122
  332. package/corpus/core/src/templates/chat/.env.example +0 -5
  333. package/corpus/core/src/templates/chat/.ignore +0 -0
  334. package/corpus/core/src/templates/chat/.oxfmtrc.json +0 -8
  335. package/corpus/core/src/templates/chat/AGENTS.md +0 -77
  336. package/corpus/core/src/templates/chat/CHANGELOG.md +0 -10
  337. package/corpus/core/src/templates/chat/DEVELOPING.md +0 -185
  338. package/corpus/core/src/templates/chat/README.md +0 -32
  339. package/corpus/core/src/templates/chat/_gitignore +0 -44
  340. package/corpus/core/src/templates/chat/actions/hello.ts +0 -13
  341. package/corpus/core/src/templates/chat/actions/navigate.ts +0 -41
  342. package/corpus/core/src/templates/chat/actions/run.ts +0 -2
  343. package/corpus/core/src/templates/chat/actions/view-screen.ts +0 -31
  344. package/corpus/core/src/templates/chat/app/components/layout/Header.tsx +0 -60
  345. package/corpus/core/src/templates/chat/app/components/layout/Layout.tsx +0 -188
  346. package/corpus/core/src/templates/chat/app/components/layout/Sidebar.tsx +0 -505
  347. package/corpus/core/src/templates/chat/app/components/ui/button.tsx +0 -1
  348. package/corpus/core/src/templates/chat/app/components/ui/card.tsx +0 -1
  349. package/corpus/core/src/templates/chat/app/components/ui/dropdown-menu.tsx +0 -1
  350. package/corpus/core/src/templates/chat/app/components/ui/input.tsx +0 -1
  351. package/corpus/core/src/templates/chat/app/components/ui/label.tsx +0 -1
  352. package/corpus/core/src/templates/chat/app/components/ui/sheet.tsx +0 -1
  353. package/corpus/core/src/templates/chat/app/components/ui/toolkit-provider.tsx +0 -17
  354. package/corpus/core/src/templates/chat/app/components/ui/tooltip.tsx +0 -1
  355. package/corpus/core/src/templates/chat/app/design-system.ts +0 -3
  356. package/corpus/core/src/templates/chat/app/entry.client.tsx +0 -22
  357. package/corpus/core/src/templates/chat/app/entry.server.tsx +0 -10
  358. package/corpus/core/src/templates/chat/app/global.css +0 -93
  359. package/corpus/core/src/templates/chat/app/hooks/use-navigation-state.ts +0 -93
  360. package/corpus/core/src/templates/chat/app/i18n/ar-SA.ts +0 -68
  361. package/corpus/core/src/templates/chat/app/i18n/de-DE.ts +0 -71
  362. package/corpus/core/src/templates/chat/app/i18n/en-US.ts +0 -70
  363. package/corpus/core/src/templates/chat/app/i18n/es-ES.ts +0 -71
  364. package/corpus/core/src/templates/chat/app/i18n/fr-FR.ts +0 -71
  365. package/corpus/core/src/templates/chat/app/i18n/hi-IN.ts +0 -69
  366. package/corpus/core/src/templates/chat/app/i18n/index.ts +0 -34
  367. package/corpus/core/src/templates/chat/app/i18n/ja-JP.ts +0 -70
  368. package/corpus/core/src/templates/chat/app/i18n/ko-KR.ts +0 -70
  369. package/corpus/core/src/templates/chat/app/i18n/pt-BR.ts +0 -71
  370. package/corpus/core/src/templates/chat/app/i18n/zh-CN.ts +0 -66
  371. package/corpus/core/src/templates/chat/app/i18n/zh-TW.ts +0 -66
  372. package/corpus/core/src/templates/chat/app/i18n-data.ts +0 -556
  373. package/corpus/core/src/templates/chat/app/lib/agent-page.tsx +0 -49
  374. package/corpus/core/src/templates/chat/app/lib/app-config.ts +0 -11
  375. package/corpus/core/src/templates/chat/app/lib/tab-id.ts +0 -1
  376. package/corpus/core/src/templates/chat/app/lib/utils.ts +0 -1
  377. package/corpus/core/src/templates/chat/app/root.tsx +0 -173
  378. package/corpus/core/src/templates/chat/app/routes/_index.tsx +0 -94
  379. package/corpus/core/src/templates/chat/app/routes/agent.tsx +0 -24
  380. package/corpus/core/src/templates/chat/app/routes/chat.$threadId.tsx +0 -1
  381. package/corpus/core/src/templates/chat/app/routes/database.tsx +0 -17
  382. package/corpus/core/src/templates/chat/app/routes/extensions.$id.$slug.tsx +0 -2
  383. package/corpus/core/src/templates/chat/app/routes/extensions.$id.tsx +0 -11
  384. package/corpus/core/src/templates/chat/app/routes/extensions._index.tsx +0 -11
  385. package/corpus/core/src/templates/chat/app/routes/extensions.tsx +0 -5
  386. package/corpus/core/src/templates/chat/app/routes/observability.tsx +0 -19
  387. package/corpus/core/src/templates/chat/app/routes/settings.tsx +0 -89
  388. package/corpus/core/src/templates/chat/app/routes/team.tsx +0 -11
  389. package/corpus/core/src/templates/chat/app/routes.ts +0 -4
  390. package/corpus/core/src/templates/chat/app/vite-env.d.ts +0 -6
  391. package/corpus/core/src/templates/chat/changelog/2026-06-24-a-new-settings-page-gives-quick-access-to-language-workspace.md +0 -6
  392. package/corpus/core/src/templates/chat/changelog/2026-06-24-added-a-language-picker-and-localized-app-chrome-for-support.md +0 -6
  393. package/corpus/core/src/templates/chat/changelog/2026-06-27-traditional-chinese-copy-uses-taiwan-terminology.md +0 -6
  394. package/corpus/core/src/templates/chat/changelog/2026-06-28-left-sidebar-collapse-motion-and-footer-chrome-are-quieter.md +0 -6
  395. package/corpus/core/src/templates/chat/changelog/2026-06-29-chat-layouts-adapt-when-the-agent-sidebar-is-open.md +0 -6
  396. package/corpus/core/src/templates/chat/changelog/2026-07-08-settings-are-cleaner-and-searchable.md +0 -5
  397. package/corpus/core/src/templates/chat/changelog/2026-07-10-chat-now-makes-ai-connection-setup-clear-without-shifting-th.md +0 -6
  398. package/corpus/core/src/templates/chat/changelog/2026-07-13-a-full-agent-page-now-brings-context-files-connections-jobs-.md +0 -6
  399. package/corpus/core/src/templates/chat/changelog/2026-07-14-chat-opens-reliably-on-hosted-deployments-instead-of-failing.md +0 -6
  400. package/corpus/core/src/templates/chat/changelog/2026-07-14-fixed-chat-template-startup-with-older-core-versions.md +0 -6
  401. package/corpus/core/src/templates/chat/changelog/2026-07-15-chat-navigation-focuses-on-chat-and-agent.md +0 -6
  402. package/corpus/core/src/templates/chat/changelog/2026-07-17-the-agent-chat-sidebar-stays-closed-until-you-open-it-or-sta.md +0 -6
  403. package/corpus/core/src/templates/chat/changelog/2026-07-22-compact-sidebar-footer.md +0 -6
  404. package/corpus/core/src/templates/chat/changelog/2026-07-22-full-page-chat-keeps-the-active-conversation-when-moving-to-.md +0 -6
  405. package/corpus/core/src/templates/chat/changelog/2026-07-22-manage-agent-navigation-now-uses-the-connected-nodes-icon.md +0 -6
  406. package/corpus/core/src/templates/chat/changelog/2026-07-22-recent-chats-are-easier-to-scan-and-expand.md +0 -6
  407. package/corpus/core/src/templates/chat/changelog/2026-07-23-full-page-chat-is-better-centered-with-quieter-chat-history-.md +0 -6
  408. package/corpus/core/src/templates/chat/changelog/2026-07-24-borderless-secondary-surfaces.md +0 -6
  409. package/corpus/core/src/templates/chat/changelog/2026-07-24-sidebar-footer-controls-follow-a-consistent-order.md +0 -6
  410. package/corpus/core/src/templates/chat/changelog/2026-07-25-settings-navigation-now-keeps-manage-agent-as-a-dedicated-li.md +0 -6
  411. package/corpus/core/src/templates/chat/components.json +0 -20
  412. package/corpus/core/src/templates/chat/learnings.defaults.md +0 -5
  413. package/corpus/core/src/templates/chat/netlify.toml +0 -11
  414. package/corpus/core/src/templates/chat/package.json +0 -92
  415. package/corpus/core/src/templates/chat/public/agent-native-icon-dark.svg +0 -10
  416. package/corpus/core/src/templates/chat/public/agent-native-icon-light.svg +0 -10
  417. package/corpus/core/src/templates/chat/public/agent-native-logo-dark.svg +0 -21
  418. package/corpus/core/src/templates/chat/public/agent-native-logo-light.svg +0 -21
  419. package/corpus/core/src/templates/chat/public/favicon.svg +0 -1
  420. package/corpus/core/src/templates/chat/public/icon-180.svg +0 -1
  421. package/corpus/core/src/templates/chat/public/icon-192.svg +0 -1
  422. package/corpus/core/src/templates/chat/public/icon-512.svg +0 -1
  423. package/corpus/core/src/templates/chat/public/manifest.json +0 -21
  424. package/corpus/core/src/templates/chat/react-router.config.ts +0 -7
  425. package/corpus/core/src/templates/chat/server/middleware/auth.ts +0 -15
  426. package/corpus/core/src/templates/chat/server/plugins/agent-chat.ts +0 -21
  427. package/corpus/core/src/templates/chat/server/plugins/auth.ts +0 -17
  428. package/corpus/core/src/templates/chat/server/routes/[...page].get.ts +0 -5
  429. package/corpus/core/src/templates/chat/ssr-entry.ts +0 -15
  430. package/corpus/core/src/templates/chat/tsconfig.json +0 -21
  431. package/corpus/core/src/templates/chat/vite.config.ts +0 -19
@@ -305,6 +305,38 @@ export default defineAction({
305
305
 
306
306
  On success the validated value is returned, so coercion/defaults on `outputSchema` apply. Omit `outputSchema` and behavior is byte-for-byte unchanged (no wrapping).
307
307
 
308
+ ### Authorization (`authorize`)
309
+
310
+ `authorize` decides whether the caller may run the action at all. It wraps
311
+ `run`, so it holds at **all six dispatch sites** — agent tool, HTTP, frontend
312
+ hook, MCP, A2A, CLI — unlike `needsApproval`, which is honoured only in the
313
+ agent loop. Use `authorize` for "not everyone may do this"; use `needsApproval`
314
+ to ask a human to bless one call a permitted caller is already allowed to make.
315
+
316
+ ```ts
317
+ import { coachAccess } from "../lib/access.js"; // defineAppRoles(...)
318
+
319
+ export default defineAction({
320
+ description: "Archive a client roster.",
321
+ schema: z.object({ id: z.string() }),
322
+ authorize: coachAccess.requireAny("coach-admin"),
323
+ run: async (args) => {
324
+ /* ... */
325
+ },
326
+ });
327
+ ```
328
+
329
+ The wrappers compose as `validate input -> authorize -> run -> validate output
330
+ -> audit`: the gate sits inside input validation, so a guard reading `args` gets
331
+ the parsed, coerced value, and auditing is outermost, so denials are recorded.
332
+
333
+ A guard that throws denies with its own message; returning `false` denies
334
+ generically; anything else (including `undefined`) allows. A guarded action
335
+ needs a user identity, so an unattended CLI/cron caller with no user email is
336
+ denied. `authorize` gates the operation; `accessFilter` / `assertAccess` still
337
+ scope which rows a permitted caller may touch. See the `authentication` skill
338
+ for `defineAppRoles` and the `sharing` skill for row scoping.
339
+
308
340
  ### Human-in-the-Loop Approval (`needsApproval`)
309
341
 
310
342
  For high-consequence, outward-facing, hard-to-undo actions (sending an email, charging a card, deleting an account), set `needsApproval` so the agent **cannot** run the action without a human approving the specific call:
@@ -305,6 +305,38 @@ export default defineAction({
305
305
 
306
306
  On success the validated value is returned, so coercion/defaults on `outputSchema` apply. Omit `outputSchema` and behavior is byte-for-byte unchanged (no wrapping).
307
307
 
308
+ ### Authorization (`authorize`)
309
+
310
+ `authorize` decides whether the caller may run the action at all. It wraps
311
+ `run`, so it holds at **all six dispatch sites** — agent tool, HTTP, frontend
312
+ hook, MCP, A2A, CLI — unlike `needsApproval`, which is honoured only in the
313
+ agent loop. Use `authorize` for "not everyone may do this"; use `needsApproval`
314
+ to ask a human to bless one call a permitted caller is already allowed to make.
315
+
316
+ ```ts
317
+ import { coachAccess } from "../lib/access.js"; // defineAppRoles(...)
318
+
319
+ export default defineAction({
320
+ description: "Archive a client roster.",
321
+ schema: z.object({ id: z.string() }),
322
+ authorize: coachAccess.requireAny("coach-admin"),
323
+ run: async (args) => {
324
+ /* ... */
325
+ },
326
+ });
327
+ ```
328
+
329
+ The wrappers compose as `validate input -> authorize -> run -> validate output
330
+ -> audit`: the gate sits inside input validation, so a guard reading `args` gets
331
+ the parsed, coerced value, and auditing is outermost, so denials are recorded.
332
+
333
+ A guard that throws denies with its own message; returning `false` denies
334
+ generically; anything else (including `undefined`) allows. A guarded action
335
+ needs a user identity, so an unattended CLI/cron caller with no user email is
336
+ denied. `authorize` gates the operation; `accessFilter` / `assertAccess` still
337
+ scope which rows a permitted caller may touch. See the `authentication` skill
338
+ for `defineAppRoles` and the `sharing` skill for row scoping.
339
+
308
340
  ### Human-in-the-Loop Approval (`needsApproval`)
309
341
 
310
342
  For high-consequence, outward-facing, hard-to-undo actions (sending an email, charging a card, deleting an account), set `needsApproval` so the agent **cannot** run the action without a human approving the specific call:
@@ -179,8 +179,15 @@ If the feature stores **user-authored resources** (documents, dashboards, forms,
179
179
 
180
180
  TL;DR: spread `ownableColumns()` into the resource table, pair it with `createSharesTable(...)`, call `registerShareableResource(...)`, wrap list/read queries with `accessFilter`, guard writes with `assertAccess`, and drop `<ShareButton>` in the resource header. The `share-resource`, `unshare-resource`, `list-resource-shares`, and `set-resource-visibility` actions are auto-mounted framework-wide.
181
181
 
182
+ ## One more area — who inside the app may do it
183
+
184
+ If the feature is one **only some teammates should be able to perform inside this app** (an admin-only import, a settings reset), that is a per-app role — not a new organization, and not a share grant. See the `authentication` skill.
185
+
186
+ TL;DR: declare the vocabulary once with `defineAppRoles({ appId, roles, defaultRole })`, guard the action with `authorize: appAccess.requireAny("...")`, and render the picker with `<TeamPage appRoles={descriptor} />`. `defaultRole` is display only — it never satisfies a guard — and `authorize` gates the operation while `accessFilter` / `assertAccess` still scope the rows.
187
+
182
188
  ## Related Skills
183
189
 
190
+ - **authentication** — Per-app member roles (`defineAppRoles`) when only some teammates may use a feature
184
191
  - **sharing** — How to make a new resource ownable (private by default, share with users/orgs/public)
185
192
  - **context-awareness** — How to expose UI state to the agent (area 4 in detail)
186
193
  - **actions** — How to create actions with `defineAction` and the `http` option (area 2 in detail)
@@ -71,6 +71,46 @@ The auto-create path skips users with pending invites or a matching
71
71
  `AUTO_CREATE_DEFAULT_ORG=0` only for deployments that intentionally want manual
72
72
  org creation.
73
73
 
74
+ ### App-Specific Roles
75
+
76
+ When a request needs "only some teammates may do this **inside this app**", the
77
+ answer is per-app roles — **not** a second organization. App roles are an
78
+ overlay on the one org membership, never a second roster. Three role systems
79
+ coexist and never imply one another: the org role (`org_members.role`) says what
80
+ a person may do to the *team*, an app role says what they may do inside *one
81
+ app*, and a share role (`sharing` skill) says what they may do to *one row*. An
82
+ app `admin` is not an org admin, and org handlers never read app roles.
83
+
84
+ Declare the vocabulary once on the server and guard actions with it:
85
+
86
+ ```ts
87
+ import { defineAppRoles } from "@agent-native/core/org-team";
88
+
89
+ export const coachAccess = defineAppRoles({
90
+ appId: "coach",
91
+ roles: ["member", "coach-admin"] as const,
92
+ defaultRole: "member",
93
+ });
94
+
95
+ // in an action
96
+ authorize: coachAccess.requireAny("coach-admin"),
97
+ ```
98
+
99
+ Roles are an unordered set, not a ladder — declaration order carries no meaning,
100
+ and every guard names its accepted roles explicitly. `defaultRole` is **display
101
+ only**: `requireAny` matches an explicit assignment row and nothing else, so
102
+ "nobody assigned this person" never reads as "granted", and widening the default
103
+ cannot silently widen a guard. Org membership is a precondition, resolved in the
104
+ same statement as the assignment, so a leftover assignment for a removed member
105
+ can never authorize. Only org owners/admins may assign app roles; render the
106
+ picker with `<TeamPage appRoles={descriptor} />`.
107
+
108
+ `requireAny` validates at definition time — no roles, or a role outside the
109
+ declared vocabulary, throws when the module loads rather than surfacing as an
110
+ unexplained 403 later. When calling `resolve`/`assertAny` directly, note that an
111
+ explicit `userEmail: null` / `orgId: null` means "this run has no identity" and
112
+ does **not** fall back to the ambient request context; only `undefined` does.
113
+
74
114
  ### Stop And Confirm Before Creating Or Switching Organizations
75
115
 
76
116
  Vault credentials are scoped per organization and are **not** shared between
@@ -159,6 +159,35 @@ whole site. Data scoping lives in actions and API routes; the client gates
159
159
  private UI after the shell loads. See the `authentication` skill and
160
160
  `guard:ssr-cache-shell` / `ssr-handler.spec.ts`.
161
161
 
162
+ **Authorization beyond "is there a session" — `authorize`.** The auth guard only
163
+ proves *someone* is signed in. To restrict an operation to some teammates, set
164
+ `authorize` on the `defineAction`. It wraps `run`, so it applies at every
165
+ dispatch site (agent tool, HTTP, frontend, MCP, A2A, CLI) — unlike
166
+ `needsApproval`, which is honoured only in the agent loop.
167
+
168
+ ```ts
169
+ import { coachAccess } from "../lib/access.js"; // defineAppRoles(...)
170
+
171
+ export default defineAction({
172
+ description: "Archive a client roster.",
173
+ schema: z.object({ id: z.string() }),
174
+ authorize: coachAccess.requireAny("coach-admin"),
175
+ run: async (args) => {
176
+ /* ... */
177
+ },
178
+ });
179
+ ```
180
+
181
+ A guard that throws denies with its own message; returning `false` denies
182
+ generically; anything else (including `undefined`) allows. Guarded actions need
183
+ a user identity — an unattended CLI/cron caller with no user email is denied.
184
+
185
+ `authorize` is **not** a substitute for `accessFilter` / `assertAccess`. It
186
+ decides whether this caller may perform the operation at all; `accessFilter` /
187
+ `assertAccess` scope which rows a permitted caller may see or touch. A
188
+ restricted write action needs both. See the `authentication` skill for
189
+ `defineAppRoles` and the `actions` skill for the full surface.
190
+
162
191
  ## Human-in-the-Loop Approval for High-Consequence Actions
163
192
 
164
193
  For a small set of outward-facing, hard-to-undo operations — sending an email, charging a card, deleting an account, posting publicly — auth and access control are necessary but not sufficient: you also do not want the **agent** to perform them autonomously. Set `needsApproval` on the `defineAction` so the agent cannot run the action without a human approving the specific call.
@@ -274,6 +303,8 @@ Run `pnpm action db-check-scoping` to verify. Use `--require-org` for multi-org
274
303
  - [ ] New env vars in `.env` only, not committed
275
304
  - [ ] New user-data tables have `owner_email` column
276
305
  - [ ] Custom routes call `getSession` and reject unauthenticated requests
306
+ - [ ] Actions only some teammates may run set `authorize` (in addition to any
307
+ `accessFilter` / `assertAccess` row scoping)
277
308
 
278
309
  ## Related Skills
279
310
 
@@ -34,6 +34,8 @@ Visibility is coarse. Explicit share grants are fine-grained (per user or per or
34
34
  - **`editor`** — read + write.
35
35
  - **`admin`** — read + write + manage shares. Does NOT replace the single `owner_email` on the resource.
36
36
 
37
+ There are three role systems and they never imply one another. A share role answers "what may this person do to **one row**". An org role (`org_members.role`) answers "what may this person do to the **team**". An app role (`defineAppRoles`, see the `authentication` skill) answers "what may this person do inside **one app**". A share `admin` is not an app admin and neither is an org admin.
38
+
37
39
  ### Anonymous public URLs stay separate
38
40
 
39
41
  Form "publish" slugs, booking-link slugs, any feature that exposes a URL to unauthenticated users — these are a different axis and are NOT controlled by the sharing system. Keep them alongside it.
@@ -137,6 +139,8 @@ export default defineAction({
137
139
 
138
140
  For delete actions use `"admin"` (or fold in `"owner"` to require the real owner).
139
141
 
142
+ `authorize` is a different axis, not an alternative: it gates whether the caller may run the operation at all, while `assertAccess` scopes which row they may touch. A write action restricted to some teammates needs both — `authorize: appAccess.requireAny(...)` on the action, `assertAccess` inside `run`.
143
+
140
144
  ## Create actions must set owner
141
145
 
142
146
  When inserting a new row, fill `ownerEmail` and `orgId` from the request context:
@@ -94,7 +94,8 @@ For App Operations](/docs/server#actions-first).
94
94
 
95
95
  On this page: [Start with one action](#hello-action), [Defining an action](#defining),
96
96
  [Run context](#run-context), [Access control](#access-control),
97
- [Human-in-the-loop approval](#needs-approval), [Audit logging](#audit),
97
+ [Authorization](#authorize), [Human-in-the-loop approval](#needs-approval),
98
+ [Audit logging](#audit),
98
99
  [Calling from the UI](#ui), [Native chat UI](#native-chat-ui),
99
100
  [Calling from the CLI](#cli), [A2A](#a2a), [MCP](#mcp),
100
101
  [Standard actions](#standard-actions), and [Feature flags](#feature-flags).
@@ -258,7 +259,7 @@ POST by default; `http: { method: "GET" }` makes it a GET. The React hooks and `
258
259
  - **`http: { method: "GET" | "POST" | "PUT" | "DELETE" }`** — default `POST`. `GET` actions are auto-marked `readOnly` so successful calls don't trigger a UI poll-refresh.
259
260
  - **`http: { path: "..." }`** — override the mounted URL under `/_agent-native/actions/`. Defaults to the filename. **Path overrides change the URL only for direct HTTP callers** — `useActionQuery`, `useActionMutation`, and `callAction` always call `/_agent-native/actions/<name>` regardless of this override, so overriding the path makes those hooks 404. Use path overrides only for external HTTP callers. Note also that `:param` route segments in the override path are **not** parsed into `run()` args — only query-string params and JSON body fields are.
260
261
  - **`http: false`** — disable the HTTP endpoint entirely. Agent + CLI only.
261
- - **`readOnly: true`** — explicitly skip the poll-refresh even for POST actions that don't mutate.
262
+ - **`readOnly: true`** — explicitly skip the poll-refresh even for POST actions that don't mutate. It is **not** access control: it does not restrict who may call the action, and it does not affect `useActionQuery`, `useActionMutation`, or any client hook. Its only effects are suppressing the post-call refresh event and opting the action out of write-auditing. To hide an action from the model use `agentTool: false`; to gate callers use the auth/access options above.
262
263
  - **`parallelSafe: true`** — allow a mutating action to run concurrently with other same-turn tool calls. Only set this when the action is internally concurrency-safe and order-independent; mutating actions serialize by default.
263
264
 
264
265
  ### Keep the action surface small {#small-surface}
@@ -274,7 +275,7 @@ A repo-level advisory helper, `node scripts/audit-template-actions.mjs [template
274
275
 
275
276
  ### Exposure flags {#exposure-flags}
276
277
 
277
- Four flags control _who_ can invoke an action. All default to the permissive value, so you only set one to tighten a specific surface. This table is the glanceable summary; the subsections add the one detail each needs.
278
+ Five flags control _who_ can invoke an action. All default to the permissive value, so you only set one to tighten a specific surface. This table is the glanceable summary; the subsections add the one detail each needs.
278
279
 
279
280
  | Flag | Default | Restrictive value → who can still call | Typical use |
280
281
  | --------------- | ------------- | --------------------------------------------------------------------------- | --------------------------------------------------------------- |
@@ -282,8 +283,9 @@ Four flags control _who_ can invoke an action. All default to the permissive val
282
283
  | `toolCallable` | `true` | `false` → everything **except** the sandboxed extension iframe bridge (403) | Auth-adjacent ops (delete account, change org membership/roles) |
283
284
  | `publicAgent` | off (private) | `{ expose: true }` → adds the action to **public** MCP/A2A/OpenAPI surfaces | Safe read/ingest tools reachable without authentication |
284
285
  | `needsApproval` | `false` | `true` → the agent **pauses**; a human must approve the specific call | Consequential side effects (send email, charge a card, delete) |
286
+ | `authorize` | none | a guard function → only callers it accepts, on **every** surface | Operations restricted to a role (per-app RBAC, admin-only ops) |
285
287
 
286
- These are independent: `agentTool` controls the model's view, `toolCallable` controls only the extension iframe, `publicAgent` adds an opt-in public surface (public web routes never imply public tool exposure), and `needsApproval` gates execution after the call is made — see [Human-in-the-loop approval](#needs-approval) below.
288
+ These are independent: `agentTool` controls the model's view, `toolCallable` controls only the extension iframe, `publicAgent` adds an opt-in public surface (public web routes never imply public tool exposure), `needsApproval` gates execution after the call is made — see [Human-in-the-loop approval](#needs-approval) below — and `authorize` decides whether this caller may run the action at all, on every dispatch path, before `run` is entered — see [Authorization](#authorize).
287
289
 
288
290
  #### `agentTool` — hide from the model {#agent-tool}
289
291
 
@@ -403,6 +405,47 @@ export default defineAction({
403
405
 
404
406
  For list and read actions, use `accessFilter` to scope the query to the current user and org. For actions that update or delete a specific row, use `assertAccess` to confirm the caller is allowed before writing. See [Security](/docs/security#access-guards) and [Sharing](/docs/sharing) for the full helper API.
405
407
 
408
+ ### Authorization {#authorize}
409
+
410
+ `accessFilter` / `assertAccess` scope _which rows_ a permitted caller may touch. `authorize` answers the question before that one: **may this caller run this operation at all?** Give it a guard function and it runs before `run()` on every caller — agent tool, HTTP, frontend, MCP, A2A, and CLI:
411
+
412
+ ```ts
413
+ import { coachAccess } from "../server/lib/access.js";
414
+
415
+ export default defineAction({
416
+ description: "Archive a training plan.",
417
+ schema: z.object({ id: z.string() }),
418
+ authorize: coachAccess.requireAny("coach-admin"),
419
+ run: async ({ id }) => {
420
+ /* ... */
421
+ },
422
+ });
423
+ ```
424
+
425
+ The guard wraps `run` itself rather than hanging off the action entry, because `run` is the one thing all six dispatch sites go through — there is no caller that can reach the body without passing the check. A guard that throws denies with its own message; one that returns `false` denies with a generic 403; anything else, including `undefined`, allows. Because the gate needs a caller identity, an unattended CLI or cron invocation with no user email is denied rather than waved through.
426
+
427
+ The wrappers compose in this order:
428
+
429
+ ```text
430
+ validate input -> authorize -> run -> validate output -> audit
431
+ ```
432
+
433
+ Authorization sits _inside_ input validation, so a guard that inspects `args` is handed the parsed, coerced value its type promises rather than whatever shape the caller sent. Auditing is outermost, so a denial is still recorded.
434
+
435
+ `requireAny` fails at definition time, not at request time: calling it with no roles, or with a role outside the declared vocabulary, throws when the module loads. `authorize: coachAccess.requireAny()` is a dropped argument, and it should break where the mistake is rather than surface later as an unexplained 403.
436
+
437
+ The three mechanisms are not interchangeable:
438
+
439
+ | Mechanism | Question it answers | Applies to |
440
+ | ----------------------------- | -------------------------------------------------- | --------------------------- |
441
+ | `authorize` | May this caller perform the operation at all? | All six dispatch sites |
442
+ | `needsApproval` | Should a human bless this specific permitted call? | The agent loop only |
443
+ | `accessFilter`/`assertAccess` | Which rows may this permitted caller see or write? | Inside `run`, per query/row |
444
+
445
+ A restricted write action typically needs both `authorize` and `assertAccess`: the first keeps non-coaches out of the operation, the second keeps a coach out of another org's plan. `needsApproval` is a separate axis again — it never restricts _who_ may call, only whether the agent may proceed unattended.
446
+
447
+ `coachAccess` above comes from `defineAppRoles`, the per-app role overlay on org membership. See [Organizations, Teams & Permissions → App roles](/docs/organizations-teams-permissions#app-roles-per-app-rbac) for the role model and its guarantees.
448
+
406
449
  ### Human-in-the-loop approval {#needs-approval}
407
450
 
408
451
  A handful of actions are too consequential to let the agent run autonomously — sending an email, charging a card, deleting an account. Set `needsApproval: true` (or a predicate `(args, ctx) => boolean | Promise<boolean>`) on `defineAction` and the loop pauses before `run()`, requiring a human to approve that specific call. The default is **off**, and almost every action should stay that way.
@@ -246,6 +246,13 @@ export default defineAction({
246
246
  Use this for first-party app UI. Keep cross-host iframe UI in `mcpApp`, and keep
247
247
  arbitrary query execution behind typed read actions rather than raw SQL in chat.
248
248
 
249
+ Size renderers in absolute units, not percentages. The transcript grows to fit
250
+ its messages, so a renderer's container has no definite height to resolve a
251
+ percentage against — `height: 40%` on a chart bar collapses to zero rather than
252
+ erroring, which reads as a renderer that failed to draw. Give charts and other
253
+ height-driven visuals a pixel (or `rem`) basis; widths are fine as percentages
254
+ because the transcript column does have a definite width.
255
+
249
256
  ## BYO agent runtimes {#byo-agent-runtimes}
250
257
 
251
258
  `AgentChatRuntime` is the bring-your-own-agent contract for the chat shell, and
@@ -41,8 +41,8 @@ server-side action or access guard must enforce the rule.
41
41
  ## Organizations and teams
42
42
 
43
43
  Every scaffold includes the framework's own `org/` module. It is backed by
44
- `organizations`, `org_members`, and `org_invitations`; it is not Better Auth's
45
- organization plugin. The built-in flow supports:
44
+ `organizations`, `org_members`, `org_invitations`, and `app_member_roles`; it is
45
+ not Better Auth's organization plugin. The built-in flow supports:
46
46
 
47
47
  - Creating an organization. The creator becomes the `owner`.
48
48
  - Inviting people as `member` or `admin` and accepting invitations.
@@ -64,6 +64,8 @@ routes are:
64
64
  | `GET /_agent-native/org/members` | List members in the active organization |
65
65
  | `DELETE /_agent-native/org/members/:email` | Remove a member |
66
66
  | `PUT /_agent-native/org/members/:email/role` | Change a member's role |
67
+ | `GET /_agent-native/org/app-roles?appId=X` | An app's role vocabulary plus its assignments in the active org |
68
+ | `PUT /_agent-native/org/app-roles/:email` | Assign or clear one member's app role (owner/admin only) |
67
69
  | `GET /_agent-native/org/invitations` | List pending invites |
68
70
  | `POST /_agent-native/org/invitations` | Invite one or more people |
69
71
  | `POST /_agent-native/org/invitations/:id/accept` | Accept an invitation |
@@ -91,7 +93,8 @@ export function AppShell() {
91
93
  export function TeamSettings() {
92
94
  return (
93
95
  <RequireActiveOrg>
94
- <TeamPage />
96
+ {/* `appRoles` is optional — see App roles below */}
97
+ <TeamPage appRoles={coachRoles} />
95
98
  </RequireActiveOrg>
96
99
  );
97
100
  }
@@ -162,11 +165,114 @@ The same helpers are available from
162
165
  client checks as progressive disclosure only; repeat the authorization check
163
166
  in the server action or route that changes org state.
164
167
 
168
+ ## App roles (per-app RBAC)
169
+
170
+ App roles answer: **what may this person do inside _one app_?**
171
+
172
+ An organization role is a statement about the team, and a resource role is a
173
+ statement about a row. Neither can express "Dana runs the coaching program, but
174
+ is an ordinary member everywhere else." App roles are that overlay: an
175
+ app-defined vocabulary layered on the org roster, stored in `app_member_roles`
176
+ and edited from the same team surface. They are not a second roster — do not
177
+ create another organization to get app-specific permissions.
178
+
179
+ Declare the vocabulary once in app source, then guard actions with an explicit
180
+ list of accepted roles:
181
+
182
+ ```ts
183
+ // server/lib/access.ts
184
+ import { defineAppRoles } from "@agent-native/core/org-team";
185
+
186
+ export const coachAccess = defineAppRoles({
187
+ appId: "coach",
188
+ roles: ["member", "coach-admin"] as const,
189
+ defaultRole: "member", // display only — never satisfies a guard
190
+ label: "Coach role", // column header in TeamPage
191
+ roleLabels: { "coach-admin": "Coach admin" },
192
+ });
193
+ ```
194
+
195
+ ```ts
196
+ // actions/archive-plan.ts
197
+ export default defineAction({
198
+ description: "Archive a training plan.",
199
+ schema: z.object({ id: z.string() }),
200
+ authorize: coachAccess.requireAny("coach-admin"),
201
+ run: async ({ id }) => {
202
+ /* ... */
203
+ },
204
+ });
205
+ ```
206
+
207
+ Against `requireAny("coach-admin")`, the caller resolves to exactly one of:
208
+
209
+ | Caller | `resolve()` status | Passes the guard |
210
+ | ------------------------------------------ | ------------------ | ----------------------------- |
211
+ | Org member assigned `coach-admin` | `assigned` | Yes |
212
+ | Org member assigned `member` | `assigned` | No — not in the accepted list |
213
+ | Org member with no assignment row | `unassigned` | No, even with a `defaultRole` |
214
+ | Signed-in user who is not in this org | `not-a-member` | No |
215
+ | Request with no active organization | `no-org` | No |
216
+ | Unattended caller with no user (CLI, cron) | `no-identity` | No |
217
+
218
+ The caveats that make this safe to build on:
219
+
220
+ - **Roles are an unordered set, not a ladder.** Declaration order carries no
221
+ meaning; `["ae", "se", "csm"]` are classifications, and ranking them would
222
+ silently grant the last one everything the first one has. Authorization is
223
+ always an explicit accepted-role list, never "at least".
224
+ - **`defaultRole` is display only.** `requireAny` matches an explicit
225
+ assignment row and nothing else. If the default satisfied a guard, "nobody
226
+ has assigned this person" and "this person was granted the role" would be the
227
+ same answer, and later widening the default would silently widen every guard
228
+ that names it.
229
+ - **Org membership is a precondition.** Membership and assignment resolve in
230
+ one SQL statement, so an assignment left behind by a removed member can never
231
+ authorize.
232
+ - **A failed lookup throws.** It is not one of the deny statuses above: a
233
+ database error is not an answer, and reporting it as a denial would look
234
+ exactly like a legitimate one.
235
+ - **`requireAny` validates at definition time.** Calling it with no roles, or
236
+ with a role outside the declared vocabulary, throws when the module loads —
237
+ a dropped argument breaks where the mistake is instead of surfacing later as
238
+ an unexplained 403 in production.
239
+ - **An explicit `null` caller is not "unspecified".** `resolve({ userEmail:
240
+ null })` means "this run has no user" and does not fall back to the ambient
241
+ request context; only `undefined` does. Collapsing the two would let a system
242
+ or cron caller that deliberately declared no identity inherit whichever
243
+ request happens to be on the stack and authorize as that person.
244
+ - **`appId` comes from trusted server config, never from the request.** The
245
+ REST layer resolves descriptors out of the `defineAppRoles` registry and 404s
246
+ an app id the server never declared.
247
+ - **An app admin is not an org admin.** Only org owners and admins may change
248
+ app-role assignments, and nothing in the org handlers reads an app role. The
249
+ implication does not run in either direction.
250
+
251
+ In the browser, `<TeamPage appRoles={coachRoles} />` adds a role column and
252
+ picker next to the org role. The argument is the descriptor — the serializable
253
+ half of the declaration, free of database imports — so hoist that object literal
254
+ into a shared module as `coachRoles`, hand it to `defineAppRoles` on the server,
255
+ and pass the same object to `TeamPage`. Passing `coachAccess` itself would drag
256
+ the database into the browser bundle. To read the current user's own role:
257
+
258
+ ```tsx
259
+ import { useAppRole } from "@agent-native/core/client/org-team";
260
+
261
+ const { role } = useAppRole("coach");
262
+ ```
263
+
264
+ `useAppRoles`, `useAppRole`, and `useSetAppMemberRole` are progressive
265
+ disclosure only. Every guarded operation re-resolves the role on the server, so
266
+ a client that shows the wrong affordance still cannot perform the operation.
267
+ See [Actions → Authorization](/docs/actions#authorize) for how `authorize`
268
+ differs from `needsApproval` and from row-level access guards.
269
+
165
270
  ## Resource permissions (sharing RBAC)
166
271
 
167
272
  Organization roles and resource roles are different systems:
168
273
 
169
274
  - **Organization role** controls team administration.
275
+ - **App role** controls what a member may do inside one app.
170
276
  - **Resource role** controls access to one document, dashboard, or other
171
277
  shareable row.
172
278
 
@@ -11,6 +11,21 @@ Once a prototype is in good shape, this page covers what happens next: pulling i
11
11
 
12
12
  Design isn't only for prototypes generated from a prompt — a coding agent can install `/visual-edit` to bring a real, already-running local app into Design as its own screens. Each requested path or URL becomes its own screen on the canvas, and a numbered flow (an onboarding step 1, 2, 3) stays as separate ordered screens instead of collapsing into one. The entry route renders before sign-in, and a shared design link works read-only without an account — but saving the layout, generating new screens, or sharing still requires signing in first.
13
13
 
14
+ ### Keep the canvas beside your chat
15
+
16
+ When your coding app has an inline browser, ask `/visual-edit` to open the returned Design URL there. In Codex Desktop, that means the built-in Browser; in Claude Code Desktop's Code tab, it means the Browser pane. Both can keep the canvas inside the coding app beside the conversation. In VS Code, the Agent Native extension opens the same Design URL in its side-panel webview. Browser panes can be disabled or unavailable in CLI, remote, or restricted sessions, so `/visual-edit` falls back to an **Open design** link instead of claiming the canvas opened.
17
+
18
+ Once Design is open, choose **Show/Hide UI** from the `Cmd+K` menu or press `Cmd+Shift+\` on Apple devices / `Ctrl+Shift+\` elsewhere to toggle all editing chrome so only the canvas remains. The same action is available by right-clicking empty canvas space.
19
+
20
+ These are especially useful canvas sets:
21
+
22
+ - **A multi-step flow:** `/visual-edit localhost:5173 — cart, shipping, payment, confirmation; open it beside this chat`
23
+ - **Several pages:** `/visual-edit localhost:5173 — home, pricing, docs, and settings`
24
+ - **One page at several sizes:** `/visual-edit localhost:5173/dashboard — desktop, tablet, and mobile side by side`
25
+ - **Several states of one page:** `/visual-edit localhost:5173/inbox — empty, selected, and compose-open states`
26
+
27
+ The agent keeps named steps in order and places responsive variants in aligned columns, so the canvas reads like a flow or comparison board rather than a pile of screenshots. Name the routes and sizes you care about; requesting every discovered route at every viewport can create a noisy canvas.
28
+
14
29
  <Diagram id="doc-block-design8" title="Three source modes" summary={"A design's source is inline, localhost, or fusion — the mode decides where an edit actually lands."}>
15
30
 
16
31
  ```html
@@ -21,17 +21,21 @@ connections, service tokens, and app switching.
21
21
 
22
22
  ## Pieces {#pieces}
23
23
 
24
- | Piece | Purpose |
25
- | --------------------- | ----------------------------------------------------------------------------------------------- |
26
- | `<TeamPage>` | Standard team management page for members, invites, roles, and organization preferences. |
27
- | `<OrgSwitcher>` | Current organization picker for sidebars and headers. |
28
- | `<InvitationBanner>` | One-click invite and domain-match join prompts. |
29
- | `<RequireActiveOrg>` | Guard for pages that need an active organization before rendering app data. |
30
- | `useOrgRole()` | Shared role booleans for member, invite, settings, and domain controls. |
31
- | Organization handlers | Create, rename, switch, invite, accept, remove, and update roles/domains. |
32
- | Roles | Owner, admin, and member gates for sharing, settings, service tokens, and provider connections. |
33
- | Allowed domains | Automatic join and domain-scoped access policy. |
34
- | App links | Workspace app-link parsing and visible app-switcher helpers. |
24
+ | Piece | Purpose |
25
+ | ----------------------- | ----------------------------------------------------------------------------------------------- |
26
+ | `<TeamPage>` | Standard team management page for members, invites, roles, and organization preferences. |
27
+ | `<OrgSwitcher>` | Current organization picker for sidebars and headers. |
28
+ | `<InvitationBanner>` | One-click invite and domain-match join prompts. |
29
+ | `<RequireActiveOrg>` | Guard for pages that need an active organization before rendering app data. |
30
+ | `useOrgRole()` | Shared role booleans for member, invite, settings, and domain controls. |
31
+ | `appRoles` prop | Adds a per-app role column and picker to `<TeamPage>` from a `defineAppRoles` descriptor. |
32
+ | `useAppRoles()` | An app's role vocabulary, its assignments in the active org, and whether the viewer may edit. |
33
+ | `useAppRole()` | The current user's role in one app, or `null` when unassigned. |
34
+ | `useSetAppMemberRole()` | Assign or clear one member's app role. Org owner/admin only, enforced server-side. |
35
+ | Organization handlers | Create, rename, switch, invite, accept, remove, and update roles/domains. |
36
+ | Roles | Owner, admin, and member gates for sharing, settings, service tokens, and provider connections. |
37
+ | Allowed domains | Automatic join and domain-scoped access policy. |
38
+ | App links | Workspace app-link parsing and visible app-switcher helpers. |
35
39
 
36
40
  ## API {#api}
37
41
 
@@ -66,12 +70,68 @@ export function AdminOnlyControl() {
66
70
 
67
71
  Server code imports the same role helpers from `@agent-native/core/org-team`.
68
72
  The route plugin mounts `/_agent-native/org/*` for org creation, switching,
69
- invites, domains, member roles, and A2A secret sync.
73
+ invites, domains, member roles, app roles, and A2A secret sync.
74
+
75
+ ### Per-app roles {#app-roles}
76
+
77
+ When an app needs its own permission vocabulary on top of team membership,
78
+ declare it with `defineAppRoles` and pass the descriptor to `TeamPage`. The
79
+ descriptor is the serializable half of the declaration — no database imports —
80
+ so the same object can be handed to `defineAppRoles` on the server and to the
81
+ component in the browser bundle:
82
+
83
+ ```tsx
84
+ import {
85
+ RequireActiveOrg,
86
+ TeamPage,
87
+ useAppRole,
88
+ useAppRoles,
89
+ useSetAppMemberRole,
90
+ } from "@agent-native/core/client/org-team";
91
+ import { coachRoles } from "../shared/coach-roles";
92
+
93
+ export function SettingsTeamTab() {
94
+ return (
95
+ <RequireActiveOrg>
96
+ <TeamPage appRoles={coachRoles} />
97
+ </RequireActiveOrg>
98
+ );
99
+ }
100
+
101
+ export function CoachOnlyControl() {
102
+ const { role } = useAppRole("coach");
103
+ return role === "coach-admin" ? <button type="button">Archive</button> : null;
104
+ }
105
+
106
+ export function RoleAdmin() {
107
+ const { data } = useAppRoles("coach");
108
+ const setRole = useSetAppMemberRole("coach");
109
+ if (!data?.canManage) return null;
110
+ return (
111
+ <button
112
+ type="button"
113
+ onClick={() => setRole.mutate({ email: "dana@acme.com", role: null })}
114
+ >
115
+ Clear role
116
+ </button>
117
+ );
118
+ }
119
+ ```
120
+
121
+ `role`, `myRole`, and `canManage` are progressive disclosure only. The server
122
+ re-resolves the caller's app role on every guarded operation, and assignment
123
+ edits require the org `owner`/`admin` role regardless of what the client
124
+ believes. See
125
+ [Organizations, Teams & Permissions → App roles](/docs/organizations-teams-permissions#app-roles-per-app-rbac)
126
+ for the role model and [Actions → Authorization](/docs/actions#authorize) for
127
+ the server-side `authorize` guard.
70
128
 
71
129
  ## UX Standard {#ux-standard}
72
130
 
73
131
  - Users can see which organization they are in before creating or sharing data.
74
132
  - Invites and roles live in the team settings surface, not per-resource dialogs.
133
+ - App-specific roles appear as another column on that same team surface, never
134
+ as a separate permissions page or a second organization.
75
135
  - Org domain changes are owner-only and explain who can auto-join.
76
136
  - App switching lists workspace/default app links. Active-org continuity comes
77
137
  from the target app sharing the same auth and organization state.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agent-native/core",
3
- "version": "0.127.1",
3
+ "version": "0.128.0",
4
4
  "description": "Framework for agent-native application development — where AI agents and UI share SQL state, actions, and context",
5
5
  "homepage": "https://github.com/BuilderIO/agent-native#readme",
6
6
  "bugs": {