@agent-native/core 0.127.3 → 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 (410) hide show
  1. package/corpus/README.md +2 -2
  2. package/corpus/core/CHANGELOG.md +80 -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/client/AgentPanel.tsx +26 -6
  15. package/corpus/core/src/client/AssistantChat.tsx +63 -7
  16. package/corpus/core/src/client/DefaultSpinner.tsx +29 -0
  17. package/corpus/core/src/client/org/TeamPage.tsx +161 -6
  18. package/corpus/core/src/client/org/hooks.ts +67 -0
  19. package/corpus/core/src/client/org/index.ts +9 -0
  20. package/corpus/core/src/client/transcription/use-live-transcription.ts +62 -10
  21. package/corpus/core/src/db/client.ts +42 -3
  22. package/corpus/core/src/db/ensure-additive-columns.ts +60 -33
  23. package/corpus/core/src/deploy/build.ts +31 -2
  24. package/corpus/core/src/mcp-client/routes.ts +10 -1
  25. package/corpus/core/src/org/app-roles-handlers.ts +152 -0
  26. package/corpus/core/src/org/app-roles.ts +355 -0
  27. package/corpus/core/src/org/index.ts +27 -1
  28. package/corpus/core/src/org/migrations.ts +22 -0
  29. package/corpus/core/src/org/plugin.ts +27 -0
  30. package/corpus/core/src/org/schema.ts +15 -0
  31. package/corpus/core/src/scripts/docs/search.ts +17 -0
  32. package/corpus/core/src/scripts/docs/source-search.ts +10 -0
  33. package/corpus/core/src/server/agent-chat/script-entries.ts +3 -0
  34. package/corpus/core/src/server/agent-chat-plugin.ts +53 -52
  35. package/corpus/core/src/server/core-routes-plugin.ts +6 -1
  36. package/corpus/core/src/server/framework-request-handler.ts +44 -6
  37. package/corpus/core/src/templates/default/.agents/skills/actions/SKILL.md +32 -0
  38. package/corpus/core/src/templates/default/.agents/skills/adding-a-feature/SKILL.md +7 -0
  39. package/corpus/core/src/templates/default/.agents/skills/security/SKILL.md +31 -0
  40. package/corpus/core/src/templates/headless/.agents/skills/actions/SKILL.md +32 -0
  41. package/corpus/core/src/templates/workspace-core/.agents/skills/actions/SKILL.md +32 -0
  42. package/corpus/core/src/templates/workspace-core/.agents/skills/adding-a-feature/SKILL.md +7 -0
  43. package/corpus/core/src/templates/workspace-core/.agents/skills/authentication/SKILL.md +40 -0
  44. package/corpus/core/src/templates/workspace-core/.agents/skills/security/SKILL.md +31 -0
  45. package/corpus/core/src/templates/workspace-core/.agents/skills/sharing/SKILL.md +4 -0
  46. package/corpus/templates/analytics/.agents/skills/actions/SKILL.md +32 -0
  47. package/corpus/templates/analytics/.agents/skills/security/SKILL.md +31 -0
  48. package/corpus/templates/analytics/.agents/skills/sharing/SKILL.md +4 -0
  49. package/corpus/templates/analytics/actions/data-source-status.ts +21 -12
  50. package/corpus/templates/analytics/app/global.css +7 -7
  51. package/corpus/templates/analytics/app/i18n-data.ts +30 -0
  52. package/corpus/templates/analytics/app/lib/data-source-status.ts +2 -1
  53. package/corpus/templates/analytics/app/pages/DataSources.tsx +54 -10
  54. package/corpus/templates/analytics/changelog/2026-07-28-analytics-pages-load-reliably-with-large-dashboard-workspaces.md +6 -0
  55. package/corpus/templates/analytics/changelog/2026-07-28-dashboard-loading-shimmer-now-flows-smoothly-in-one-directi.md +6 -0
  56. package/corpus/templates/analytics/server/lib/first-party-dashboard-repair.ts +5 -4
  57. package/corpus/templates/analytics/server/plugins/agent-chat.ts +54 -42
  58. package/corpus/templates/analytics/server/plugins/db.ts +1 -18
  59. package/corpus/templates/assets/.agents/skills/actions/SKILL.md +32 -0
  60. package/corpus/templates/assets/.agents/skills/security/SKILL.md +31 -0
  61. package/corpus/templates/assets/.agents/skills/sharing/SKILL.md +4 -0
  62. package/corpus/templates/brain/.agents/skills/actions/SKILL.md +32 -0
  63. package/corpus/templates/brain/.agents/skills/adding-a-feature/SKILL.md +7 -0
  64. package/corpus/templates/brain/.agents/skills/security/SKILL.md +31 -0
  65. package/corpus/templates/brain/.agents/skills/sharing/SKILL.md +4 -0
  66. package/corpus/templates/calendar/.agents/skills/actions/SKILL.md +32 -0
  67. package/corpus/templates/calendar/.agents/skills/security/SKILL.md +31 -0
  68. package/corpus/templates/calendar/.agents/skills/sharing/SKILL.md +4 -0
  69. package/corpus/templates/chat/.agents/skills/actions/SKILL.md +32 -0
  70. package/corpus/templates/chat/.agents/skills/adding-a-feature/SKILL.md +7 -0
  71. package/corpus/templates/chat/.agents/skills/security/SKILL.md +31 -0
  72. package/corpus/templates/chat/.agents/skills/sharing/SKILL.md +4 -0
  73. package/corpus/templates/clips/.agents/skills/actions/SKILL.md +32 -0
  74. package/corpus/templates/clips/.agents/skills/security/SKILL.md +31 -0
  75. package/corpus/templates/clips/actions/request-transcript.ts +77 -11
  76. package/corpus/templates/clips/actions/save-browser-transcript.ts +28 -7
  77. package/corpus/templates/clips/app/routes/record.tsx +11 -3
  78. package/corpus/templates/clips/changelog/2026-07-28-browser-recordings-no-longer-save-a-truncated-transcript-as-.md +6 -0
  79. package/corpus/templates/clips/changelog/2026-07-28-browser-recordings-no-longer-stop-transcribing-partway-throu.md +6 -0
  80. package/corpus/templates/clips/changelog/2026-07-28-desktop-full-screen-clips-now-get-an-instant-local-transcrip.md +6 -0
  81. package/corpus/templates/clips/changelog/2026-07-28-long-transcriptions-no-longer-show-a-false-transcription-sto.md +6 -0
  82. package/corpus/templates/clips/changelog/2026-07-28-restarting-for-an-update-now-installs-the-newest-release-ins.md +6 -0
  83. package/corpus/templates/clips/changelog/2026-07-28-the-meeting-recording-pill-now-anchors-to-the-right-edge-of-.md +6 -0
  84. package/corpus/templates/clips/desktop/src/lib/audio-meter.ts +31 -2
  85. package/corpus/templates/clips/desktop/src/lib/recorder.ts +114 -13
  86. package/corpus/templates/clips/desktop/src/lib/updater.ts +12 -4
  87. package/corpus/templates/clips/desktop/src/overlays/live-audio-bars.tsx +40 -15
  88. package/corpus/templates/clips/desktop/src/styles.css +10 -7
  89. package/corpus/templates/clips/desktop/src-tauri/src/recording_indicator.rs +21 -14
  90. package/corpus/templates/clips/shared/transcript-status.ts +10 -0
  91. package/corpus/templates/content/.agents/skills/actions/SKILL.md +32 -0
  92. package/corpus/templates/content/.agents/skills/security/SKILL.md +31 -0
  93. package/corpus/templates/content/.agents/skills/sharing/SKILL.md +4 -0
  94. package/corpus/templates/crm/.agents/skills/sharing/SKILL.md +4 -0
  95. package/corpus/templates/design/.agents/skills/actions/SKILL.md +32 -0
  96. package/corpus/templates/design/.agents/skills/security/SKILL.md +31 -0
  97. package/corpus/templates/design/.agents/skills/sharing/SKILL.md +4 -0
  98. package/corpus/templates/design/.agents/skills/visual-edit/SKILL.md +46 -3
  99. package/corpus/templates/design/.generated/bridge/editor-chrome.generated.ts +7 -5
  100. package/corpus/templates/design/app/components/design/CanvasContextMenu.tsx +2 -2
  101. package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +7 -4
  102. package/corpus/templates/design/app/components/design/keyboard-shortcuts.ts +1 -1
  103. package/corpus/templates/design/app/hooks/useDesignHotkeys.ts +10 -4
  104. package/corpus/templates/design/app/lib/design-ui-events.ts +5 -0
  105. package/corpus/templates/design/app/root.tsx +18 -1
  106. package/corpus/templates/design/changelog/2026-07-28-show-or-hide-design-editing-chrome-with-cmd-on-apple-devices.md +6 -0
  107. package/corpus/templates/dispatch/.agents/skills/actions/SKILL.md +32 -0
  108. package/corpus/templates/dispatch/.agents/skills/security/SKILL.md +31 -0
  109. package/corpus/templates/dispatch/.agents/skills/sharing/SKILL.md +4 -0
  110. package/corpus/templates/forms/.agents/skills/actions/SKILL.md +32 -0
  111. package/corpus/templates/forms/.agents/skills/security/SKILL.md +31 -0
  112. package/corpus/templates/forms/.agents/skills/sharing/SKILL.md +4 -0
  113. package/corpus/templates/macros/.agents/skills/security/SKILL.md +31 -0
  114. package/corpus/templates/macros/.agents/skills/sharing/SKILL.md +4 -0
  115. package/corpus/templates/mail/.agents/skills/actions/SKILL.md +32 -0
  116. package/corpus/templates/mail/.agents/skills/security/SKILL.md +31 -0
  117. package/corpus/templates/mail/.agents/skills/sharing/SKILL.md +4 -0
  118. package/corpus/templates/plan/.agents/skills/actions/SKILL.md +32 -0
  119. package/corpus/templates/plan/.agents/skills/adding-a-feature/SKILL.md +7 -0
  120. package/corpus/templates/plan/.agents/skills/security/SKILL.md +31 -0
  121. package/corpus/templates/plan/.agents/skills/sharing/SKILL.md +4 -0
  122. package/corpus/templates/slides/.agents/skills/actions/SKILL.md +32 -0
  123. package/corpus/templates/slides/.agents/skills/security/SKILL.md +31 -0
  124. package/corpus/templates/slides/.agents/skills/sharing/SKILL.md +4 -0
  125. package/corpus/templates/tasks/.agents/skills/actions/SKILL.md +32 -0
  126. package/corpus/templates/tasks/.agents/skills/adding-a-feature/SKILL.md +7 -0
  127. package/corpus/templates/tasks/.agents/skills/security/SKILL.md +31 -0
  128. package/corpus/templates/tasks/.agents/skills/sharing/SKILL.md +4 -0
  129. package/dist/a2a/artifact-response.d.ts.map +1 -1
  130. package/dist/a2a/artifact-response.js +30 -29
  131. package/dist/a2a/artifact-response.js.map +1 -1
  132. package/dist/action.d.ts +36 -0
  133. package/dist/action.d.ts.map +1 -1
  134. package/dist/action.js +37 -2
  135. package/dist/action.js.map +1 -1
  136. package/dist/chat-threads/store.d.ts +12 -0
  137. package/dist/chat-threads/store.d.ts.map +1 -1
  138. package/dist/chat-threads/store.js +48 -42
  139. package/dist/chat-threads/store.js.map +1 -1
  140. package/dist/cli/skills-content/design-visual-edit-skill.d.ts +1 -1
  141. package/dist/cli/skills-content/design-visual-edit-skill.d.ts.map +1 -1
  142. package/dist/cli/skills-content/design-visual-edit-skill.js +46 -3
  143. package/dist/cli/skills-content/design-visual-edit-skill.js.map +1 -1
  144. package/dist/client/AgentPanel.d.ts +3 -1
  145. package/dist/client/AgentPanel.d.ts.map +1 -1
  146. package/dist/client/AgentPanel.js +11 -9
  147. package/dist/client/AgentPanel.js.map +1 -1
  148. package/dist/client/AssistantChat.d.ts.map +1 -1
  149. package/dist/client/AssistantChat.js +57 -6
  150. package/dist/client/AssistantChat.js.map +1 -1
  151. package/dist/client/DefaultSpinner.d.ts +7 -0
  152. package/dist/client/DefaultSpinner.d.ts.map +1 -1
  153. package/dist/client/DefaultSpinner.js +25 -1
  154. package/dist/client/DefaultSpinner.js.map +1 -1
  155. package/dist/client/org/TeamPage.d.ts +13 -1
  156. package/dist/client/org/TeamPage.d.ts.map +1 -1
  157. package/dist/client/org/TeamPage.js +41 -11
  158. package/dist/client/org/TeamPage.js.map +1 -1
  159. package/dist/client/org/hooks.d.ts +37 -0
  160. package/dist/client/org/hooks.d.ts.map +1 -1
  161. package/dist/client/org/hooks.js +37 -0
  162. package/dist/client/org/hooks.js.map +1 -1
  163. package/dist/client/org/index.d.ts +3 -2
  164. package/dist/client/org/index.d.ts.map +1 -1
  165. package/dist/client/org/index.js +1 -1
  166. package/dist/client/org/index.js.map +1 -1
  167. package/dist/client/transcription/use-live-transcription.d.ts +8 -0
  168. package/dist/client/transcription/use-live-transcription.d.ts.map +1 -1
  169. package/dist/client/transcription/use-live-transcription.js +38 -11
  170. package/dist/client/transcription/use-live-transcription.js.map +1 -1
  171. package/dist/collab/routes.d.ts +2 -2
  172. package/dist/db/client.d.ts +12 -0
  173. package/dist/db/client.d.ts.map +1 -1
  174. package/dist/db/client.js +40 -3
  175. package/dist/db/client.js.map +1 -1
  176. package/dist/db/ensure-additive-columns.d.ts.map +1 -1
  177. package/dist/db/ensure-additive-columns.js +54 -32
  178. package/dist/db/ensure-additive-columns.js.map +1 -1
  179. package/dist/deploy/build.d.ts +1 -0
  180. package/dist/deploy/build.d.ts.map +1 -1
  181. package/dist/deploy/build.js +23 -2
  182. package/dist/deploy/build.js.map +1 -1
  183. package/dist/file-upload/actions/upload-image.d.ts +1 -1
  184. package/dist/mcp-client/routes.d.ts +3 -1
  185. package/dist/mcp-client/routes.d.ts.map +1 -1
  186. package/dist/mcp-client/routes.js +8 -2
  187. package/dist/mcp-client/routes.js.map +1 -1
  188. package/dist/notifications/routes.d.ts +1 -1
  189. package/dist/org/app-roles-handlers.d.ts +27 -0
  190. package/dist/org/app-roles-handlers.d.ts.map +1 -0
  191. package/dist/org/app-roles-handlers.js +125 -0
  192. package/dist/org/app-roles-handlers.js.map +1 -0
  193. package/dist/org/app-roles.d.ts +136 -0
  194. package/dist/org/app-roles.d.ts.map +1 -0
  195. package/dist/org/app-roles.js +216 -0
  196. package/dist/org/app-roles.js.map +1 -0
  197. package/dist/org/index.d.ts +4 -1
  198. package/dist/org/index.d.ts.map +1 -1
  199. package/dist/org/index.js +3 -1
  200. package/dist/org/index.js.map +1 -1
  201. package/dist/org/migrations.d.ts.map +1 -1
  202. package/dist/org/migrations.js +22 -0
  203. package/dist/org/migrations.js.map +1 -1
  204. package/dist/org/plugin.d.ts +2 -0
  205. package/dist/org/plugin.d.ts.map +1 -1
  206. package/dist/org/plugin.js +20 -0
  207. package/dist/org/plugin.js.map +1 -1
  208. package/dist/org/schema.d.ts +143 -0
  209. package/dist/org/schema.d.ts.map +1 -1
  210. package/dist/org/schema.js +14 -0
  211. package/dist/org/schema.js.map +1 -1
  212. package/dist/progress/routes.d.ts +1 -1
  213. package/dist/provider-api/actions/custom-provider-registration.d.ts +4 -4
  214. package/dist/provider-api/actions/provider-api.d.ts +12 -12
  215. package/dist/scripts/docs/search.d.ts.map +1 -1
  216. package/dist/scripts/docs/search.js +15 -0
  217. package/dist/scripts/docs/search.js.map +1 -1
  218. package/dist/scripts/docs/source-search.d.ts +7 -0
  219. package/dist/scripts/docs/source-search.d.ts.map +1 -1
  220. package/dist/scripts/docs/source-search.js +9 -0
  221. package/dist/scripts/docs/source-search.js.map +1 -1
  222. package/dist/secrets/routes.d.ts +9 -9
  223. package/dist/server/agent-chat/script-entries.d.ts.map +1 -1
  224. package/dist/server/agent-chat/script-entries.js +3 -0
  225. package/dist/server/agent-chat/script-entries.js.map +1 -1
  226. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  227. package/dist/server/agent-chat-plugin.js +46 -48
  228. package/dist/server/agent-chat-plugin.js.map +1 -1
  229. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  230. package/dist/server/core-routes-plugin.d.ts.map +1 -1
  231. package/dist/server/core-routes-plugin.js +6 -1
  232. package/dist/server/core-routes-plugin.js.map +1 -1
  233. package/dist/server/framework-request-handler.d.ts.map +1 -1
  234. package/dist/server/framework-request-handler.js +42 -6
  235. package/dist/server/framework-request-handler.js.map +1 -1
  236. package/dist/server/realtime-token.d.ts +1 -1
  237. package/dist/templates/chat/.agents/skills/actions/SKILL.md +32 -0
  238. package/dist/templates/chat/.agents/skills/adding-a-feature/SKILL.md +7 -0
  239. package/dist/templates/chat/.agents/skills/security/SKILL.md +31 -0
  240. package/dist/templates/chat/.agents/skills/sharing/SKILL.md +4 -0
  241. package/dist/templates/default/.agents/skills/actions/SKILL.md +32 -0
  242. package/dist/templates/default/.agents/skills/adding-a-feature/SKILL.md +7 -0
  243. package/dist/templates/default/.agents/skills/security/SKILL.md +31 -0
  244. package/dist/templates/headless/.agents/skills/actions/SKILL.md +32 -0
  245. package/dist/templates/workspace-core/.agents/skills/actions/SKILL.md +32 -0
  246. package/dist/templates/workspace-core/.agents/skills/adding-a-feature/SKILL.md +7 -0
  247. package/dist/templates/workspace-core/.agents/skills/authentication/SKILL.md +40 -0
  248. package/dist/templates/workspace-core/.agents/skills/security/SKILL.md +31 -0
  249. package/dist/templates/workspace-core/.agents/skills/sharing/SKILL.md +4 -0
  250. package/docs/content/actions.mdx +47 -4
  251. package/docs/content/native-chat-ui.mdx +7 -0
  252. package/docs/content/organizations-teams-permissions.mdx +109 -3
  253. package/docs/content/template-design-collaboration-and-full-apps.mdx +15 -0
  254. package/docs/content/toolkit-org-team.mdx +72 -12
  255. package/package.json +1 -1
  256. package/src/a2a/artifact-response.ts +36 -29
  257. package/src/action.ts +83 -2
  258. package/src/chat-threads/store.ts +48 -43
  259. package/src/cli/skills-content/design-visual-edit-skill.ts +46 -3
  260. package/src/client/AgentPanel.tsx +26 -6
  261. package/src/client/AssistantChat.tsx +63 -7
  262. package/src/client/DefaultSpinner.tsx +29 -0
  263. package/src/client/org/TeamPage.tsx +161 -6
  264. package/src/client/org/hooks.ts +67 -0
  265. package/src/client/org/index.ts +9 -0
  266. package/src/client/transcription/use-live-transcription.ts +62 -10
  267. package/src/db/client.ts +42 -3
  268. package/src/db/ensure-additive-columns.ts +60 -33
  269. package/src/deploy/build.ts +31 -2
  270. package/src/mcp-client/routes.ts +10 -1
  271. package/src/org/app-roles-handlers.ts +152 -0
  272. package/src/org/app-roles.ts +355 -0
  273. package/src/org/index.ts +27 -1
  274. package/src/org/migrations.ts +22 -0
  275. package/src/org/plugin.ts +27 -0
  276. package/src/org/schema.ts +15 -0
  277. package/src/scripts/docs/search.ts +17 -0
  278. package/src/scripts/docs/source-search.ts +10 -0
  279. package/src/server/agent-chat/script-entries.ts +3 -0
  280. package/src/server/agent-chat-plugin.ts +53 -52
  281. package/src/server/core-routes-plugin.ts +6 -1
  282. package/src/server/framework-request-handler.ts +44 -6
  283. package/src/templates/chat/.agents/skills/actions/SKILL.md +32 -0
  284. package/src/templates/chat/.agents/skills/adding-a-feature/SKILL.md +7 -0
  285. package/src/templates/chat/.agents/skills/security/SKILL.md +31 -0
  286. package/src/templates/chat/.agents/skills/sharing/SKILL.md +4 -0
  287. package/src/templates/default/.agents/skills/actions/SKILL.md +32 -0
  288. package/src/templates/default/.agents/skills/adding-a-feature/SKILL.md +7 -0
  289. package/src/templates/default/.agents/skills/security/SKILL.md +31 -0
  290. package/src/templates/headless/.agents/skills/actions/SKILL.md +32 -0
  291. package/src/templates/workspace-core/.agents/skills/actions/SKILL.md +32 -0
  292. package/src/templates/workspace-core/.agents/skills/adding-a-feature/SKILL.md +7 -0
  293. package/src/templates/workspace-core/.agents/skills/authentication/SKILL.md +40 -0
  294. package/src/templates/workspace-core/.agents/skills/security/SKILL.md +31 -0
  295. package/src/templates/workspace-core/.agents/skills/sharing/SKILL.md +4 -0
  296. package/corpus/core/src/templates/chat/.agents/skills/actions/SKILL.md +0 -530
  297. package/corpus/core/src/templates/chat/.agents/skills/adding-a-feature/SKILL.md +0 -191
  298. package/corpus/core/src/templates/chat/.agents/skills/agent-native-docs/SKILL.md +0 -115
  299. package/corpus/core/src/templates/chat/.agents/skills/agent-native-toolkit/SKILL.md +0 -177
  300. package/corpus/core/src/templates/chat/.agents/skills/capture-learnings/SKILL.md +0 -89
  301. package/corpus/core/src/templates/chat/.agents/skills/create-skill/SKILL.md +0 -221
  302. package/corpus/core/src/templates/chat/.agents/skills/customizing-agent-native/SKILL.md +0 -220
  303. package/corpus/core/src/templates/chat/.agents/skills/delegate-to-agent/SKILL.md +0 -263
  304. package/corpus/core/src/templates/chat/.agents/skills/feature-flags/SKILL.md +0 -169
  305. package/corpus/core/src/templates/chat/.agents/skills/frontend-design/SKILL.md +0 -174
  306. package/corpus/core/src/templates/chat/.agents/skills/real-time-sync/SKILL.md +0 -232
  307. package/corpus/core/src/templates/chat/.agents/skills/security/SKILL.md +0 -282
  308. package/corpus/core/src/templates/chat/.agents/skills/self-modifying-code/SKILL.md +0 -119
  309. package/corpus/core/src/templates/chat/.agents/skills/shadcn-ui/SKILL.md +0 -123
  310. package/corpus/core/src/templates/chat/.agents/skills/upgrade-agent-native/SKILL.md +0 -122
  311. package/corpus/core/src/templates/chat/.env.example +0 -5
  312. package/corpus/core/src/templates/chat/.ignore +0 -0
  313. package/corpus/core/src/templates/chat/.oxfmtrc.json +0 -8
  314. package/corpus/core/src/templates/chat/AGENTS.md +0 -77
  315. package/corpus/core/src/templates/chat/CHANGELOG.md +0 -10
  316. package/corpus/core/src/templates/chat/DEVELOPING.md +0 -185
  317. package/corpus/core/src/templates/chat/README.md +0 -32
  318. package/corpus/core/src/templates/chat/_gitignore +0 -46
  319. package/corpus/core/src/templates/chat/actions/hello.ts +0 -13
  320. package/corpus/core/src/templates/chat/actions/navigate.ts +0 -41
  321. package/corpus/core/src/templates/chat/actions/run.ts +0 -2
  322. package/corpus/core/src/templates/chat/actions/view-screen.ts +0 -31
  323. package/corpus/core/src/templates/chat/app/components/layout/Header.tsx +0 -60
  324. package/corpus/core/src/templates/chat/app/components/layout/Layout.tsx +0 -188
  325. package/corpus/core/src/templates/chat/app/components/layout/Sidebar.tsx +0 -505
  326. package/corpus/core/src/templates/chat/app/components/ui/button.tsx +0 -1
  327. package/corpus/core/src/templates/chat/app/components/ui/card.tsx +0 -1
  328. package/corpus/core/src/templates/chat/app/components/ui/dropdown-menu.tsx +0 -1
  329. package/corpus/core/src/templates/chat/app/components/ui/input.tsx +0 -1
  330. package/corpus/core/src/templates/chat/app/components/ui/label.tsx +0 -1
  331. package/corpus/core/src/templates/chat/app/components/ui/sheet.tsx +0 -1
  332. package/corpus/core/src/templates/chat/app/components/ui/toolkit-provider.tsx +0 -17
  333. package/corpus/core/src/templates/chat/app/components/ui/tooltip.tsx +0 -1
  334. package/corpus/core/src/templates/chat/app/design-system.ts +0 -3
  335. package/corpus/core/src/templates/chat/app/entry.client.tsx +0 -22
  336. package/corpus/core/src/templates/chat/app/entry.server.tsx +0 -10
  337. package/corpus/core/src/templates/chat/app/global.css +0 -93
  338. package/corpus/core/src/templates/chat/app/hooks/use-navigation-state.ts +0 -93
  339. package/corpus/core/src/templates/chat/app/i18n/ar-SA.ts +0 -68
  340. package/corpus/core/src/templates/chat/app/i18n/de-DE.ts +0 -71
  341. package/corpus/core/src/templates/chat/app/i18n/en-US.ts +0 -70
  342. package/corpus/core/src/templates/chat/app/i18n/es-ES.ts +0 -71
  343. package/corpus/core/src/templates/chat/app/i18n/fr-FR.ts +0 -71
  344. package/corpus/core/src/templates/chat/app/i18n/hi-IN.ts +0 -69
  345. package/corpus/core/src/templates/chat/app/i18n/index.ts +0 -34
  346. package/corpus/core/src/templates/chat/app/i18n/ja-JP.ts +0 -70
  347. package/corpus/core/src/templates/chat/app/i18n/ko-KR.ts +0 -70
  348. package/corpus/core/src/templates/chat/app/i18n/pt-BR.ts +0 -71
  349. package/corpus/core/src/templates/chat/app/i18n/zh-CN.ts +0 -66
  350. package/corpus/core/src/templates/chat/app/i18n/zh-TW.ts +0 -66
  351. package/corpus/core/src/templates/chat/app/i18n-data.ts +0 -556
  352. package/corpus/core/src/templates/chat/app/lib/agent-page.tsx +0 -49
  353. package/corpus/core/src/templates/chat/app/lib/app-config.ts +0 -11
  354. package/corpus/core/src/templates/chat/app/lib/tab-id.ts +0 -1
  355. package/corpus/core/src/templates/chat/app/lib/utils.ts +0 -1
  356. package/corpus/core/src/templates/chat/app/root.tsx +0 -173
  357. package/corpus/core/src/templates/chat/app/routes/_index.tsx +0 -94
  358. package/corpus/core/src/templates/chat/app/routes/agent.tsx +0 -24
  359. package/corpus/core/src/templates/chat/app/routes/chat.$threadId.tsx +0 -1
  360. package/corpus/core/src/templates/chat/app/routes/database.tsx +0 -17
  361. package/corpus/core/src/templates/chat/app/routes/extensions.$id.$slug.tsx +0 -2
  362. package/corpus/core/src/templates/chat/app/routes/extensions.$id.tsx +0 -11
  363. package/corpus/core/src/templates/chat/app/routes/extensions._index.tsx +0 -11
  364. package/corpus/core/src/templates/chat/app/routes/extensions.tsx +0 -5
  365. package/corpus/core/src/templates/chat/app/routes/observability.tsx +0 -19
  366. package/corpus/core/src/templates/chat/app/routes/settings.tsx +0 -89
  367. package/corpus/core/src/templates/chat/app/routes/team.tsx +0 -11
  368. package/corpus/core/src/templates/chat/app/routes.ts +0 -4
  369. package/corpus/core/src/templates/chat/app/vite-env.d.ts +0 -6
  370. package/corpus/core/src/templates/chat/changelog/2026-06-24-a-new-settings-page-gives-quick-access-to-language-workspace.md +0 -6
  371. package/corpus/core/src/templates/chat/changelog/2026-06-24-added-a-language-picker-and-localized-app-chrome-for-support.md +0 -6
  372. package/corpus/core/src/templates/chat/changelog/2026-06-27-traditional-chinese-copy-uses-taiwan-terminology.md +0 -6
  373. package/corpus/core/src/templates/chat/changelog/2026-06-28-left-sidebar-collapse-motion-and-footer-chrome-are-quieter.md +0 -6
  374. package/corpus/core/src/templates/chat/changelog/2026-06-29-chat-layouts-adapt-when-the-agent-sidebar-is-open.md +0 -6
  375. package/corpus/core/src/templates/chat/changelog/2026-07-08-settings-are-cleaner-and-searchable.md +0 -5
  376. package/corpus/core/src/templates/chat/changelog/2026-07-10-chat-now-makes-ai-connection-setup-clear-without-shifting-th.md +0 -6
  377. package/corpus/core/src/templates/chat/changelog/2026-07-13-a-full-agent-page-now-brings-context-files-connections-jobs-.md +0 -6
  378. package/corpus/core/src/templates/chat/changelog/2026-07-14-chat-opens-reliably-on-hosted-deployments-instead-of-failing.md +0 -6
  379. package/corpus/core/src/templates/chat/changelog/2026-07-14-fixed-chat-template-startup-with-older-core-versions.md +0 -6
  380. package/corpus/core/src/templates/chat/changelog/2026-07-15-chat-navigation-focuses-on-chat-and-agent.md +0 -6
  381. 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
  382. package/corpus/core/src/templates/chat/changelog/2026-07-22-compact-sidebar-footer.md +0 -6
  383. package/corpus/core/src/templates/chat/changelog/2026-07-22-full-page-chat-keeps-the-active-conversation-when-moving-to-.md +0 -6
  384. package/corpus/core/src/templates/chat/changelog/2026-07-22-manage-agent-navigation-now-uses-the-connected-nodes-icon.md +0 -6
  385. package/corpus/core/src/templates/chat/changelog/2026-07-22-recent-chats-are-easier-to-scan-and-expand.md +0 -6
  386. package/corpus/core/src/templates/chat/changelog/2026-07-23-full-page-chat-is-better-centered-with-quieter-chat-history-.md +0 -6
  387. package/corpus/core/src/templates/chat/changelog/2026-07-24-borderless-secondary-surfaces.md +0 -6
  388. package/corpus/core/src/templates/chat/changelog/2026-07-24-sidebar-footer-controls-follow-a-consistent-order.md +0 -6
  389. package/corpus/core/src/templates/chat/changelog/2026-07-25-settings-navigation-now-keeps-manage-agent-as-a-dedicated-li.md +0 -6
  390. package/corpus/core/src/templates/chat/components.json +0 -20
  391. package/corpus/core/src/templates/chat/learnings.defaults.md +0 -5
  392. package/corpus/core/src/templates/chat/netlify.toml +0 -11
  393. package/corpus/core/src/templates/chat/package.json +0 -92
  394. package/corpus/core/src/templates/chat/public/agent-native-icon-dark.svg +0 -10
  395. package/corpus/core/src/templates/chat/public/agent-native-icon-light.svg +0 -10
  396. package/corpus/core/src/templates/chat/public/agent-native-logo-dark.svg +0 -21
  397. package/corpus/core/src/templates/chat/public/agent-native-logo-light.svg +0 -21
  398. package/corpus/core/src/templates/chat/public/favicon.svg +0 -1
  399. package/corpus/core/src/templates/chat/public/icon-180.svg +0 -1
  400. package/corpus/core/src/templates/chat/public/icon-192.svg +0 -1
  401. package/corpus/core/src/templates/chat/public/icon-512.svg +0 -1
  402. package/corpus/core/src/templates/chat/public/manifest.json +0 -21
  403. package/corpus/core/src/templates/chat/react-router.config.ts +0 -7
  404. package/corpus/core/src/templates/chat/server/middleware/auth.ts +0 -15
  405. package/corpus/core/src/templates/chat/server/plugins/agent-chat.ts +0 -21
  406. package/corpus/core/src/templates/chat/server/plugins/auth.ts +0 -17
  407. package/corpus/core/src/templates/chat/server/routes/[...page].get.ts +0 -5
  408. package/corpus/core/src/templates/chat/ssr-entry.ts +0 -15
  409. package/corpus/core/src/templates/chat/tsconfig.json +0 -21
  410. package/corpus/core/src/templates/chat/vite.config.ts +0 -19
@@ -87,14 +87,11 @@ export default defineAction({
87
87
  run: async (args) => {
88
88
  const ctx = tryRequestCredentialContext();
89
89
  if (!ctx) {
90
- return {
91
- error: "missing_api_key",
92
- key: "AUTH",
93
- label: "Authentication",
94
- message: "Sign in to view credential status.",
95
- settingsPath: "/data-sources",
96
- dataSourcesSetupLink: DATA_SOURCES_SETUP_LINK,
97
- };
90
+ // Returning 200 here let callers read "signed out" as an authoritative
91
+ // "nothing is configured".
92
+ throw Object.assign(new Error("Sign in to view credential status."), {
93
+ statusCode: 401,
94
+ });
98
95
  }
99
96
 
100
97
  const { configs, known } = resolveCredentialConfigs(args.key);
@@ -195,12 +192,16 @@ export default defineAction({
195
192
  workspace.connections,
196
193
  workspace.grants,
197
194
  );
195
+ const configured =
196
+ hasRequiredCredentials ||
197
+ workspaceConnection.grantState === "connected";
198
198
  return {
199
199
  provider: provider.provider,
200
200
  label: provider.label,
201
- configured:
202
- hasRequiredCredentials ||
203
- workspaceConnection.grantState === "connected",
201
+ // A failed workspace-connection lookup cannot prove a provider is
202
+ // disconnected — a workspace-held connection lives in exactly the
203
+ // data we could not read. Report null, never false.
204
+ configured: configured ? true : workspace.error ? null : false,
204
205
  configuredKeys: configuredProviderKeys,
205
206
  missingRequiredKeys,
206
207
  optionalKeys,
@@ -231,13 +232,21 @@ export default defineAction({
231
232
  const connectedExternalDataSources = configuredDataSources.filter(
232
233
  (source) => source.provider !== BUILT_IN_FIRST_PARTY_PROVIDER.provider,
233
234
  );
235
+ const hasUnknownProviderStatus = providers.some(
236
+ (provider) => provider.configured === null,
237
+ );
234
238
  return {
235
239
  // Keep a compact, explicit summary first so models do not infer source
236
240
  // availability from the much larger per-credential list below.
237
241
  hasConfiguredDataSources: configuredDataSources.length > 0,
238
242
  configuredDataSourceCount: configuredDataSources.length,
239
243
  configuredDataSources,
240
- hasConnectedExternalDataSources: connectedExternalDataSources.length > 0,
244
+ hasConnectedExternalDataSources:
245
+ connectedExternalDataSources.length > 0
246
+ ? true
247
+ : hasUnknownProviderStatus
248
+ ? null
249
+ : false,
241
250
  connectedExternalDataSourceCount: connectedExternalDataSources.length,
242
251
  dataSourcesSetupLink: DATA_SOURCES_SETUP_LINK,
243
252
  credentials: results,
@@ -148,18 +148,18 @@
148
148
  hsl(var(--foreground) / 0.025) 56%,
149
149
  transparent 72%
150
150
  );
151
- background-size: 220% 100%;
152
- animation: dashboard-panel-skeleton-shimmer 2.4s ease-in-out infinite;
151
+ background-size: 28rem 100%;
152
+ background-repeat: repeat;
153
+ animation: dashboard-panel-skeleton-shimmer 2.6s linear infinite;
153
154
  }
154
155
 
155
156
  @keyframes dashboard-panel-skeleton-shimmer {
156
- 0%,
157
- 100% {
158
- background-position: 120% 0;
157
+ 0% {
158
+ background-position: 0 0;
159
159
  }
160
160
 
161
- 50% {
162
- background-position: -120% 0;
161
+ 100% {
162
+ background-position: 28rem 0;
163
163
  }
164
164
  }
165
165
 
@@ -893,6 +893,9 @@ const enUS = {
893
893
  sharedCredentials: "Shared credentials: {{credentials}}",
894
894
  ready: "Ready",
895
895
  notConfigured: "Not configured",
896
+ statusUnknown: "Couldn't check connection status",
897
+ statusUnknownDescription:
898
+ "The connection status couldn't be read, so this source may already be connected. Reload to check again before adding credentials.",
896
899
  back: "Back",
897
900
  continue: "Continue",
898
901
  saveCredentials: "Save Credentials",
@@ -1356,6 +1359,9 @@ const analyticsSliceTranslations: {
1356
1359
  sharedCredentials: "共享凭证:{{credentials}}",
1357
1360
  ready: "准备好",
1358
1361
  notConfigured: "未配置",
1362
+ statusUnknown: "无法检查连接状态",
1363
+ statusUnknownDescription:
1364
+ "无法读取连接状态,此数据源可能已连接。请重新加载页面确认后再添加凭据。",
1359
1365
  back: "后退",
1360
1366
  continue: "继续",
1361
1367
  saveCredentials: "保存凭证",
@@ -1648,6 +1654,9 @@ const analyticsSliceTranslations: {
1648
1654
  sharedCredentials: "Credenciales compartidas: {{credentials}}",
1649
1655
  ready: "Listo",
1650
1656
  notConfigured: "No configurado",
1657
+ statusUnknown: "No se pudo comprobar el estado de la conexión",
1658
+ statusUnknownDescription:
1659
+ "No se pudo leer el estado de la conexión, así que esta fuente puede estar ya conectada. Vuelve a cargar la página para comprobarlo antes de añadir credenciales.",
1651
1660
  back: "Atrás",
1652
1661
  continue: "Continuar",
1653
1662
  saveCredentials: "Guardar credenciales",
@@ -1957,6 +1966,9 @@ const analyticsSliceTranslations: {
1957
1966
  sharedCredentials: "Identifiants partagés : {{credentials}}",
1958
1967
  ready: "Prêt",
1959
1968
  notConfigured: "Non configuré",
1969
+ statusUnknown: "Impossible de vérifier l'état de la connexion",
1970
+ statusUnknownDescription:
1971
+ "L'état de la connexion n'a pas pu être lu ; cette source est peut-être déjà connectée. Rechargez la page pour vérifier avant d'ajouter des identifiants.",
1960
1972
  back: "Dos",
1961
1973
  continue: "Continuer",
1962
1974
  saveCredentials: "Enregistrer les informations d'identification",
@@ -2264,6 +2276,9 @@ const analyticsSliceTranslations: {
2264
2276
  sharedCredentials: "Gemeinsame Anmeldeinformationen: {{credentials}}",
2265
2277
  ready: "Bereit",
2266
2278
  notConfigured: "Nicht konfiguriert",
2279
+ statusUnknown: "Verbindungsstatus konnte nicht geprüft werden",
2280
+ statusUnknownDescription:
2281
+ "Der Verbindungsstatus konnte nicht gelesen werden, diese Quelle ist möglicherweise bereits verbunden. Lade die Seite neu, um erneut zu prüfen, bevor du Zugangsdaten hinzufügst.",
2267
2282
  back: "Zurück",
2268
2283
  continue: "Weitermachen",
2269
2284
  saveCredentials: "Anmeldeinformationen speichern",
@@ -2568,6 +2583,9 @@ const analyticsSliceTranslations: {
2568
2583
  sharedCredentials: "共有資格情報: {{credentials}}",
2569
2584
  ready: "準備ができて",
2570
2585
  notConfigured: "未設定",
2586
+ statusUnknown: "接続状態を確認できませんでした",
2587
+ statusUnknownDescription:
2588
+ "接続状態を読み取れなかったため、このソースはすでに接続されている可能性があります。認証情報を追加する前に、再読み込みして確認してください。",
2571
2589
  back: "戻る",
2572
2590
  continue: "続く",
2573
2591
  saveCredentials: "認証情報の保存",
@@ -2867,6 +2885,9 @@ const analyticsSliceTranslations: {
2867
2885
  sharedCredentials: "공유 자격 증명: {{credentials}}",
2868
2886
  ready: "준비가 된",
2869
2887
  notConfigured: "구성되지 않음",
2888
+ statusUnknown: "연결 상태를 확인할 수 없습니다",
2889
+ statusUnknownDescription:
2890
+ "연결 상태를 읽을 수 없어 이 소스가 이미 연결되어 있을 수 있습니다. 자격 증명을 추가하기 전에 새로 고쳐 다시 확인하세요.",
2870
2891
  back: "뒤쪽에",
2871
2892
  continue: "계속하다",
2872
2893
  saveCredentials: "자격 증명 저장",
@@ -3163,6 +3184,9 @@ const analyticsSliceTranslations: {
3163
3184
  sharedCredentials: "Credenciais compartilhadas: {{credentials}}",
3164
3185
  ready: "Preparar",
3165
3186
  notConfigured: "Não configurado",
3187
+ statusUnknown: "Não foi possível verificar o status da conexão",
3188
+ statusUnknownDescription:
3189
+ "Não foi possível ler o status da conexão, então esta fonte pode já estar conectada. Recarregue a página para verificar antes de adicionar credenciais.",
3166
3190
  back: "Voltar",
3167
3191
  continue: "Continuar",
3168
3192
  saveCredentials: "Salvar credenciais",
@@ -3464,6 +3488,9 @@ const analyticsSliceTranslations: {
3464
3488
  sharedCredentials: "साझा क्रेडेंशियल: {{credentials}}",
3465
3489
  ready: "तैयार",
3466
3490
  notConfigured: "कॉन्फ़िगर नहीं किया गया",
3491
+ statusUnknown: "कनेक्शन स्थिति जाँची नहीं जा सकी",
3492
+ statusUnknownDescription:
3493
+ "कनेक्शन स्थिति पढ़ी नहीं जा सकी, इसलिए हो सकता है कि यह स्रोत पहले से जुड़ा हो। क्रेडेंशियल जोड़ने से पहले पेज फिर से लोड करके जाँचें।",
3467
3494
  back: "पीछे",
3468
3495
  continue: "जारी रखना",
3469
3496
  saveCredentials: "क्रेडेंशियल सहेजें",
@@ -3756,6 +3783,9 @@ const analyticsSliceTranslations: {
3756
3783
  sharedCredentials: "بيانات الاعتماد المشتركة: {{credentials}}",
3757
3784
  ready: "مستعد",
3758
3785
  notConfigured: "لم يتم تكوينه",
3786
+ statusUnknown: "تعذّر التحقق من حالة الاتصال",
3787
+ statusUnknownDescription:
3788
+ "تعذّرت قراءة حالة الاتصال، لذا قد يكون هذا المصدر متصلاً بالفعل. أعد تحميل الصفحة للتحقق قبل إضافة بيانات الاعتماد.",
3759
3789
  back: "خلف",
3760
3790
  continue: "يكمل",
3761
3791
  saveCredentials: "حفظ بيانات الاعتماد",
@@ -30,7 +30,8 @@ export interface WorkspaceConnectionProviderSummary {
30
30
  export interface DataSourceProviderStatus {
31
31
  provider: string;
32
32
  label: string;
33
- configured: boolean;
33
+ // null when the workspace-connection lookup failed: unreadable, not absent.
34
+ configured: boolean | null;
34
35
  configuredKeys: string[];
35
36
  missingRequiredKeys: string[];
36
37
  optionalKeys: string[];
@@ -1100,6 +1100,7 @@ function DataSourceCard({
1100
1100
  sharedConnectionStatus,
1101
1101
  envStatus,
1102
1102
  isStatusLoading,
1103
+ statusUnknown,
1103
1104
  onSaved,
1104
1105
  }: {
1105
1106
  source: DataSource;
@@ -1108,6 +1109,7 @@ function DataSourceCard({
1108
1109
  sharedConnectionStatus: SharedConnectionStatus | null;
1109
1110
  envStatus: EnvKeyStatus[];
1110
1111
  isStatusLoading: boolean;
1112
+ statusUnknown: boolean;
1111
1113
  onSaved: () => void;
1112
1114
  }) {
1113
1115
  const t = useT();
@@ -1136,6 +1138,9 @@ function DataSourceCard({
1136
1138
  const readyViaWorkspace = sharedConnectionStatus?.kind === "ready";
1137
1139
  const showCredentialSetup =
1138
1140
  !locallyConfigured && (!readyViaWorkspace || showLocalCredentials);
1141
+ // An unreadable status cannot tell this source apart from an unconfigured
1142
+ // one, so the setup walkthrough would be guessing.
1143
+ const showUnknownStatus = statusUnknown && !ready && !showLocalCredentials;
1139
1144
 
1140
1145
  return (
1141
1146
  <Card className="data-source-card bg-card border-border/50">
@@ -1161,6 +1166,11 @@ function DataSourceCard({
1161
1166
  <div className="flex shrink-0 items-center gap-2">
1162
1167
  {isStatusLoading ? (
1163
1168
  <Skeleton className="h-4 w-20 rounded-full" />
1169
+ ) : statusUnknown && !ready ? (
1170
+ <span className="flex items-center gap-1.5 text-xs text-amber-500 font-medium whitespace-nowrap">
1171
+ <IconAlertCircle className="h-3.5 w-3.5" />
1172
+ {t("dataSources.statusUnknown")}
1173
+ </span>
1164
1174
  ) : ready ? (
1165
1175
  <span className="flex items-center gap-1.5 text-xs text-emerald-500 font-medium whitespace-nowrap">
1166
1176
  <IconCheck className="h-3.5 w-3.5" />
@@ -1174,7 +1184,7 @@ function DataSourceCard({
1174
1184
  {t("dataSources.notConfigured")}
1175
1185
  </span>
1176
1186
  )}
1177
- {!isStatusLoading && sharedConnectionStatus && (
1187
+ {!isStatusLoading && !statusUnknown && sharedConnectionStatus && (
1178
1188
  <span className="data-source-shared-badge">
1179
1189
  <SharedConnectionBadge status={sharedConnectionStatus} />
1180
1190
  </span>
@@ -1189,7 +1199,26 @@ function DataSourceCard({
1189
1199
  </CardHeader>
1190
1200
  </button>
1191
1201
 
1192
- {expanded && (
1202
+ {expanded && showUnknownStatus && (
1203
+ <CardContent className="border-t border-border/50 px-5 py-4">
1204
+ <div className="space-y-3">
1205
+ <p className="flex items-start gap-2 text-xs text-muted-foreground">
1206
+ <IconAlertCircle className="mt-px h-3.5 w-3.5 shrink-0 text-amber-500" />
1207
+ {t("dataSources.statusUnknownDescription")}
1208
+ </p>
1209
+ <Button
1210
+ size="sm"
1211
+ variant="outline"
1212
+ onClick={() => setShowLocalCredentials(true)}
1213
+ className="text-xs"
1214
+ >
1215
+ {t("dataSources.addLocalCredentials")}
1216
+ </Button>
1217
+ </div>
1218
+ </CardContent>
1219
+ )}
1220
+
1221
+ {expanded && !showUnknownStatus && (
1193
1222
  <CardContent className="border-t border-border/50 px-5 py-4">
1194
1223
  {source.id === "github" && (
1195
1224
  <div className="mb-4">
@@ -1700,15 +1729,24 @@ export default function DataSources() {
1700
1729
  const queryClient = useQueryClient();
1701
1730
  const [search, setSearch] = useState("");
1702
1731
 
1703
- const { data: rawStatusData, isLoading: isStatusLoading } = useActionQuery(
1704
- "data-source-status",
1705
- undefined,
1706
- {
1707
- staleTime: 10_000,
1708
- },
1709
- );
1732
+ const {
1733
+ data: rawStatusData,
1734
+ isLoading: isStatusLoading,
1735
+ isError: isStatusError,
1736
+ } = useActionQuery("data-source-status", undefined, {
1737
+ staleTime: 10_000,
1738
+ });
1710
1739
  const statusData = rawStatusData as DataSourceStatusResponse | undefined;
1711
1740
  const envStatus = credentialRowsFromStatus(statusData);
1741
+ // A failed fetch, an error payload, or a failed workspace-connection lookup
1742
+ // all read as "everything is unconfigured" once they collapse into the empty
1743
+ // credential list. Keep them a separate state instead.
1744
+ const statusUnknown =
1745
+ !isStatusLoading &&
1746
+ (isStatusError ||
1747
+ !statusData ||
1748
+ Boolean(statusData.error) ||
1749
+ statusData.workspaceConnections?.available === false);
1712
1750
 
1713
1751
  const configuredCount = dataSources.filter((s) =>
1714
1752
  isSourceReady(s, statusData, envStatus),
@@ -1743,7 +1781,11 @@ export default function DataSources() {
1743
1781
  <p className="text-sm text-muted-foreground">
1744
1782
  {t("dataSources.intro")}{" "}
1745
1783
  {!isStatusLoading &&
1746
- (configuredCount > 0 ? (
1784
+ (statusUnknown && configuredCount === 0 ? (
1785
+ <span className="text-amber-500 font-medium">
1786
+ {t("dataSources.statusUnknown")}
1787
+ </span>
1788
+ ) : configuredCount > 0 ? (
1747
1789
  <span className="text-emerald-500 font-medium">
1748
1790
  {t("dataSources.configuredCount", { count: configuredCount })}
1749
1791
  </span>
@@ -1793,6 +1835,7 @@ export default function DataSources() {
1793
1835
  )}
1794
1836
  envStatus={envStatus}
1795
1837
  isStatusLoading={isStatusLoading}
1838
+ statusUnknown={statusUnknown}
1796
1839
  onSaved={handleSaved}
1797
1840
  />
1798
1841
  ))}
@@ -1830,6 +1873,7 @@ export default function DataSources() {
1830
1873
  )}
1831
1874
  envStatus={envStatus}
1832
1875
  isStatusLoading={isStatusLoading}
1876
+ statusUnknown={statusUnknown}
1833
1877
  onSaved={handleSaved}
1834
1878
  />
1835
1879
  ))}
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-07-28
4
+ ---
5
+
6
+ Analytics pages load reliably in workspaces with many saved dashboards.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-07-28
4
+ ---
5
+
6
+ Dashboard loading shimmer now flows smoothly in one direction instead of reversing.
@@ -153,10 +153,11 @@ export async function repairPersistedFirstPartyDashboardQueries(): Promise<boole
153
153
  * Returns the number of dashboards actually changed.
154
154
  */
155
155
  export async function repairUnboundedFirstPartyPanelsAcrossDashboards(): Promise<number> {
156
- // guard:allow-unscoped — this is an org-wide startup repair: it may touch
157
- // any dashboard's persisted panel SQL, but only ever replaces an exact
158
- // known-bad SQL string under the same optimistic (config, updatedAt) fence
159
- // used by the canonical repair above, so a concurrent edit always wins.
156
+ // guard:allow-unscoped — this explicit operator repair may touch any
157
+ // dashboard's persisted panel SQL. It must never run during server startup:
158
+ // reading every config on each serverless cold start can saturate the
159
+ // database. Exact-string matches and the optimistic (config, updatedAt)
160
+ // fence ensure a concurrent edit always wins.
160
161
  const db = getDb() as any;
161
162
  const dialect = getDialect();
162
163
  const rows = await db
@@ -302,7 +302,6 @@ function dataSourceStatusSummary(
302
302
  .replace(/[\s_]+/g, "-");
303
303
  if (normalizedName !== "data-source-status" || result.isError) continue;
304
304
 
305
- checked = true;
306
305
  let parsed: Record<string, unknown>;
307
306
  try {
308
307
  const value = JSON.parse(String(result.content ?? ""));
@@ -314,6 +313,19 @@ function dataSourceStatusSummary(
314
313
  continue;
315
314
  }
316
315
 
316
+ const workspaceConnections =
317
+ parsed.workspaceConnections &&
318
+ typeof parsed.workspaceConnections === "object" &&
319
+ !Array.isArray(parsed.workspaceConnections)
320
+ ? (parsed.workspaceConnections as Record<string, unknown>)
321
+ : null;
322
+ // A status result that errored, or whose workspace-connection lookup
323
+ // failed, says "we could not look", not "nothing is connected". Only a
324
+ // trustworthy result may mark the turn as checked.
325
+ if (!parsed.error && workspaceConnections?.available !== false) {
326
+ checked = true;
327
+ }
328
+
317
329
  let foundSetupLink = false;
318
330
  for (const candidate of [
319
331
  parsed.dataSourcesSetupLink,
@@ -392,12 +404,6 @@ function dataSourceStatusSummary(
392
404
  }
393
405
  }
394
406
 
395
- const workspaceConnections =
396
- parsed.workspaceConnections &&
397
- typeof parsed.workspaceConnections === "object" &&
398
- !Array.isArray(parsed.workspaceConnections)
399
- ? (parsed.workspaceConnections as Record<string, unknown>)
400
- : null;
401
407
  const workspaceProviders = Array.isArray(workspaceConnections?.providers)
402
408
  ? workspaceConnections.providers
403
409
  : [];
@@ -678,6 +684,46 @@ export function realDataFinalGuard(
678
684
  };
679
685
  }
680
686
 
687
+ export async function searchDashboardMentions(query: string, event?: any) {
688
+ if (!event) return [];
689
+ try {
690
+ const { getOrgContext } = await import("@agent-native/core/org");
691
+ const { listDashboardSummaries } =
692
+ await import("../lib/dashboards-store.js");
693
+ const ctx = await getOrgContext(event);
694
+ const rows = await listDashboardSummaries(
695
+ { email: ctx.email, orgId: ctx.orgId ?? null },
696
+ { kind: "sql", hidden: query ? "all" : "visible" },
697
+ );
698
+ const items = rows.map((dashboard) => ({
699
+ id: dashboard.id,
700
+ name: dashboard.name,
701
+ }));
702
+
703
+ const q = (query || "").toLowerCase().trim();
704
+ const filtered = q
705
+ ? items.filter(
706
+ (dashboard) =>
707
+ (dashboard.name || "").toLowerCase().includes(q) ||
708
+ dashboard.id.toLowerCase().includes(q),
709
+ )
710
+ : items;
711
+
712
+ return filtered.slice(0, 20).map((dashboard) => ({
713
+ id: `dashboard:${dashboard.id}`,
714
+ label: dashboard.name || "Untitled dashboard",
715
+ description: `/dashboards/${dashboard.id}`,
716
+ icon: "deck",
717
+ refType: "dashboard",
718
+ refId: dashboard.id,
719
+ refPath: `/dashboards/${dashboard.id}`,
720
+ }));
721
+ } catch (err) {
722
+ console.error("[analytics] Dashboard mention provider failed:", err);
723
+ return [];
724
+ }
725
+ }
726
+
681
727
  export default createAgentChatPlugin({
682
728
  appId: "analytics",
683
729
  actions: applyAnalyticsPlanModePolicy(
@@ -756,41 +802,7 @@ export default createAgentChatPlugin({
756
802
  dashboards: {
757
803
  label: "Dashboards",
758
804
  icon: "deck",
759
- search: async (query: string, event?: any) => {
760
- if (!event) return [];
761
- try {
762
- const { getOrgContext } = await import("@agent-native/core/org");
763
- const { listDashboards } = await import("../lib/dashboards-store.js");
764
- const ctx = await getOrgContext(event);
765
- const rows = await listDashboards(
766
- { email: ctx.email, orgId: ctx.orgId ?? null },
767
- { kind: "sql", hidden: query ? "all" : "visible" },
768
- );
769
- const items = rows.map((d) => ({ id: d.id, name: d.title }));
770
-
771
- const q = (query || "").toLowerCase().trim();
772
- const filtered = q
773
- ? items.filter(
774
- (d) =>
775
- (d.name || "").toLowerCase().includes(q) ||
776
- d.id.toLowerCase().includes(q),
777
- )
778
- : items;
779
-
780
- return filtered.slice(0, 20).map((d) => ({
781
- id: `dashboard:${d.id}`,
782
- label: d.name || "Untitled dashboard",
783
- description: `/dashboards/${d.id}`,
784
- icon: "deck",
785
- refType: "dashboard",
786
- refId: d.id,
787
- refPath: `/dashboards/${d.id}`,
788
- }));
789
- } catch (err) {
790
- console.error("[analytics] Dashboard mention provider failed:", err);
791
- return [];
792
- }
793
- },
805
+ search: searchDashboardMentions,
794
806
  },
795
807
  },
796
808
  });
@@ -8,10 +8,7 @@ import {
8
8
  // startup so the dashboard / analysis share actions know where to dispatch.
9
9
  import "../db/index.js";
10
10
  import * as schema from "../db/schema.js";
11
- import {
12
- repairPersistedFirstPartyDashboardQueries,
13
- repairUnboundedFirstPartyPanelsAcrossDashboards,
14
- } from "../lib/first-party-dashboard-repair.js";
11
+ import { repairPersistedFirstPartyDashboardQueries } from "../lib/first-party-dashboard-repair.js";
15
12
 
16
13
  /**
17
14
  * Every Drizzle table exported from schema.ts. Filters out type-only and
@@ -1338,20 +1335,6 @@ export default async (nitroApp: any): Promise<void> => {
1338
1335
  err instanceof Error ? err.message : err,
1339
1336
  );
1340
1337
  }
1341
- try {
1342
- const repairedCount =
1343
- await repairUnboundedFirstPartyPanelsAcrossDashboards();
1344
- if (repairedCount > 0) {
1345
- console.info(
1346
- `[db] Repaired ${repairedCount} dashboard(s) with unbounded first-party panel SQL.`,
1347
- );
1348
- }
1349
- } catch (err) {
1350
- console.warn(
1351
- "[db] Failed to repair unbounded first-party panels across dashboards (non-fatal):",
1352
- err instanceof Error ? err.message : err,
1353
- );
1354
- }
1355
1338
  try {
1356
1339
  const summary = await ensureAdditiveColumns({
1357
1340
  db: getDbExec(),
@@ -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:
@@ -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: