@agent-native/core 0.103.1 → 0.105.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 (568) hide show
  1. package/corpus/README.md +2 -2
  2. package/corpus/core/CHANGELOG.md +61 -0
  3. package/corpus/core/package.json +9 -2
  4. package/corpus/core/src/agent/engine/credential-errors.ts +2 -2
  5. package/corpus/core/src/agent/production-agent.ts +30 -0
  6. package/corpus/core/src/agent/run-store.ts +12 -2
  7. package/corpus/core/src/cli/create.ts +1 -0
  8. package/corpus/core/src/cli/skills-content/visual-plan-skill.ts +30 -11
  9. package/corpus/core/src/cli/templates-meta.ts +4 -3
  10. package/corpus/core/src/client/AgentAskPopover.tsx +89 -0
  11. package/corpus/core/src/client/AgentChatHome.tsx +4 -0
  12. package/corpus/core/src/client/AgentPanel.tsx +321 -223
  13. package/corpus/core/src/client/AssistantChat.tsx +6 -10
  14. package/corpus/core/src/client/MultiTabAssistantChat.tsx +53 -372
  15. package/corpus/core/src/client/agent-chat-adapter.ts +13 -1
  16. package/corpus/core/src/client/agent-page/AgentContextTab.tsx +133 -149
  17. package/corpus/core/src/client/agent-page/AgentEmptyState.tsx +44 -0
  18. package/corpus/core/src/client/agent-page/AgentJobsTab.tsx +153 -82
  19. package/corpus/core/src/client/agent-page/AgentTabFrame.tsx +39 -0
  20. package/corpus/core/src/client/agent-page/AgentTabsPage.tsx +368 -356
  21. package/corpus/core/src/client/agent-page/types.ts +1 -1
  22. package/corpus/core/src/client/analytics.ts +51 -5
  23. package/corpus/core/src/client/chat/run-recovery.tsx +12 -4
  24. package/corpus/core/src/client/composer/PromptComposer.tsx +5 -15
  25. package/corpus/core/src/client/composer/TiptapComposer.tsx +32 -3
  26. package/corpus/core/src/client/dynamic-suggestions.ts +3 -3
  27. package/corpus/core/src/client/index.ts +16 -1
  28. package/corpus/core/src/client/resources/ResourceTree.tsx +249 -38
  29. package/corpus/core/src/client/resources/ResourcesPanel.tsx +307 -140
  30. package/corpus/core/src/client/session-replay.ts +158 -5
  31. package/corpus/core/src/client/settings/AutomationsSection.tsx +30 -10
  32. package/corpus/core/src/client/settings/SettingsPanel.tsx +3 -2
  33. package/corpus/core/src/client/settings/SettingsTabsPage.tsx +2 -0
  34. package/corpus/core/src/client/settings/agent-settings-search.ts +2 -2
  35. package/corpus/core/src/client/use-chat-threads.ts +2 -0
  36. package/corpus/core/src/connections/catalog.ts +49 -7
  37. package/corpus/core/src/db/index.ts +6 -1
  38. package/corpus/core/src/deploy/build.ts +23 -0
  39. package/corpus/core/src/extensions/actions.ts +106 -16
  40. package/corpus/core/src/extensions/content-patch.ts +22 -0
  41. package/corpus/core/src/extensions/routes.ts +18 -0
  42. package/corpus/core/src/extensions/store.ts +8 -0
  43. package/corpus/core/src/index.ts +3 -0
  44. package/corpus/core/src/ingestion/docx.ts +158 -0
  45. package/corpus/core/src/ingestion/figma-node-to-html.ts +1860 -0
  46. package/corpus/core/src/ingestion/figma.ts +548 -0
  47. package/corpus/core/src/ingestion/index.ts +107 -0
  48. package/corpus/core/src/ingestion/media.ts +264 -0
  49. package/corpus/core/src/ingestion/notion.ts +121 -0
  50. package/corpus/core/src/ingestion/office.ts +214 -0
  51. package/corpus/core/src/ingestion/orchestration.ts +160 -0
  52. package/corpus/core/src/ingestion/pptx.ts +333 -0
  53. package/corpus/core/src/ingestion/selection.ts +81 -0
  54. package/corpus/core/src/ingestion/website.ts +151 -0
  55. package/corpus/core/src/integrations/plugin.ts +45 -37
  56. package/corpus/core/src/localization/default-messages.ts +35 -12
  57. package/corpus/core/src/observability/hosted-model-experiment.ts +118 -0
  58. package/corpus/core/src/observability/traces.ts +5 -3
  59. package/corpus/core/src/provider-api/index.ts +452 -8
  60. package/corpus/core/src/scripts/agent-engines/list-agent-engines.ts +18 -1
  61. package/corpus/core/src/search-utils/index.ts +112 -0
  62. package/corpus/core/src/secrets/register-framework-secrets.ts +61 -0
  63. package/corpus/core/src/server/action-discovery.ts +33 -8
  64. package/corpus/core/src/server/agent-chat/framework-prompts.ts +2 -2
  65. package/corpus/core/src/server/agent-chat/prompt-resources.ts +144 -0
  66. package/corpus/core/src/server/agent-chat-plugin.ts +6 -0
  67. package/corpus/core/src/server/core-routes-plugin.ts +12 -0
  68. package/corpus/core/src/server/index.ts +30 -0
  69. package/corpus/core/src/server/workspace-provider-oauth.ts +583 -0
  70. package/corpus/core/src/styles/agent-native.css +9 -0
  71. package/corpus/core/src/templates/default/app/i18n/en-US.ts +3 -3
  72. package/corpus/core/src/templates/workspace-core/.agents/skills/extensions/SKILL.md +14 -5
  73. package/corpus/core/src/templates/workspace-root/.env.example +12 -0
  74. package/corpus/core/src/workspace-connections/index.ts +6 -0
  75. package/corpus/core/src/workspace-connections/lifecycle.ts +43 -0
  76. package/corpus/core/src/workspace-connections/store.ts +16 -0
  77. package/corpus/templates/analytics/.agents/skills/dashboard-management/SKILL.md +46 -3
  78. package/corpus/templates/analytics/AGENTS.md +9 -0
  79. package/corpus/templates/analytics/actions/dashboard-mutation-api.ts +120 -6
  80. package/corpus/templates/analytics/actions/mutate-dashboard.ts +92 -30
  81. package/corpus/templates/analytics/actions/update-dashboard.ts +5 -5
  82. package/corpus/templates/analytics/app/components/dashboard/SqlChart.tsx +313 -220
  83. package/corpus/templates/analytics/app/components/layout/CommandPalette.tsx +2 -2
  84. package/corpus/templates/analytics/app/components/layout/Layout.tsx +9 -6
  85. package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +90 -64
  86. package/corpus/templates/analytics/app/i18n-data.ts +3 -3
  87. package/corpus/templates/analytics/app/lib/dashboard-list-loading.ts +25 -0
  88. package/corpus/templates/analytics/app/lib/item-popularity.ts +13 -4
  89. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/DashboardFilterBar.tsx +1 -1
  90. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/pivot.ts +8 -3
  91. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/types.ts +1 -0
  92. package/corpus/templates/analytics/app/pages/sessions/SessionDetailPage.tsx +15 -3
  93. package/corpus/templates/analytics/changelog/2026-07-16-dashboard-filter-defaults-can-now-be-changed-reliably-withou.md +6 -0
  94. package/corpus/templates/analytics/changelog/2026-07-16-dashboard-lists-load-in-one-stable-order-without-popping-bet.md +6 -0
  95. package/corpus/templates/analytics/changelog/2026-07-16-fixed-dashboard-filter-dropdown-text-alignment.md +6 -0
  96. package/corpus/templates/analytics/changelog/2026-07-16-recurring-signed-in-users-can-now-be-viewed-as-weekly-bars-b.md +6 -0
  97. package/corpus/templates/analytics/changelog/2026-07-16-the-analytics-agent-can-now-duplicate-a-chart-and-place-the-.md +6 -0
  98. package/corpus/templates/analytics/seeds/dashboards/agent-native-templates-first-party.json +41 -1
  99. package/corpus/templates/analytics/server/lib/dashboard-catalog.ts +1 -1
  100. package/corpus/templates/analytics/server/lib/first-party-metric-catalog.ts +47 -1
  101. package/corpus/templates/analytics/server/lib/session-replay.ts +68 -0
  102. package/corpus/templates/analytics/server/plugins/agent-chat.ts +1 -0
  103. package/corpus/templates/analytics/server/routes/sessions/lookup.get.ts +47 -0
  104. package/corpus/templates/assets/.agents/skills/asset-generation/SKILL.md +16 -9
  105. package/corpus/templates/assets/.agents/skills/creative-context/SKILL.md +86 -0
  106. package/corpus/templates/assets/AGENTS.md +10 -0
  107. package/corpus/templates/assets/actions/create-generation-session.ts +59 -1
  108. package/corpus/templates/assets/actions/edit-image.ts +2 -0
  109. package/corpus/templates/assets/actions/generate-asset.ts +52 -0
  110. package/corpus/templates/assets/actions/generate-image-batch.ts +55 -0
  111. package/corpus/templates/assets/actions/generate-image.ts +219 -1
  112. package/corpus/templates/assets/actions/open-asset-picker.ts +14 -0
  113. package/corpus/templates/assets/actions/refine-image.ts +3 -0
  114. package/corpus/templates/assets/actions/restyle-image.ts +2 -0
  115. package/corpus/templates/assets/agent-native.app-skill.json +4 -0
  116. package/corpus/templates/assets/app/components/layout/Layout.tsx +2 -0
  117. package/corpus/templates/assets/app/i18n/zh-TW.ts +3 -0
  118. package/corpus/templates/assets/app/i18n-data.ts +29 -13
  119. package/corpus/templates/assets/app/routes/agent.tsx +7 -1
  120. package/corpus/templates/assets/app/routes/library.tsx +9 -0
  121. package/corpus/templates/assets/app/routes/settings.tsx +3 -0
  122. package/corpus/templates/assets/changelog/2026-07-16-creative-context-library.md +6 -0
  123. package/corpus/templates/assets/package.json +1 -0
  124. package/corpus/templates/assets/server/lib/image-processing.ts +1 -22
  125. package/corpus/templates/assets/server/plugins/creative-context.ts +205 -0
  126. package/corpus/templates/brain/app/i18n-data.ts +3 -3
  127. package/corpus/templates/brain/app/lib/brain.ts +1 -1
  128. package/corpus/templates/brain/server/lib/search.ts +17 -67
  129. package/corpus/templates/calendar/app/i18n-data.ts +3 -3
  130. package/corpus/templates/calendar/app/pages/BookingLinksPage.tsx +19 -18
  131. package/corpus/templates/chat/app/i18n/en-US.ts +3 -3
  132. package/corpus/templates/chat/app/lib/agent-page.tsx +10 -1
  133. package/corpus/templates/clips/.agents/skills/meetings/SKILL.md +1 -1
  134. package/corpus/templates/clips/AGENTS.md +4 -0
  135. package/corpus/templates/clips/actions/cleanup-transcript.ts +35 -4
  136. package/corpus/templates/clips/actions/create-meeting.ts +6 -2
  137. package/corpus/templates/clips/actions/create-organization.ts +3 -2
  138. package/corpus/templates/clips/actions/create-recording.ts +4 -1
  139. package/corpus/templates/clips/actions/finalize-recording.ts +44 -7
  140. package/corpus/templates/clips/actions/import-loom-recording.ts +4 -1
  141. package/corpus/templates/clips/actions/lib/create-recording-schema.ts +2 -2
  142. package/corpus/templates/clips/actions/list-meetings.ts +23 -5
  143. package/corpus/templates/clips/actions/list-organization-state.ts +1 -1
  144. package/corpus/templates/clips/actions/remove-silences.ts +10 -1
  145. package/corpus/templates/clips/actions/request-transcript.ts +53 -11
  146. package/corpus/templates/clips/actions/search-recordings-utils.ts +7 -0
  147. package/corpus/templates/clips/actions/search-recordings.ts +5 -8
  148. package/corpus/templates/clips/actions/set-organization-branding.ts +2 -2
  149. package/corpus/templates/clips/actions/stitch-recordings.ts +10 -5
  150. package/corpus/templates/clips/actions/update-ai-request-status.ts +38 -0
  151. package/corpus/templates/clips/app/components/editor/editor-layout.tsx +3 -4
  152. package/corpus/templates/clips/app/components/editor/editor-selection.ts +19 -0
  153. package/corpus/templates/clips/app/components/editor/stitch-manager.tsx +10 -10
  154. package/corpus/templates/clips/app/components/library/bulk-action-toolbar.tsx +1 -2
  155. package/corpus/templates/clips/app/components/library/library-grid.tsx +101 -93
  156. package/corpus/templates/clips/app/components/player/video-player.tsx +11 -0
  157. package/corpus/templates/clips/app/components/workspace/branding-editor.tsx +53 -1
  158. package/corpus/templates/clips/app/i18n/ar-SA.ts +7 -1
  159. package/corpus/templates/clips/app/i18n/de-DE.ts +7 -1
  160. package/corpus/templates/clips/app/i18n/en-US.ts +10 -4
  161. package/corpus/templates/clips/app/i18n/es-ES.ts +7 -1
  162. package/corpus/templates/clips/app/i18n/fr-FR.ts +7 -1
  163. package/corpus/templates/clips/app/i18n/hi-IN.ts +7 -1
  164. package/corpus/templates/clips/app/i18n/ja-JP.ts +7 -1
  165. package/corpus/templates/clips/app/i18n/ko-KR.ts +7 -1
  166. package/corpus/templates/clips/app/i18n/pt-BR.ts +7 -1
  167. package/corpus/templates/clips/app/i18n/zh-CN.ts +6 -1
  168. package/corpus/templates/clips/app/i18n/zh-TW.ts +6 -1
  169. package/corpus/templates/clips/app/routes/_app.settings._index.tsx +5 -9
  170. package/corpus/templates/clips/app/routes/_app.settings.organization.tsx +6 -2
  171. package/corpus/templates/clips/app/routes/r.$recordingId.tsx +129 -27
  172. package/corpus/templates/clips/app/routes/record.tsx +23 -2
  173. package/corpus/templates/clips/app/routes/share.$shareId.tsx +6 -2
  174. package/corpus/templates/clips/app/routes.ts +3 -1
  175. package/corpus/templates/clips/changelog/2026-07-16-authorized-viewers-can-open-shared-private-clips-without-a-m.md +6 -0
  176. package/corpus/templates/clips/changelog/2026-07-16-camera-bubble-hover-controls-appear-above-the-face.md +6 -0
  177. package/corpus/templates/clips/changelog/2026-07-16-chrome-extension-recovers-stale-recorder-state.md +6 -0
  178. package/corpus/templates/clips/changelog/2026-07-16-clips-agent-chat-no-longer-shows-a-separate-workspace-header.md +6 -0
  179. package/corpus/templates/clips/changelog/2026-07-16-clips-search-now-matches-recording-content-without-requiring.md +6 -0
  180. package/corpus/templates/clips/changelog/2026-07-16-declined-meetings-no-longer-show-desktop-reminders.md +6 -0
  181. package/corpus/templates/clips/changelog/2026-07-16-failed-desktop-saves-now-show-their-local-recovery-copy.md +6 -0
  182. package/corpus/templates/clips/changelog/2026-07-16-long-desktop-clips-now-preserve-complete-playback-synced-aud.md +6 -0
  183. package/corpus/templates/clips/changelog/2026-07-16-long-recording-lists-keep-stitch-and-library-actions-visible.md +6 -0
  184. package/corpus/templates/clips/changelog/2026-07-16-organization-admins-can-choose-new-recording-visibility.md +6 -0
  185. package/corpus/templates/clips/changelog/2026-07-16-remove-silences-now-shows-queued-active-completed-and-failed.md +6 -0
  186. package/corpus/templates/clips/changelog/2026-07-16-settings-no-longer-repeats-the-builder-connection-status-in-.md +6 -0
  187. package/corpus/templates/clips/changelog/2026-07-16-transcripts-now-appear-from-native-browser-speech-sooner-wit.md +6 -0
  188. package/corpus/templates/clips/chrome-extension/public/manifest.json +1 -1
  189. package/corpus/templates/clips/chrome-extension/src/background.ts +73 -1
  190. package/corpus/templates/clips/chrome-extension/src/native-recording-state.ts +32 -0
  191. package/corpus/templates/clips/chrome-extension/src/native-transcription.ts +248 -0
  192. package/corpus/templates/clips/chrome-extension/src/offscreen.ts +106 -0
  193. package/corpus/templates/clips/desktop/src/app.tsx +66 -28
  194. package/corpus/templates/clips/desktop/src/lib/recorder.ts +335 -285
  195. package/corpus/templates/clips/desktop/src/lib/single-flight.ts +7 -0
  196. package/corpus/templates/clips/desktop/src/lib/upload-verification.ts +51 -0
  197. package/corpus/templates/clips/desktop/src/overlays/bubble.tsx +2 -2
  198. package/corpus/templates/clips/desktop/src/overlays/finalizing.tsx +10 -2
  199. package/corpus/templates/clips/desktop/src/styles.css +13 -11
  200. package/corpus/templates/clips/desktop/src-tauri/src/clips/mod.rs +8 -9
  201. package/corpus/templates/clips/desktop/src-tauri/src/meetings_watcher.rs +1 -0
  202. package/corpus/templates/clips/desktop/src-tauri/src/native_screen/custom_capture.rs +88 -13
  203. package/corpus/templates/clips/desktop/src-tauri/src/native_screen/live_upload.rs +13 -2
  204. package/corpus/templates/clips/desktop/src-tauri/src/native_screen.rs +241 -6
  205. package/corpus/templates/clips/server/db/schema.ts +2 -2
  206. package/corpus/templates/clips/server/lib/builder-media-compression.ts +64 -67
  207. package/corpus/templates/clips/server/lib/calendar-event-classification.ts +19 -0
  208. package/corpus/templates/clips/server/lib/google-calendar-client.ts +1 -0
  209. package/corpus/templates/clips/server/lib/recordings.ts +40 -1
  210. package/corpus/templates/clips/server/plugins/agent-chat.ts +1 -0
  211. package/corpus/templates/clips/server/plugins/db.ts +2 -2
  212. package/corpus/templates/clips/server/routes/api/auth/google-calendar.get.ts +1 -1
  213. package/corpus/templates/clips/server/routes/api/public-recording.get.ts +14 -5
  214. package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/chunk.post.ts +51 -1
  215. package/corpus/templates/clips/server/routes/api/video/[recordingId].get.ts +1 -64
  216. package/corpus/templates/clips/shared/media-worker-contract.ts +32 -15
  217. package/corpus/templates/content/.agents/skills/content/SKILL.md +16 -0
  218. package/corpus/templates/content/.agents/skills/creative-context/SKILL.md +85 -0
  219. package/corpus/templates/content/.agents/skills/notion-integration/SKILL.md +8 -0
  220. package/corpus/templates/content/AGENTS.md +9 -0
  221. package/corpus/templates/content/actions/create-document.ts +94 -0
  222. package/corpus/templates/content/actions/edit-document.ts +144 -4
  223. package/corpus/templates/content/actions/update-document.ts +138 -0
  224. package/corpus/templates/content/agent-native.app-skill.json +4 -0
  225. package/corpus/templates/content/app/components/layout/Layout.tsx +2 -0
  226. package/corpus/templates/content/app/i18n/zh-TW.ts +3 -0
  227. package/corpus/templates/content/app/i18n-data.ts +13 -4
  228. package/corpus/templates/content/app/routes/_app.agent.tsx +2 -1
  229. package/corpus/templates/content/app/routes/_app.settings.tsx +3 -0
  230. package/corpus/templates/content/changelog/2026-07-16-creative-context-library.md +6 -0
  231. package/corpus/templates/content/package.json +1 -0
  232. package/corpus/templates/content/server/plugins/creative-context.ts +31 -0
  233. package/corpus/templates/design/.agents/skills/creative-context/SKILL.md +116 -0
  234. package/corpus/templates/design/.agents/skills/design-generation/SKILL.md +16 -0
  235. package/corpus/templates/design/.agents/skills/design-systems/SKILL.md +8 -0
  236. package/corpus/templates/design/AGENTS.md +6 -0
  237. package/corpus/templates/design/actions/clone-creative-context-design.ts +176 -0
  238. package/corpus/templates/design/actions/edit-design.ts +128 -0
  239. package/corpus/templates/design/actions/generate-design.ts +278 -14
  240. package/corpus/templates/design/actions/generate-screens.ts +42 -1
  241. package/corpus/templates/design/agent-native.app-skill.json +4 -0
  242. package/corpus/templates/design/app/components/layout/Layout.tsx +7 -3
  243. package/corpus/templates/design/app/i18n/zh-TW.ts +3 -0
  244. package/corpus/templates/design/app/i18n-data.ts +10 -4
  245. package/corpus/templates/design/app/routes/agent.tsx +2 -1
  246. package/corpus/templates/design/app/routes/settings.tsx +3 -0
  247. package/corpus/templates/design/changelog/2026-07-16-creative-context-library.md +6 -0
  248. package/corpus/templates/design/changelog/2026-07-16-design-agent-chat-no-longer-shows-a-separate-workspace-header.md +6 -0
  249. package/corpus/templates/design/package.json +1 -0
  250. package/corpus/templates/design/server/lib/figma-design-context.ts +5 -335
  251. package/corpus/templates/design/server/lib/figma-node-to-html.ts +1 -1859
  252. package/corpus/templates/design/server/lib/import-design-files.ts +6 -8
  253. package/corpus/templates/design/server/plugins/creative-context.ts +31 -0
  254. package/corpus/templates/design/shared/generation-session.ts +7 -0
  255. package/corpus/templates/dispatch/app/i18n-data.ts +3 -3
  256. package/corpus/templates/forms/app/i18n/en-US.ts +3 -3
  257. package/corpus/templates/macros/app/i18n/en-US.ts +3 -3
  258. package/corpus/templates/mail/app/components/email/EmailThread.tsx +35 -5
  259. package/corpus/templates/mail/app/i18n/en-US.ts +3 -3
  260. package/corpus/templates/mail/changelog/2026-07-16-mail-previews-now-expand-to-show-the-full-message-without-an.md +6 -0
  261. package/corpus/templates/plan/.agents/skills/visual-plan/SKILL.md +30 -11
  262. package/corpus/templates/plan/AGENTS.md +21 -1
  263. package/corpus/templates/plan/actions/get-visual-plan.ts +1 -1
  264. package/corpus/templates/plan/actions/patch-visual-plan-source.ts +161 -0
  265. package/corpus/templates/plan/actions/read-visual-plan-source.ts +1 -1
  266. package/corpus/templates/plan/actions/update-visual-plan.ts +126 -10
  267. package/corpus/templates/plan/app/hooks/use-plans.ts +2 -0
  268. package/corpus/templates/plan/app/i18n/en-US.ts +3 -3
  269. package/corpus/templates/plan/app/pages/PlansPage.tsx +65 -62
  270. package/corpus/templates/plan/changelog/2026-07-16-local-plan-previews-now-load-annotations-containing-html-lik.md +6 -0
  271. package/corpus/templates/plan/changelog/2026-07-16-plan-agents-now-prevent-stale-edits-from-overwriting-newer-p.md +6 -0
  272. package/corpus/templates/plan/server/plan-mdx.ts +75 -2
  273. package/corpus/templates/slides/.agents/skills/create-deck/SKILL.md +21 -4
  274. package/corpus/templates/slides/.agents/skills/creative-context/SKILL.md +122 -0
  275. package/corpus/templates/slides/.agents/skills/design-systems/SKILL.md +11 -0
  276. package/corpus/templates/slides/.agents/skills/slide-editing/SKILL.md +12 -3
  277. package/corpus/templates/slides/AGENTS.md +6 -0
  278. package/corpus/templates/slides/actions/add-slide.ts +230 -14
  279. package/corpus/templates/slides/actions/clone-context-slide.ts +302 -0
  280. package/corpus/templates/slides/actions/create-deck.ts +130 -0
  281. package/corpus/templates/slides/actions/extract-pdf.ts +6 -2
  282. package/corpus/templates/slides/actions/import-file.ts +5 -4
  283. package/corpus/templates/slides/actions/patch-deck.ts +200 -10
  284. package/corpus/templates/slides/actions/update-slide.ts +208 -15
  285. package/corpus/templates/slides/app/components/layout/Layout.tsx +2 -0
  286. package/corpus/templates/slides/app/components/visual-editor/CanvasCommentPins.tsx +16 -1
  287. package/corpus/templates/slides/app/i18n/ar-SA.ts +3 -0
  288. package/corpus/templates/slides/app/i18n/de-DE.ts +3 -0
  289. package/corpus/templates/slides/app/i18n/en-US.ts +6 -3
  290. package/corpus/templates/slides/app/i18n/es-ES.ts +3 -0
  291. package/corpus/templates/slides/app/i18n/fr-FR.ts +3 -0
  292. package/corpus/templates/slides/app/i18n/hi-IN.ts +3 -0
  293. package/corpus/templates/slides/app/i18n/ja-JP.ts +3 -0
  294. package/corpus/templates/slides/app/i18n/ko-KR.ts +3 -0
  295. package/corpus/templates/slides/app/i18n/pt-BR.ts +3 -0
  296. package/corpus/templates/slides/app/i18n/zh-CN.ts +3 -0
  297. package/corpus/templates/slides/app/i18n/zh-TW.ts +3 -0
  298. package/corpus/templates/slides/app/lib/validate-native-slide-html.ts +176 -0
  299. package/corpus/templates/slides/app/routes/agent.tsx +7 -1
  300. package/corpus/templates/slides/app/routes/settings.tsx +3 -0
  301. package/corpus/templates/slides/changelog/2026-07-16-creative-context-library.md +6 -0
  302. package/corpus/templates/slides/changelog/2026-07-16-google-slides-native-cloning.md +6 -0
  303. package/corpus/templates/slides/package.json +1 -0
  304. package/corpus/templates/slides/server/handlers/import/docx-parser.ts +4 -85
  305. package/corpus/templates/slides/server/handlers/import/pptx-parser.ts +7 -421
  306. package/corpus/templates/slides/server/plugins/creative-context.ts +166 -0
  307. package/dist/agent/engine/credential-errors.d.ts +1 -1
  308. package/dist/agent/engine/credential-errors.d.ts.map +1 -1
  309. package/dist/agent/engine/credential-errors.js +2 -2
  310. package/dist/agent/engine/credential-errors.js.map +1 -1
  311. package/dist/agent/production-agent.d.ts.map +1 -1
  312. package/dist/agent/production-agent.js +25 -0
  313. package/dist/agent/production-agent.js.map +1 -1
  314. package/dist/agent/run-store.d.ts.map +1 -1
  315. package/dist/agent/run-store.js +12 -2
  316. package/dist/agent/run-store.js.map +1 -1
  317. package/dist/cli/create.d.ts.map +1 -1
  318. package/dist/cli/create.js +1 -0
  319. package/dist/cli/create.js.map +1 -1
  320. package/dist/cli/skills-content/visual-plan-skill.d.ts +1 -1
  321. package/dist/cli/skills-content/visual-plan-skill.d.ts.map +1 -1
  322. package/dist/cli/skills-content/visual-plan-skill.js +30 -11
  323. package/dist/cli/skills-content/visual-plan-skill.js.map +1 -1
  324. package/dist/cli/templates-meta.d.ts.map +1 -1
  325. package/dist/cli/templates-meta.js +4 -3
  326. package/dist/cli/templates-meta.js.map +1 -1
  327. package/dist/client/AgentAskPopover.d.ts +11 -0
  328. package/dist/client/AgentAskPopover.d.ts.map +1 -0
  329. package/dist/client/AgentAskPopover.js +30 -0
  330. package/dist/client/AgentAskPopover.js.map +1 -0
  331. package/dist/client/AgentChatHome.d.ts +1 -1
  332. package/dist/client/AgentChatHome.d.ts.map +1 -1
  333. package/dist/client/AgentChatHome.js +2 -2
  334. package/dist/client/AgentChatHome.js.map +1 -1
  335. package/dist/client/AgentPanel.d.ts +9 -19
  336. package/dist/client/AgentPanel.d.ts.map +1 -1
  337. package/dist/client/AgentPanel.js +119 -80
  338. package/dist/client/AgentPanel.js.map +1 -1
  339. package/dist/client/AssistantChat.d.ts.map +1 -1
  340. package/dist/client/AssistantChat.js +4 -4
  341. package/dist/client/AssistantChat.js.map +1 -1
  342. package/dist/client/MultiTabAssistantChat.d.ts +3 -9
  343. package/dist/client/MultiTabAssistantChat.d.ts.map +1 -1
  344. package/dist/client/MultiTabAssistantChat.js +49 -189
  345. package/dist/client/MultiTabAssistantChat.js.map +1 -1
  346. package/dist/client/agent-chat-adapter.d.ts.map +1 -1
  347. package/dist/client/agent-chat-adapter.js +12 -1
  348. package/dist/client/agent-chat-adapter.js.map +1 -1
  349. package/dist/client/agent-page/AgentContextTab.d.ts.map +1 -1
  350. package/dist/client/agent-page/AgentContextTab.js +26 -28
  351. package/dist/client/agent-page/AgentContextTab.js.map +1 -1
  352. package/dist/client/agent-page/AgentEmptyState.d.ts +13 -0
  353. package/dist/client/agent-page/AgentEmptyState.d.ts.map +1 -0
  354. package/dist/client/agent-page/AgentEmptyState.js +6 -0
  355. package/dist/client/agent-page/AgentEmptyState.js.map +1 -0
  356. package/dist/client/agent-page/AgentJobsTab.d.ts +1 -1
  357. package/dist/client/agent-page/AgentJobsTab.d.ts.map +1 -1
  358. package/dist/client/agent-page/AgentJobsTab.js +90 -58
  359. package/dist/client/agent-page/AgentJobsTab.js.map +1 -1
  360. package/dist/client/agent-page/AgentTabFrame.d.ts +12 -0
  361. package/dist/client/agent-page/AgentTabFrame.d.ts.map +1 -0
  362. package/dist/client/agent-page/AgentTabFrame.js +7 -0
  363. package/dist/client/agent-page/AgentTabFrame.js.map +1 -0
  364. package/dist/client/agent-page/AgentTabsPage.d.ts +9 -1
  365. package/dist/client/agent-page/AgentTabsPage.d.ts.map +1 -1
  366. package/dist/client/agent-page/AgentTabsPage.js +135 -99
  367. package/dist/client/agent-page/AgentTabsPage.js.map +1 -1
  368. package/dist/client/agent-page/types.d.ts +1 -1
  369. package/dist/client/agent-page/types.d.ts.map +1 -1
  370. package/dist/client/agent-page/types.js.map +1 -1
  371. package/dist/client/analytics.d.ts +10 -3
  372. package/dist/client/analytics.d.ts.map +1 -1
  373. package/dist/client/analytics.js +37 -2
  374. package/dist/client/analytics.js.map +1 -1
  375. package/dist/client/chat/run-recovery.d.ts.map +1 -1
  376. package/dist/client/chat/run-recovery.js +10 -3
  377. package/dist/client/chat/run-recovery.js.map +1 -1
  378. package/dist/client/composer/PromptComposer.d.ts.map +1 -1
  379. package/dist/client/composer/PromptComposer.js +2 -2
  380. package/dist/client/composer/PromptComposer.js.map +1 -1
  381. package/dist/client/composer/TiptapComposer.d.ts.map +1 -1
  382. package/dist/client/composer/TiptapComposer.js +15 -3
  383. package/dist/client/composer/TiptapComposer.js.map +1 -1
  384. package/dist/client/dynamic-suggestions.js +3 -3
  385. package/dist/client/dynamic-suggestions.js.map +1 -1
  386. package/dist/client/index.d.ts +4 -3
  387. package/dist/client/index.d.ts.map +1 -1
  388. package/dist/client/index.js +3 -2
  389. package/dist/client/index.js.map +1 -1
  390. package/dist/client/resources/ResourceTree.d.ts +5 -1
  391. package/dist/client/resources/ResourceTree.d.ts.map +1 -1
  392. package/dist/client/resources/ResourceTree.js +74 -5
  393. package/dist/client/resources/ResourceTree.js.map +1 -1
  394. package/dist/client/resources/ResourcesPanel.d.ts +11 -2
  395. package/dist/client/resources/ResourcesPanel.d.ts.map +1 -1
  396. package/dist/client/resources/ResourcesPanel.js +105 -31
  397. package/dist/client/resources/ResourcesPanel.js.map +1 -1
  398. package/dist/client/session-replay.d.ts +28 -0
  399. package/dist/client/session-replay.d.ts.map +1 -1
  400. package/dist/client/session-replay.js +122 -8
  401. package/dist/client/session-replay.js.map +1 -1
  402. package/dist/client/settings/AutomationsSection.d.ts +3 -1
  403. package/dist/client/settings/AutomationsSection.d.ts.map +1 -1
  404. package/dist/client/settings/AutomationsSection.js +16 -6
  405. package/dist/client/settings/AutomationsSection.js.map +1 -1
  406. package/dist/client/settings/SettingsPanel.d.ts.map +1 -1
  407. package/dist/client/settings/SettingsPanel.js +3 -3
  408. package/dist/client/settings/SettingsPanel.js.map +1 -1
  409. package/dist/client/settings/SettingsTabsPage.d.ts +2 -0
  410. package/dist/client/settings/SettingsTabsPage.d.ts.map +1 -1
  411. package/dist/client/settings/SettingsTabsPage.js.map +1 -1
  412. package/dist/client/settings/agent-settings-search.js +2 -2
  413. package/dist/client/settings/agent-settings-search.js.map +1 -1
  414. package/dist/client/use-chat-threads.d.ts +2 -0
  415. package/dist/client/use-chat-threads.d.ts.map +1 -1
  416. package/dist/client/use-chat-threads.js.map +1 -1
  417. package/dist/connections/catalog.d.ts +41 -7
  418. package/dist/connections/catalog.d.ts.map +1 -1
  419. package/dist/connections/catalog.js +40 -7
  420. package/dist/connections/catalog.js.map +1 -1
  421. package/dist/db/index.d.ts +2 -2
  422. package/dist/db/index.d.ts.map +1 -1
  423. package/dist/db/index.js +2 -2
  424. package/dist/db/index.js.map +1 -1
  425. package/dist/deploy/build.d.ts.map +1 -1
  426. package/dist/deploy/build.js +17 -0
  427. package/dist/deploy/build.js.map +1 -1
  428. package/dist/extensions/actions.d.ts.map +1 -1
  429. package/dist/extensions/actions.js +85 -15
  430. package/dist/extensions/actions.js.map +1 -1
  431. package/dist/extensions/content-patch.d.ts +4 -0
  432. package/dist/extensions/content-patch.d.ts.map +1 -1
  433. package/dist/extensions/content-patch.js +18 -0
  434. package/dist/extensions/content-patch.js.map +1 -1
  435. package/dist/extensions/routes.d.ts.map +1 -1
  436. package/dist/extensions/routes.js +14 -0
  437. package/dist/extensions/routes.js.map +1 -1
  438. package/dist/extensions/store.d.ts +1 -0
  439. package/dist/extensions/store.d.ts.map +1 -1
  440. package/dist/extensions/store.js +4 -1
  441. package/dist/extensions/store.js.map +1 -1
  442. package/dist/index.d.ts +1 -1
  443. package/dist/index.d.ts.map +1 -1
  444. package/dist/index.js +1 -1
  445. package/dist/index.js.map +1 -1
  446. package/dist/ingestion/docx.d.ts +16 -0
  447. package/dist/ingestion/docx.d.ts.map +1 -0
  448. package/dist/ingestion/docx.js +129 -0
  449. package/dist/ingestion/docx.js.map +1 -0
  450. package/dist/ingestion/figma-node-to-html.d.ts +304 -0
  451. package/dist/ingestion/figma-node-to-html.d.ts.map +1 -0
  452. package/dist/ingestion/figma-node-to-html.js +1292 -0
  453. package/dist/ingestion/figma-node-to-html.js.map +1 -0
  454. package/dist/ingestion/figma.d.ts +115 -0
  455. package/dist/ingestion/figma.d.ts.map +1 -0
  456. package/dist/ingestion/figma.js +399 -0
  457. package/dist/ingestion/figma.js.map +1 -0
  458. package/dist/ingestion/index.d.ts +11 -0
  459. package/dist/ingestion/index.d.ts.map +1 -0
  460. package/dist/ingestion/index.js +11 -0
  461. package/dist/ingestion/index.js.map +1 -0
  462. package/dist/ingestion/media.d.ts +36 -0
  463. package/dist/ingestion/media.d.ts.map +1 -0
  464. package/dist/ingestion/media.js +178 -0
  465. package/dist/ingestion/media.js.map +1 -0
  466. package/dist/ingestion/notion.d.ts +12 -0
  467. package/dist/ingestion/notion.d.ts.map +1 -0
  468. package/dist/ingestion/notion.js +104 -0
  469. package/dist/ingestion/notion.js.map +1 -0
  470. package/dist/ingestion/office.d.ts +45 -0
  471. package/dist/ingestion/office.d.ts.map +1 -0
  472. package/dist/ingestion/office.js +141 -0
  473. package/dist/ingestion/office.js.map +1 -0
  474. package/dist/ingestion/orchestration.d.ts +52 -0
  475. package/dist/ingestion/orchestration.d.ts.map +1 -0
  476. package/dist/ingestion/orchestration.js +89 -0
  477. package/dist/ingestion/orchestration.js.map +1 -0
  478. package/dist/ingestion/pptx.d.ts +28 -0
  479. package/dist/ingestion/pptx.d.ts.map +1 -0
  480. package/dist/ingestion/pptx.js +255 -0
  481. package/dist/ingestion/pptx.js.map +1 -0
  482. package/dist/ingestion/selection.d.ts +20 -0
  483. package/dist/ingestion/selection.d.ts.map +1 -0
  484. package/dist/ingestion/selection.js +52 -0
  485. package/dist/ingestion/selection.js.map +1 -0
  486. package/dist/ingestion/website.d.ts +27 -0
  487. package/dist/ingestion/website.d.ts.map +1 -0
  488. package/dist/ingestion/website.js +100 -0
  489. package/dist/ingestion/website.js.map +1 -0
  490. package/dist/integrations/plugin.d.ts.map +1 -1
  491. package/dist/integrations/plugin.js +32 -27
  492. package/dist/integrations/plugin.js.map +1 -1
  493. package/dist/localization/default-messages.d.ts +22 -0
  494. package/dist/localization/default-messages.d.ts.map +1 -1
  495. package/dist/localization/default-messages.js +31 -9
  496. package/dist/localization/default-messages.js.map +1 -1
  497. package/dist/notifications/routes.d.ts +2 -2
  498. package/dist/observability/hosted-model-experiment.d.ts +39 -0
  499. package/dist/observability/hosted-model-experiment.d.ts.map +1 -0
  500. package/dist/observability/hosted-model-experiment.js +90 -0
  501. package/dist/observability/hosted-model-experiment.js.map +1 -0
  502. package/dist/observability/routes.d.ts +5 -5
  503. package/dist/observability/traces.d.ts.map +1 -1
  504. package/dist/observability/traces.js +5 -3
  505. package/dist/observability/traces.js.map +1 -1
  506. package/dist/provider-api/index.d.ts +35 -4
  507. package/dist/provider-api/index.d.ts.map +1 -1
  508. package/dist/provider-api/index.js +339 -8
  509. package/dist/provider-api/index.js.map +1 -1
  510. package/dist/scripts/agent-engines/list-agent-engines.d.ts.map +1 -1
  511. package/dist/scripts/agent-engines/list-agent-engines.js +18 -1
  512. package/dist/scripts/agent-engines/list-agent-engines.js.map +1 -1
  513. package/dist/search-utils/index.d.ts +12 -0
  514. package/dist/search-utils/index.d.ts.map +1 -0
  515. package/dist/search-utils/index.js +95 -0
  516. package/dist/search-utils/index.js.map +1 -0
  517. package/dist/secrets/register-framework-secrets.d.ts.map +1 -1
  518. package/dist/secrets/register-framework-secrets.js +57 -0
  519. package/dist/secrets/register-framework-secrets.js.map +1 -1
  520. package/dist/secrets/routes.d.ts +9 -9
  521. package/dist/server/action-discovery.d.ts +8 -0
  522. package/dist/server/action-discovery.d.ts.map +1 -1
  523. package/dist/server/action-discovery.js +26 -9
  524. package/dist/server/action-discovery.js.map +1 -1
  525. package/dist/server/agent-chat/framework-prompts.js +2 -2
  526. package/dist/server/agent-chat/framework-prompts.js.map +1 -1
  527. package/dist/server/agent-chat/prompt-resources.d.ts +19 -0
  528. package/dist/server/agent-chat/prompt-resources.d.ts.map +1 -1
  529. package/dist/server/agent-chat/prompt-resources.js +95 -0
  530. package/dist/server/agent-chat/prompt-resources.js.map +1 -1
  531. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  532. package/dist/server/agent-chat-plugin.js +7 -0
  533. package/dist/server/agent-chat-plugin.js.map +1 -1
  534. package/dist/server/core-routes-plugin.d.ts.map +1 -1
  535. package/dist/server/core-routes-plugin.js +5 -0
  536. package/dist/server/core-routes-plugin.js.map +1 -1
  537. package/dist/server/index.d.ts +5 -1
  538. package/dist/server/index.d.ts.map +1 -1
  539. package/dist/server/index.js +5 -1
  540. package/dist/server/index.js.map +1 -1
  541. package/dist/server/workspace-provider-oauth.d.ts +48 -0
  542. package/dist/server/workspace-provider-oauth.d.ts.map +1 -0
  543. package/dist/server/workspace-provider-oauth.js +415 -0
  544. package/dist/server/workspace-provider-oauth.js.map +1 -0
  545. package/dist/styles/agent-native.css +9 -0
  546. package/dist/templates/chat/app/i18n/en-US.ts +3 -3
  547. package/dist/templates/chat/app/lib/agent-page.tsx +10 -1
  548. package/dist/templates/default/app/i18n/en-US.ts +3 -3
  549. package/dist/templates/workspace-core/.agents/skills/extensions/SKILL.md +14 -5
  550. package/dist/templates/workspace-root/.env.example +12 -0
  551. package/dist/workspace-connections/index.d.ts +1 -0
  552. package/dist/workspace-connections/index.d.ts.map +1 -1
  553. package/dist/workspace-connections/index.js +1 -0
  554. package/dist/workspace-connections/index.js.map +1 -1
  555. package/dist/workspace-connections/lifecycle.d.ts +16 -0
  556. package/dist/workspace-connections/lifecycle.d.ts.map +1 -0
  557. package/dist/workspace-connections/lifecycle.js +14 -0
  558. package/dist/workspace-connections/lifecycle.js.map +1 -0
  559. package/dist/workspace-connections/store.d.ts.map +1 -1
  560. package/dist/workspace-connections/store.js +16 -0
  561. package/dist/workspace-connections/store.js.map +1 -1
  562. package/package.json +10 -3
  563. package/src/templates/chat/app/i18n/en-US.ts +3 -3
  564. package/src/templates/chat/app/lib/agent-page.spec.tsx +10 -1
  565. package/src/templates/chat/app/lib/agent-page.tsx +10 -1
  566. package/src/templates/default/app/i18n/en-US.ts +3 -3
  567. package/src/templates/workspace-core/.agents/skills/extensions/SKILL.md +14 -5
  568. package/src/templates/workspace-root/.env.example +12 -0
@@ -0,0 +1,43 @@
1
+ export type WorkspaceConnectionLifecycleEvent =
2
+ | {
3
+ type: "connection-deleted";
4
+ connectionId: string;
5
+ ownerEmail: string;
6
+ orgId: string | null;
7
+ }
8
+ | {
9
+ type: "grant-revoked";
10
+ connectionId: string;
11
+ appId: string;
12
+ ownerEmail: string;
13
+ orgId: string | null;
14
+ };
15
+
16
+ export type WorkspaceConnectionLifecycleListener = (
17
+ event: WorkspaceConnectionLifecycleEvent,
18
+ ) => void | Promise<void>;
19
+
20
+ const LISTENERS_KEY = Symbol.for(
21
+ "@agent-native/core.workspace-connection-lifecycle-listeners",
22
+ );
23
+
24
+ function listeners(): Set<WorkspaceConnectionLifecycleListener> {
25
+ const global = globalThis as typeof globalThis & {
26
+ [LISTENERS_KEY]?: Set<WorkspaceConnectionLifecycleListener>;
27
+ };
28
+ global[LISTENERS_KEY] ??= new Set();
29
+ return global[LISTENERS_KEY];
30
+ }
31
+
32
+ export function registerWorkspaceConnectionLifecycleListener(
33
+ listener: WorkspaceConnectionLifecycleListener,
34
+ ): () => void {
35
+ listeners().add(listener);
36
+ return () => listeners().delete(listener);
37
+ }
38
+
39
+ export async function notifyWorkspaceConnectionLifecycle(
40
+ event: WorkspaceConnectionLifecycleEvent,
41
+ ): Promise<void> {
42
+ await Promise.all([...listeners()].map((listener) => listener(event)));
43
+ }
@@ -24,6 +24,7 @@ import {
24
24
  getRequestOrgId,
25
25
  getRequestUserEmail,
26
26
  } from "../server/request-context.js";
27
+ import { notifyWorkspaceConnectionLifecycle } from "./lifecycle.js";
27
28
 
28
29
  export type WorkspaceConnectionStatus =
29
30
  | "connected"
@@ -1903,6 +1904,15 @@ export async function revokeWorkspaceConnectionGrant(
1903
1904
  sql: `DELETE FROM ${table} WHERE connection_id = ? AND app_id = ? AND ${where.sql}`,
1904
1905
  args: [normalizedConnectionId, normalizedAppId, ...where.args],
1905
1906
  });
1907
+ if (result.rowsAffected > 0) {
1908
+ await notifyWorkspaceConnectionLifecycle({
1909
+ type: "grant-revoked",
1910
+ connectionId: normalizedConnectionId,
1911
+ appId: normalizedAppId,
1912
+ ownerEmail: scope.ownerEmail,
1913
+ orgId: scope.orgId,
1914
+ });
1915
+ }
1906
1916
  return result.rowsAffected > 0;
1907
1917
  }
1908
1918
 
@@ -1922,6 +1932,12 @@ export async function deleteWorkspaceConnection(id: string): Promise<boolean> {
1922
1932
  sql: `DELETE FROM ${grantsTable} WHERE connection_id = ? AND ${where.sql}`,
1923
1933
  args: [id, ...where.args],
1924
1934
  });
1935
+ await notifyWorkspaceConnectionLifecycle({
1936
+ type: "connection-deleted",
1937
+ connectionId: id,
1938
+ ownerEmail: scope.ownerEmail,
1939
+ orgId: scope.orgId,
1940
+ });
1925
1941
  }
1926
1942
  return result.rowsAffected > 0;
1927
1943
  }
@@ -192,6 +192,20 @@ re-typing it as a `content` argument.
192
192
  extension panel (`chartType: "extension"`, `config.extensionId`), then
193
193
  `navigate` to it.
194
194
 
195
+ ## Repairing An Existing Extension-Backed Dashboard
196
+
197
+ When the user asks to fix data loading in an existing or migrated
198
+ extension-backed dashboard, treat the current extension body as user-authored
199
+ design. Read the dashboard config and extension once, identify the smallest
200
+ data-loading seam, and call `update-extension` with focused `patches` or
201
+ `edits`. Preserve the existing layout, CSS, copy, and interactions. Do not
202
+ send a reconstructed full `content` body for a data-only repair;
203
+ `update-extension` blocks full-body replacement unless
204
+ `allowFullReplacement: true` is explicitly supplied. Use that flag only for a
205
+ user-requested broad visual rewrite or a complete replacement body supplied by
206
+ the user. If a focused edit fails, inspect the current body and change the
207
+ target rather than retrying the same arguments.
208
+
195
209
  ### Display truncation is cosmetic — do not chase the "missing" tail
196
210
 
197
211
  A tool result ending in `...[truncated — full result was N chars; only first
@@ -315,6 +329,10 @@ calling other actions from the script are not available.
315
329
  type DashboardMutationApi = {
316
330
  dashboard: {
317
331
  set(patch: DashboardPatch): void;
332
+ setFilterDefault(
333
+ filterId: string,
334
+ value: string | number | boolean | null,
335
+ ): void;
318
336
  panel(id: string): PanelSelection;
319
337
  section(id: string): SectionSelection;
320
338
  panels(ids: string[]): PanelSelection;
@@ -329,6 +347,7 @@ type DashboardPatch = {
329
347
  columns?: number;
330
348
  filters?: unknown[];
331
349
  variables?: Record<string, string>;
350
+ parentId?: string;
332
351
  };
333
352
 
334
353
  type PanelTimeScope =
@@ -340,6 +359,7 @@ type PanelTimeScope =
340
359
  type PanelConfig = Record<string, unknown> & {
341
360
  // Use "dashboard" for AI-generated first-party panels by default.
342
361
  timeScope?: PanelTimeScope;
362
+ // Fixed bar width in pixels for bar charts.
343
363
  };
344
364
 
345
365
  type PanelPatch = {
@@ -351,7 +371,8 @@ type PanelPatch = {
351
371
  | "amplitude"
352
372
  | "first-party"
353
373
  | "demo"
354
- | "prometheus";
374
+ | "prometheus"
375
+ | "program";
355
376
  chartType?:
356
377
  | "line"
357
378
  | "area"
@@ -397,6 +418,14 @@ type PanelSelection = {
397
418
  moveBefore(panelId: string): void;
398
419
  moveAfter(panelId: string): void;
399
420
  moveToIndex(index: number): void;
421
+ moveNextTo(panelId: string): void;
422
+ nextTo(panelId: string): void;
423
+ moveToRow(rowNumber: number): void;
424
+ moveToRowStart(rowNumber: number): void;
425
+ moveToRowEnd(rowNumber: number): void;
426
+ atRow(rowNumber: number): void;
427
+ atRowStart(rowNumber: number): void;
428
+ atRowEnd(rowNumber: number): void;
400
429
  remove(): void;
401
430
  set(patch: PanelPatch): void;
402
431
  setTitle(title: string): void;
@@ -404,26 +433,40 @@ type PanelSelection = {
404
433
  setWidth(width: number): void;
405
434
  setConfig(patch: Record<string, unknown>): void;
406
435
  setConfigPath(path: string, value: unknown): void;
407
- duplicate(newPanelId: string, patch?: PanelPatch): void;
436
+ duplicate(newPanelId: string, patch?: PanelPatch): PanelPlacement;
408
437
  };
409
438
 
410
439
  type SectionSelection = PanelSelection & {
411
440
  append(panelIds: string[]): void;
412
441
  };
413
442
 
414
- type InsertedPanel = {
443
+ type PanelPlacement = {
415
444
  atTop(): void;
416
445
  atBottom(): void;
417
446
  before(panelId: string): void;
418
447
  after(panelId: string): void;
419
448
  atIndex(index: number): void;
449
+ nextTo(panelId: string): void;
450
+ atRow(rowNumber: number): void;
451
+ atRowStart(rowNumber: number): void;
452
+ atRowEnd(rowNumber: number): void;
420
453
  };
454
+
455
+ type InsertedPanel = PanelPlacement;
421
456
  ```
422
457
 
423
458
  Examples:
424
459
 
425
460
  ```ts
426
461
  dashboard.panels(["dau-over-time", "wau-over-time"]).moveToTop();
462
+ dashboard
463
+ .panel("recurring-users-by-template")
464
+ .duplicate("recurring-users-by-template-bar", {
465
+ title: "Recurring Signed-In Users by Template (Bar)",
466
+ chartType: "bar",
467
+ })
468
+ .nextTo("recurring-users-by-template");
469
+ dashboard.setFilterDefault("emailFilter", "exclude_builder");
427
470
  dashboard.panel("top-referrers").setTitle("Top Referrers by Domain");
428
471
  dashboard.panel("retention").set({
429
472
  width: 2,
@@ -175,6 +175,15 @@ details live in `.agents/skills/`.
175
175
  or bespoke workflow cannot be done faithfully with the built-in dashboard JSON
176
176
  config/components or saved-analysis markdown/chart format, automatically build
177
177
  it as an extension instead and tell the user why.
178
+ - For an existing extension-backed dashboard or migrated surface such as Risk
179
+ Meeting, separate data repair from visual redesign. Inspect the dashboard and
180
+ extension first, then use `update-extension` `patches`/`edits` that touch only
181
+ the data-loading seam. Preserve the existing layout, CSS, copy, and
182
+ interactions; never reconstruct the full HTML body for a data-only fix.
183
+ `update-extension` blocks full-body replacement unless
184
+ `allowFullReplacement: true` is explicit, and that flag is reserved for a
185
+ user-requested broad rewrite or a complete replacement body supplied by the
186
+ user. If a focused edit fails, do not retry unchanged arguments.
178
187
  - Use framework sharing and access helpers for dashboards, analyses, and saved
179
188
  resources.
180
189
  - Dashboard email reports live in SQL via the
@@ -14,6 +14,7 @@ import { movePanelsById, type PanelOrderTarget } from "./dashboard-panel-order";
14
14
  export const DASHBOARD_MUTATION_API_TYPES = `type DashboardScript = {
15
15
  dashboard: {
16
16
  set(patch: DashboardPatch): void;
17
+ setFilterDefault(filterId: string, value: string | number | boolean | null): void;
17
18
  panel(id: string): PanelSelection;
18
19
  section(id: string): SectionSelection;
19
20
  panels(ids: string[]): PanelSelection;
@@ -41,6 +42,7 @@ type PanelTimeScope =
41
42
  type PanelConfig = Record<string, unknown> & {
42
43
  /** Use "dashboard" for AI-generated first-party panels by default. */
43
44
  timeScope?: PanelTimeScope;
45
+ /** Fixed bar width in pixels for bar charts. */
44
46
  };
45
47
 
46
48
  type PanelPatch = {
@@ -96,14 +98,14 @@ type PanelSelection = {
96
98
  setWidth(width: number): void;
97
99
  setConfig(patch: Record<string, unknown>): void;
98
100
  setConfigPath(path: string, value: unknown): void; // path under config, e.g. "yAxis.format" or "config.yAxis.format"
99
- duplicate(newPanelId: string, patch?: PanelPatch): void;
101
+ duplicate(newPanelId: string, patch?: PanelPatch): PanelPlacement;
100
102
  };
101
103
 
102
104
  type SectionSelection = PanelSelection & {
103
105
  append(panelIds: string[]): void;
104
106
  };
105
107
 
106
- type InsertedPanel = {
108
+ type PanelPlacement = {
107
109
  atTop(): void;
108
110
  atBottom(): void;
109
111
  before(panelId: string): void;
@@ -113,10 +115,14 @@ type InsertedPanel = {
113
115
  atRow(rowNumber: number): void; // 1-based visible row number, end of row
114
116
  atRowStart(rowNumber: number): void;
115
117
  atRowEnd(rowNumber: number): void;
116
- };`;
118
+ };
119
+
120
+ type InsertedPanel = PanelPlacement;`;
117
121
 
118
122
  export const DASHBOARD_MUTATION_EXAMPLES = [
119
123
  'dashboard.panels(["dau-over-time","wau-over-time"]).moveToTop();',
124
+ 'dashboard.panel("recurring-users-by-template").duplicate("recurring-users-by-template-bar", {"title":"Recurring Signed-In Users by Template (Bar)","chartType":"bar"}).nextTo("recurring-users-by-template");',
125
+ 'dashboard.setFilterDefault("emailFilter","exclude_builder");',
120
126
  'dashboard.panel("top-referrers").setTitle("Top Referrers by Domain");',
121
127
  'dashboard.panel("retention").set({"width":2,"config":{"description":"Updated definition."}});',
122
128
  'dashboard.panelsMatching({"titleIncludes":"Signed-In"}).moveToTop();',
@@ -183,6 +189,11 @@ export type DashboardMutationOperation =
183
189
  | {
184
190
  op: "setDashboard";
185
191
  patch: Record<string, unknown>;
192
+ }
193
+ | {
194
+ op: "setFilterDefault";
195
+ filterId: string;
196
+ value: string | number | boolean | null;
186
197
  };
187
198
 
188
199
  export interface DashboardMutationResult {
@@ -217,6 +228,7 @@ type DashboardPlacementTarget = PanelOrderTarget | VisualPlacementTarget;
217
228
 
218
229
  const DASHBOARD_SUBJECTS = [
219
230
  "set",
231
+ "setFilterDefault",
220
232
  "panel",
221
233
  "section",
222
234
  "panels",
@@ -277,6 +289,49 @@ function panelsFromConfig(config: Record<string, unknown>) {
277
289
  return panels as Array<Record<string, unknown>>;
278
290
  }
279
291
 
292
+ function requireDashboardFilter(
293
+ config: Record<string, unknown>,
294
+ filterId: string,
295
+ ): Record<string, unknown> {
296
+ if (!Array.isArray(config.filters)) {
297
+ throw new Error("config.filters must be an array");
298
+ }
299
+ const filters = config.filters as Array<Record<string, unknown>>;
300
+ const filter = filters.find((item) => item?.id === filterId);
301
+ if (!filter) {
302
+ const ids = filters
303
+ .map((item) => (typeof item?.id === "string" ? item.id : ""))
304
+ .filter(Boolean);
305
+ throw new Error(
306
+ `filter "${filterId}" was not found. Available filter ids: ${compactList(ids)}.`,
307
+ );
308
+ }
309
+ return filter;
310
+ }
311
+
312
+ function setFilterDefault(
313
+ config: Record<string, unknown>,
314
+ filterId: string,
315
+ value: string | number | boolean | null,
316
+ ): void {
317
+ const filter = requireDashboardFilter(config, filterId);
318
+ if (Array.isArray(filter.options) && filter.options.length > 0) {
319
+ const optionValues = filter.options
320
+ .map((option) =>
321
+ option && typeof option === "object" && !Array.isArray(option)
322
+ ? (option as Record<string, unknown>).value
323
+ : undefined,
324
+ )
325
+ .filter((optionValue) => optionValue !== undefined);
326
+ if (!optionValues.some((optionValue) => Object.is(optionValue, value))) {
327
+ throw new Error(
328
+ `filter "${filterId}" default ${JSON.stringify(value)} is not one of its option values: ${optionValues.map((optionValue) => JSON.stringify(optionValue)).join(", ")}`,
329
+ );
330
+ }
331
+ }
332
+ filter.default = value;
333
+ }
334
+
280
335
  function panelId(panel: Record<string, unknown>): string {
281
336
  return typeof panel.id === "string" ? panel.id : "";
282
337
  }
@@ -895,6 +950,14 @@ export function applyDashboardMutationOperations(
895
950
  );
896
951
  break;
897
952
  }
953
+ case "setFilterDefault": {
954
+ setFilterDefault(config, op.filterId, op.value);
955
+ dashboardFieldsChanged.add(`filters.${op.filterId}.default`);
956
+ commandLog.push(
957
+ `setFilterDefault(${op.filterId}: ${JSON.stringify(op.value)})`,
958
+ );
959
+ break;
960
+ }
898
961
  default:
899
962
  throw new Error(
900
963
  `unsupported dashboard mutation op ${(op as any).op}`,
@@ -1304,6 +1367,33 @@ function operationsFromStatement(
1304
1367
  ];
1305
1368
  }
1306
1369
 
1370
+ if (subject.name === "setFilterDefault") {
1371
+ if (commands.length > 0) {
1372
+ throw new Error("dashboard.setFilterDefault(...) cannot be chained");
1373
+ }
1374
+ if (subject.args.length !== 2) {
1375
+ throw new Error(
1376
+ "dashboard.setFilterDefault(...) requires filterId and value",
1377
+ );
1378
+ }
1379
+ const value = subject.args[1];
1380
+ if (
1381
+ value !== null &&
1382
+ !["string", "number", "boolean"].includes(typeof value)
1383
+ ) {
1384
+ throw new Error(
1385
+ "dashboard.setFilterDefault(...) value must be a string, number, boolean, or null",
1386
+ );
1387
+ }
1388
+ return [
1389
+ {
1390
+ op: "setFilterDefault",
1391
+ filterId: assertString(subject.args[0], "filter id"),
1392
+ value: value as string | number | boolean | null,
1393
+ },
1394
+ ];
1395
+ }
1396
+
1307
1397
  if (commands.length === 0) {
1308
1398
  throw new Error(`mutation statement has no command: ${statement}`);
1309
1399
  }
@@ -1370,9 +1460,33 @@ function operationsFromStatement(
1370
1460
 
1371
1461
  requirePanelIds(config, panelIds);
1372
1462
 
1373
- return commands.flatMap((command) =>
1374
- operationFromPanelCommand(panelIds, command),
1375
- );
1463
+ const operations: DashboardMutationOperation[] = [];
1464
+ for (let index = 0; index < commands.length; index++) {
1465
+ const command = commands[index];
1466
+ if (command.name !== "duplicate") {
1467
+ operations.push(...operationFromPanelCommand(panelIds, command));
1468
+ continue;
1469
+ }
1470
+ if (panelIds.length !== 1) {
1471
+ throw new Error("duplicate requires exactly one selected panel");
1472
+ }
1473
+ const placement = commands[index + 1];
1474
+ if (placement && index + 1 !== commands.length - 1) {
1475
+ throw new Error("duplicate accepts at most one placement method");
1476
+ }
1477
+ operations.push({
1478
+ op: "duplicatePanel",
1479
+ panelId: panelIds[0],
1480
+ newPanelId: assertString(command.args[0], "newPanelId"),
1481
+ patch:
1482
+ command.args[1] === undefined
1483
+ ? undefined
1484
+ : assertObject(command.args[1], "duplicate patch"),
1485
+ ...(placement ? targetFromChainCall(placement) : {}),
1486
+ });
1487
+ if (placement) index++;
1488
+ }
1489
+ return operations;
1376
1490
  }
1377
1491
 
1378
1492
  export function parseDashboardMutationScript(
@@ -85,6 +85,11 @@ const mutationOperationSchema = z.discriminatedUnion("op", [
85
85
  op: z.literal("setDashboard"),
86
86
  patch: z.record(z.string(), z.unknown()),
87
87
  }),
88
+ z.object({
89
+ op: z.literal("setFilterDefault"),
90
+ filterId: z.string().min(1),
91
+ value: z.union([z.string(), z.number(), z.boolean(), z.null()]),
92
+ }),
88
93
  ]);
89
94
 
90
95
  function parseJsonArrayString(
@@ -112,19 +117,41 @@ function parseJsonArrayString(
112
117
  const operationsInputSchema = z
113
118
  .union([
114
119
  z.array(mutationOperationSchema),
115
- z.string().transform((value) => parseJsonArrayString(value, "operations")),
120
+ z.string().transform((value) => {
121
+ const trimmed = value.trim();
122
+ return trimmed ? parseJsonArrayString(trimmed, "operations") : undefined;
123
+ }),
116
124
  ])
117
125
  .optional();
118
126
 
127
+ function nonEmptyCode(value: string | undefined): string | undefined {
128
+ return value?.trim() ? value : undefined;
129
+ }
130
+
131
+ function nonEmptyOperations(
132
+ value: DashboardMutationOperation[] | undefined,
133
+ ): DashboardMutationOperation[] | undefined {
134
+ return value && value.length > 0 ? value : undefined;
135
+ }
136
+
119
137
  const apiHelp =
120
138
  "Constrained TypeScript-like dashboard mutation script. The server parses only calls on `dashboard`; it does not execute arbitrary JavaScript. " +
121
139
  "No variables, imports, loops, functions, templates, network, filesystem, or DB access. Arguments must be JSON-compatible literals, so quote object keys. " +
122
- "Subjects: dashboard.set, dashboard.panel, dashboard.panels, dashboard.panelsMatching, dashboard.section, dashboard.insertPanel. " +
123
- "Selection methods: moveToTop, moveToBottom, moveBefore, moveAfter, moveToIndex, moveNextTo, moveToRow, remove, set, setTitle, setSql, setWidth, setConfig, setConfigPath, duplicate. " +
140
+ "Subjects: dashboard.set, dashboard.setFilterDefault, dashboard.panel, dashboard.panels, dashboard.panelsMatching, dashboard.section, dashboard.insertPanel. " +
141
+ 'For a simple default-filter change, use `dashboard.setFilterDefault("emailFilter","exclude_builder");`; it verifies the filter and option value without resending every filter or revalidating unchanged panel SQL. ' +
142
+ 'Selection methods: moveToTop, moveToBottom, moveBefore, moveAfter, moveToIndex, moveNextTo, moveToRow, remove, set, setTitle, setSql, setWidth, setConfig, setConfigPath, duplicate. Duplicate supports one chained placement method, for example `dashboard.panel("source").duplicate("copy", {"chartType":"bar"}).nextTo("source");`. ' +
124
143
  "Inserted panels support atTop, atBottom, before, after, atIndex, nextTo, atRow, atRowStart, and atRowEnd. Use nextTo(panelId) or atRow(rowNumber) for visible row placement. " +
125
144
  "AI-generated first-party panels are dashboard-time-bound by default: set config.timeScope to dashboard and include a matching dashboard time filter in SQL. Allowed values are dashboard, fixed-window, cohort-history, and all-time; use all-time only when the user requests full available history and put all-time, lifetime, or historical in the title or description. A {{timeRange}} token requires the timeRange select filter; {{<id>Start}}/{{<id>End}} require a matching date-range filter. Server validation rejects unbound first-party SQL. " +
126
145
  `Examples: ${DASHBOARD_MUTATION_EXAMPLES.slice(0, 5).join(" ")}`;
127
146
 
147
+ const agentInputSchema = z.object({
148
+ dashboardId: z
149
+ .string()
150
+ .min(1)
151
+ .describe("Dashboard id, e.g. 'agent-native-templates-first-party'."),
152
+ code: z.string().min(1).describe(apiHelp),
153
+ });
154
+
128
155
  function resolveScope() {
129
156
  const orgId = getRequestOrgId() || null;
130
157
  const email = getRequestUserEmail();
@@ -162,17 +189,52 @@ async function syncToCollab(
162
189
  }
163
190
  }
164
191
 
165
- function mutationCanChangePanelSql(op: DashboardMutationOperation): boolean {
166
- if (op.op === "insertPanel" || op.op === "duplicatePanel") return true;
167
- if (op.op === "setDashboard") {
168
- return Object.keys(op.patch).some((key) =>
169
- ["filters", "variables"].includes(key),
170
- );
192
+ function sqlValidationScope(
193
+ operations: DashboardMutationOperation[],
194
+ ): ReadonlySet<string> | "all" | null {
195
+ const panelIds = new Set<string>();
196
+ for (const op of operations) {
197
+ if (op.op === "setDashboard") {
198
+ if (
199
+ Object.keys(op.patch).some((key) =>
200
+ ["filters", "variables", "panels"].includes(key),
201
+ )
202
+ ) {
203
+ return "all";
204
+ }
205
+ continue;
206
+ }
207
+ if (op.op === "insertPanel") {
208
+ if (typeof op.panel.id === "string") panelIds.add(op.panel.id);
209
+ continue;
210
+ }
211
+ if (op.op === "duplicatePanel") {
212
+ panelIds.add(op.newPanelId);
213
+ continue;
214
+ }
215
+ if (op.op === "updatePanelPath") {
216
+ panelIds.add(op.panelId);
217
+ continue;
218
+ }
219
+ if (
220
+ op.op === "updatePanel" &&
221
+ Object.keys(op.patch).some((key) =>
222
+ ["sql", "source", "chartType", "config"].includes(key),
223
+ )
224
+ ) {
225
+ panelIds.add(op.panelId);
226
+ }
171
227
  }
172
- if (op.op !== "updatePanel") return false;
173
- return Object.keys(op.patch).some((key) =>
174
- ["sql", "source", "chartType"].includes(key),
175
- );
228
+ return panelIds.size > 0 ? panelIds : null;
229
+ }
230
+
231
+ async function validateMutationSql(
232
+ config: Record<string, unknown>,
233
+ operations: DashboardMutationOperation[],
234
+ ): Promise<string | null> {
235
+ const scope = sqlValidationScope(operations);
236
+ if (scope === null) return null;
237
+ return validatePanelSql(config, scope === "all" ? undefined : scope);
176
238
  }
177
239
 
178
240
  function movedPanelIdsFrom(operations: DashboardMutationOperation[]): string[] {
@@ -214,7 +276,7 @@ export default defineAction({
214
276
  code: z.string().optional().describe(apiHelp),
215
277
  operations: operationsInputSchema.describe(
216
278
  "Structured equivalent of the typed script. Native callers should pass an array of mutation ops; shell/legacy callers may pass a JSON string. " +
217
- "Supported ops: movePanels, removePanels, updatePanel, updatePanelPath, insertPanel, duplicatePanel, setDashboard.",
279
+ "Supported ops: movePanels, removePanels, updatePanel, updatePanelPath, insertPanel, duplicatePanel, setDashboard, setFilterDefault.",
218
280
  ),
219
281
  dryRun: z
220
282
  .boolean()
@@ -233,6 +295,7 @@ export default defineAction({
233
295
  .optional()
234
296
  .describe("If true, include the allowed TypeScript API and examples."),
235
297
  }),
298
+ agentInputSchema,
236
299
  http: { method: "POST" },
237
300
  mcpApp: {
238
301
  compactCatalog: true,
@@ -245,18 +308,18 @@ export default defineAction({
245
308
  }),
246
309
  },
247
310
  run: async (args) => {
311
+ const code = nonEmptyCode(args.code);
312
+ const requestedOperations = nonEmptyOperations(args.operations);
248
313
  const wantsHelpOnly =
249
314
  args.returnTypes === true &&
250
315
  !args.dashboardId &&
251
316
  !args.id &&
252
- !args.code &&
253
- !args.operations;
317
+ !code &&
318
+ !requestedOperations;
254
319
  if (wantsHelpOnly) return helpResult();
255
320
 
256
321
  const dashboardId = resolveDashboardId(args);
257
- const suppliedModes = [args.code, args.operations].filter(
258
- (value) => value !== undefined,
259
- ).length;
322
+ const suppliedModes = [code, requestedOperations].filter(Boolean).length;
260
323
  if (suppliedModes === 0) {
261
324
  throw new Error("provide `code` or `operations`.");
262
325
  }
@@ -282,9 +345,9 @@ export default defineAction({
282
345
  );
283
346
  }
284
347
  const nextRoot = cloneConfig(existing.config as Record<string, unknown>);
285
- const nextOperations = args.operations
286
- ? (args.operations as DashboardMutationOperation[])
287
- : parseDashboardMutationScript(nextRoot, args.code!);
348
+ const nextOperations = requestedOperations
349
+ ? requestedOperations
350
+ : parseDashboardMutationScript(nextRoot, code!);
288
351
  const nextMutation = applyDashboardMutationOperations(
289
352
  nextRoot,
290
353
  nextOperations,
@@ -313,20 +376,19 @@ export default defineAction({
313
376
  root = computed.nextRoot;
314
377
  operations = computed.nextOperations;
315
378
  mutation = computed.nextMutation;
316
- if (operations.some(mutationCanChangePanelSql)) {
317
- const sqlError = await validatePanelSql(root);
318
- if (sqlError) throw new Error(sqlError);
319
- }
379
+ const sqlError = await validateMutationSql(root, operations);
380
+ if (sqlError) throw new Error(sqlError);
320
381
  } else {
321
382
  const saved = await upsertDashboardWithRetry(
322
383
  dashboardId,
323
384
  ctx,
324
385
  async (existing) => {
325
386
  const computed = computeMutation(existing);
326
- if (computed.nextOperations.some(mutationCanChangePanelSql)) {
327
- const sqlError = await validatePanelSql(computed.nextRoot);
328
- if (sqlError) throw new Error(sqlError);
329
- }
387
+ const sqlError = await validateMutationSql(
388
+ computed.nextRoot,
389
+ computed.nextOperations,
390
+ );
391
+ if (sqlError) throw new Error(sqlError);
330
392
  root = computed.nextRoot;
331
393
  operations = computed.nextOperations;
332
394
  mutation = computed.nextMutation;
@@ -387,19 +387,19 @@ export function validateDashboardConfig(
387
387
  return null;
388
388
  }
389
389
 
390
- /**
391
- * Dry-run each BigQuery panel's SQL so bad column names or type
392
- * mismatches fail here, with the full BigQuery error text, rather than
393
- * silently saving a broken dashboard that crashes on render.
394
- */
390
+ /** Validate every query panel, or only the supplied ids for a targeted edit. */
395
391
  export async function validatePanelSql(
396
392
  config: Record<string, unknown>,
393
+ panelIds?: ReadonlySet<string>,
397
394
  ): Promise<string | null> {
398
395
  const panels = config.panels;
399
396
  if (!Array.isArray(panels)) return null;
400
397
  const vars = buildDryRunVars(config);
401
398
  for (let i = 0; i < panels.length; i++) {
402
399
  const p = panels[i] as Record<string, unknown>;
400
+ if (panelIds && (typeof p.id !== "string" || !panelIds.has(p.id))) {
401
+ continue;
402
+ }
403
403
  // Sections are layout-only and extensions render their own iframe — neither
404
404
  // has SQL to dry-run. heatmap, callout, and other query panels still
405
405
  // validate normally below.