@agent-native/core 0.91.2 → 0.92.1

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 (538) hide show
  1. package/corpus/README.md +2 -2
  2. package/corpus/core/CHANGELOG.md +31 -0
  3. package/corpus/core/docs/content/faq.mdx +17 -0
  4. package/corpus/core/docs/content/notifications.mdx +12 -6
  5. package/corpus/core/package.json +1 -1
  6. package/corpus/core/src/agent/production-agent.ts +140 -46
  7. package/corpus/core/src/agent/tool-search.ts +71 -4
  8. package/corpus/core/src/application-state/store.ts +12 -1
  9. package/corpus/core/src/cli/index.ts +20 -0
  10. package/corpus/core/src/cli/upgrade.ts +798 -0
  11. package/corpus/core/src/client/AssistantChat.tsx +28 -15
  12. package/corpus/core/src/client/HighlightedCodeBlock.tsx +20 -3
  13. package/corpus/core/src/client/PoweredByBadge.tsx +1 -8
  14. package/corpus/core/src/client/agent-chat-adapter.ts +68 -16
  15. package/corpus/core/src/client/chat/message-components.tsx +85 -8
  16. package/corpus/core/src/client/chat/tool-call-display.tsx +355 -144
  17. package/corpus/core/src/client/chat/widgets/DataTableWidget.tsx +52 -1
  18. package/corpus/core/src/client/code-agent-chat-adapter.ts +2 -9
  19. package/corpus/core/src/client/db-admin/TableEditor.tsx +49 -0
  20. package/corpus/core/src/client/db-admin/export-utils.ts +13 -4
  21. package/corpus/core/src/client/db-admin/useAgentSync.ts +72 -0
  22. package/corpus/core/src/client/error-capture.ts +69 -7
  23. package/corpus/core/src/client/extensions/EmbeddedExtension.tsx +5 -1
  24. package/corpus/core/src/client/extensions/ExtensionViewer.tsx +53 -8
  25. package/corpus/core/src/client/extensions/InlineExtensionFrame.tsx +5 -1
  26. package/corpus/core/src/client/extensions/portable-extension.ts +1 -0
  27. package/corpus/core/src/client/org/OrgSwitcher.tsx +12 -9
  28. package/corpus/core/src/client/org/TeamPage.tsx +77 -71
  29. package/corpus/core/src/client/session-replay.ts +3 -97
  30. package/corpus/core/src/client/settings/SettingsPanel.tsx +738 -441
  31. package/corpus/core/src/client/settings/SettingsSection.tsx +161 -17
  32. package/corpus/core/src/client/settings/SettingsTabsPage.tsx +25 -9
  33. package/corpus/core/src/client/sse-event-processor.ts +29 -2
  34. package/corpus/core/src/db-admin/agent-tools.ts +8 -2
  35. package/corpus/core/src/db-admin/operations.ts +116 -4
  36. package/corpus/core/src/db-admin/routes.ts +1 -0
  37. package/corpus/core/src/db-admin/types.ts +4 -0
  38. package/corpus/core/src/extensions/actions.ts +113 -5
  39. package/corpus/core/src/extensions/html-shell.ts +5 -4
  40. package/corpus/core/src/extensions/routes.ts +10 -0
  41. package/corpus/core/src/navigation/index.ts +1 -1
  42. package/corpus/core/src/notifications/channels.ts +88 -25
  43. package/corpus/core/src/notifications/registry.ts +17 -3
  44. package/corpus/core/src/notifications/types.ts +4 -1
  45. package/corpus/core/src/resources/handlers.ts +10 -8
  46. package/corpus/core/src/server/agent-chat-plugin.ts +7 -3
  47. package/corpus/core/src/server/poll.ts +293 -8
  48. package/corpus/core/src/server/request-context.ts +7 -0
  49. package/corpus/core/src/styles/agent-conversation.css +1 -1
  50. package/corpus/core/src/styles/agent-native.css +27 -0
  51. package/corpus/core/src/templates/default/.agents/skills/actions/SKILL.md +5 -0
  52. package/corpus/core/src/templates/default/.agents/skills/adding-a-feature/SKILL.md +5 -0
  53. package/corpus/core/src/templates/default/.agents/skills/real-time-sync/SKILL.md +1 -1
  54. package/corpus/core/src/templates/default/.agents/skills/security/SKILL.md +7 -0
  55. package/corpus/core/src/templates/default/.agents/skills/self-modifying-code/SKILL.md +20 -2
  56. package/corpus/core/src/templates/default/.agents/skills/storing-data/SKILL.md +5 -1
  57. package/corpus/core/src/templates/default/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
  58. package/corpus/core/src/templates/default/AGENTS.md +14 -5
  59. package/corpus/core/src/templates/default/package.json +2 -1
  60. package/corpus/core/src/templates/headless/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
  61. package/corpus/core/src/templates/headless/AGENTS.md +13 -3
  62. package/corpus/core/src/templates/headless/package.json +1 -0
  63. package/corpus/core/src/templates/workspace-core/.agents/skills/actions/SKILL.md +5 -0
  64. package/corpus/core/src/templates/workspace-core/.agents/skills/adding-a-feature/SKILL.md +5 -0
  65. package/corpus/core/src/templates/workspace-core/.agents/skills/context-awareness/SKILL.md +4 -0
  66. package/corpus/core/src/templates/workspace-core/.agents/skills/extensions/SKILL.md +6 -0
  67. package/corpus/core/src/templates/workspace-core/.agents/skills/performance/SKILL.md +4 -0
  68. package/corpus/core/src/templates/workspace-core/.agents/skills/real-time-sync/SKILL.md +1 -1
  69. package/corpus/core/src/templates/workspace-core/.agents/skills/security/SKILL.md +7 -0
  70. package/corpus/core/src/templates/workspace-core/.agents/skills/self-modifying-code/SKILL.md +20 -2
  71. package/corpus/core/src/templates/workspace-core/.agents/skills/storing-data/SKILL.md +5 -1
  72. package/corpus/core/src/templates/workspace-core/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
  73. package/corpus/core/src/templates/workspace-core/AGENTS.md +7 -1
  74. package/corpus/core/src/templates/workspace-root/AGENTS.md +17 -5
  75. package/corpus/core/src/templates/workspace-root/package.json +1 -0
  76. package/corpus/templates/analytics/.agents/skills/actions/SKILL.md +5 -0
  77. package/corpus/templates/analytics/.agents/skills/dashboard-management/SKILL.md +10 -0
  78. package/corpus/templates/analytics/.agents/skills/real-time-sync/SKILL.md +1 -1
  79. package/corpus/templates/analytics/.agents/skills/security/SKILL.md +7 -0
  80. package/corpus/templates/analytics/.agents/skills/self-modifying-code/SKILL.md +20 -2
  81. package/corpus/templates/analytics/.agents/skills/session-replay/SKILL.md +5 -6
  82. package/corpus/templates/analytics/.agents/skills/storing-data/SKILL.md +5 -1
  83. package/corpus/templates/analytics/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
  84. package/corpus/templates/analytics/AGENTS.md +39 -18
  85. package/corpus/templates/analytics/actions/capture-test-error.ts +4 -0
  86. package/corpus/templates/analytics/actions/get-analytics-alert-rule-defaults.ts +23 -0
  87. package/corpus/templates/analytics/actions/get-error-issue.ts +1 -1
  88. package/corpus/templates/analytics/actions/list-analysis-revisions.ts +40 -0
  89. package/corpus/templates/analytics/actions/list-dashboard-revisions.ts +40 -0
  90. package/corpus/templates/analytics/actions/list-dashboard-usage-stats.ts +299 -0
  91. package/corpus/templates/analytics/actions/navigate.ts +4 -2
  92. package/corpus/templates/analytics/actions/restore-analysis-revision.ts +43 -0
  93. package/corpus/templates/analytics/actions/restore-dashboard-revision.ts +68 -0
  94. package/corpus/templates/analytics/actions/save-analytics-alert-rule.ts +14 -0
  95. package/corpus/templates/analytics/actions/save-monitor.ts +15 -1
  96. package/corpus/templates/analytics/actions/view-screen.ts +24 -0
  97. package/corpus/templates/analytics/app/components/analysis/AnalysisHistoryPanel.tsx +181 -0
  98. package/corpus/templates/analytics/app/components/dashboard/DashboardHistoryPanel.tsx +184 -0
  99. package/corpus/templates/analytics/app/components/dashboard/DataTable.tsx +41 -6
  100. package/corpus/templates/analytics/app/components/dashboard/SqlChart.tsx +122 -11
  101. package/corpus/templates/analytics/app/components/layout/CommandPalette.tsx +22 -16
  102. package/corpus/templates/analytics/app/components/layout/Header.tsx +1 -1
  103. package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +27 -21
  104. package/corpus/templates/analytics/app/hooks/use-analysis-revisions.ts +43 -0
  105. package/corpus/templates/analytics/app/hooks/use-dashboard-chat-context.ts +110 -0
  106. package/corpus/templates/analytics/app/hooks/use-dashboard-revisions.ts +43 -0
  107. package/corpus/templates/analytics/app/hooks/use-navigation-state.ts +8 -3
  108. package/corpus/templates/analytics/app/i18n/zh-TW.ts +64 -2
  109. package/corpus/templates/analytics/app/i18n-data.ts +783 -3
  110. package/corpus/templates/analytics/app/pages/Agents.tsx +359 -19
  111. package/corpus/templates/analytics/app/pages/Settings.tsx +3 -2
  112. package/corpus/templates/analytics/app/pages/adhoc/explorer-dashboard/index.tsx +34 -1
  113. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/index.tsx +28 -0
  114. package/corpus/templates/analytics/app/pages/analyses/AnalysisDetail.tsx +18 -1
  115. package/corpus/templates/analytics/app/pages/monitoring/ErrorsPanel.tsx +7 -10
  116. package/corpus/templates/analytics/app/pages/monitoring/MonitoringPage.tsx +8 -2
  117. package/corpus/templates/analytics/app/pages/monitoring/errors/IssueDetail.tsx +479 -23
  118. package/corpus/templates/analytics/app/pages/monitoring/errors/IssueList.tsx +0 -9
  119. package/corpus/templates/analytics/app/pages/monitoring/errors/i18n.ts +11 -0
  120. package/corpus/templates/analytics/app/pages/monitoring/errors/types.ts +9 -1
  121. package/corpus/templates/analytics/app/pages/monitoring/uptime/MonitorFormPage.tsx +157 -35
  122. package/corpus/templates/analytics/app/pages/monitoring/uptime/i18n.ts +17 -2
  123. package/corpus/templates/analytics/app/pages/monitoring/uptime/types.ts +4 -0
  124. package/corpus/templates/analytics/app/pages/sessions/SessionDetailPage.tsx +80 -220
  125. package/corpus/templates/analytics/app/pages/sessions/SessionsPage.tsx +9 -99
  126. package/corpus/templates/analytics/app/pages/settings/AlertRulesSettingsCard.tsx +262 -104
  127. package/corpus/templates/analytics/app/routes/team.tsx +1 -1
  128. package/corpus/templates/analytics/changelog/2026-07-08-admins-can-audit-dashboard-usage-ownership-and-cleanup-signa.md +6 -0
  129. package/corpus/templates/analytics/changelog/2026-07-08-agent-monitoring-stays-available-to-non-admins.md +6 -0
  130. package/corpus/templates/analytics/changelog/2026-07-08-alert-rules-are-easier-to-scan-expand-and-edit-from-settings.md +6 -0
  131. package/corpus/templates/analytics/changelog/2026-07-08-analytics-alert-forms-remember-last-email-recipients.md +6 -0
  132. package/corpus/templates/analytics/changelog/2026-07-08-analytics-alert-rules-can-now-use-per-rule-slack-and-webhook.md +6 -0
  133. package/corpus/templates/analytics/changelog/2026-07-08-dashboard-history-and-chat-context.md +5 -0
  134. package/corpus/templates/analytics/changelog/2026-07-08-dashboard-tables-keep-their-size-while-loading.md +6 -0
  135. package/corpus/templates/analytics/changelog/2026-07-08-dashboard-usage-now-counts-explorer-dashboard-traffic.md +6 -0
  136. package/corpus/templates/analytics/changelog/2026-07-08-demo-mode-session-emails-are-filtered-and-anonymized.md +6 -0
  137. package/corpus/templates/analytics/changelog/2026-07-08-error-issue-detail-adds-stack-traces-and-frequency-bars.md +6 -0
  138. package/corpus/templates/analytics/changelog/2026-07-08-error-issue-detail-now-shows-the-latest-occurrence-message-a.md +6 -0
  139. package/corpus/templates/analytics/changelog/2026-07-08-monitoring-errors-only-show-test-action-when-empty.md +6 -0
  140. package/corpus/templates/analytics/changelog/2026-07-08-monitoring-uptime-and-errors-tabs-now-clearly-show-which-view-is-active.md +6 -0
  141. package/corpus/templates/analytics/changelog/2026-07-08-production-session-replay-now-requires-private-blob-storage-.md +6 -0
  142. package/corpus/templates/analytics/changelog/2026-07-08-session-replay-uses-stock-rrweb-sizing-again-so-recorded.md +6 -0
  143. package/corpus/templates/analytics/changelog/2026-07-08-shared-extension-links-now-show-a-clear-message-when-you-do-.md +6 -0
  144. package/corpus/templates/analytics/changelog/2026-07-08-sidebar-dashboard-menus-now-open-above-the-dashboard-canvas.md +6 -0
  145. package/corpus/templates/analytics/changelog/2026-07-08-team-settings-show-access-controls-next-to-member-lists.md +6 -0
  146. package/corpus/templates/analytics/changelog/2026-07-08-uptime-alerting-clarifies-in-app-inbox-vs-email-and-lets-you-paste-slack-or-webhook-urls-per-monitor.md +6 -0
  147. package/corpus/templates/analytics/changelog/2026-07-08-uptime-monitors-now-use-a-10-second-request-timeout-by-defau.md +6 -0
  148. package/corpus/templates/analytics/docs/uptime-monitoring.md +13 -11
  149. package/corpus/templates/analytics/server/db/schema-monitoring.ts +5 -1
  150. package/corpus/templates/analytics/server/db/schema.ts +56 -0
  151. package/corpus/templates/analytics/server/lib/analytics-alerts.ts +92 -0
  152. package/corpus/templates/analytics/server/lib/dashboards-store.ts +334 -5
  153. package/corpus/templates/analytics/server/lib/error-capture.ts +231 -36
  154. package/corpus/templates/analytics/server/lib/session-replay.ts +114 -8
  155. package/corpus/templates/analytics/server/lib/uptime-monitors.ts +65 -16
  156. package/corpus/templates/analytics/server/plugins/db.ts +122 -2
  157. package/corpus/templates/analytics/server/routes/api/dashboard-agent-context.json.get.ts +1 -0
  158. package/corpus/templates/assets/.agents/skills/actions/SKILL.md +5 -0
  159. package/corpus/templates/assets/.agents/skills/real-time-sync/SKILL.md +1 -1
  160. package/corpus/templates/assets/.agents/skills/security/SKILL.md +7 -0
  161. package/corpus/templates/assets/.agents/skills/self-modifying-code/SKILL.md +20 -2
  162. package/corpus/templates/assets/.agents/skills/storing-data/SKILL.md +5 -1
  163. package/corpus/templates/assets/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
  164. package/corpus/templates/assets/AGENTS.md +4 -0
  165. package/corpus/templates/assets/app/routes/settings.tsx +1 -1
  166. package/corpus/templates/assets/app/routes/team.tsx +1 -1
  167. package/corpus/templates/brain/.agents/skills/actions/SKILL.md +5 -0
  168. package/corpus/templates/brain/.agents/skills/adding-a-feature/SKILL.md +5 -0
  169. package/corpus/templates/brain/.agents/skills/real-time-sync/SKILL.md +1 -1
  170. package/corpus/templates/brain/.agents/skills/security/SKILL.md +7 -0
  171. package/corpus/templates/brain/.agents/skills/self-modifying-code/SKILL.md +20 -2
  172. package/corpus/templates/brain/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
  173. package/corpus/templates/brain/AGENTS.md +4 -0
  174. package/corpus/templates/brain/app/routes/team.tsx +1 -1
  175. package/corpus/templates/calendar/.agents/skills/actions/SKILL.md +5 -0
  176. package/corpus/templates/calendar/.agents/skills/real-time-sync/SKILL.md +1 -1
  177. package/corpus/templates/calendar/.agents/skills/security/SKILL.md +7 -0
  178. package/corpus/templates/calendar/.agents/skills/self-modifying-code/SKILL.md +20 -2
  179. package/corpus/templates/calendar/.agents/skills/storing-data/SKILL.md +5 -1
  180. package/corpus/templates/calendar/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
  181. package/corpus/templates/calendar/AGENTS.md +4 -0
  182. package/corpus/templates/calendar/app/components/calendar/DayView.tsx +11 -2
  183. package/corpus/templates/calendar/app/components/calendar/EventDetailPopover.tsx +21 -8
  184. package/corpus/templates/calendar/app/components/calendar/MonthView.tsx +7 -1
  185. package/corpus/templates/calendar/app/components/calendar/WeekView.tsx +11 -2
  186. package/corpus/templates/calendar/app/lib/popover-click-guard.ts +48 -4
  187. package/corpus/templates/calendar/app/pages/Settings.tsx +1 -1
  188. package/corpus/templates/calendar/app/routes/_app.team.tsx +1 -1
  189. package/corpus/templates/calendar/changelog/2026-07-08-clicking-empty-calendar-space-closes-an-open-event-popover-b.md +6 -0
  190. package/corpus/templates/chat/.agents/skills/actions/SKILL.md +5 -0
  191. package/corpus/templates/chat/.agents/skills/adding-a-feature/SKILL.md +5 -0
  192. package/corpus/templates/chat/.agents/skills/real-time-sync/SKILL.md +1 -1
  193. package/corpus/templates/chat/.agents/skills/security/SKILL.md +7 -0
  194. package/corpus/templates/chat/.agents/skills/self-modifying-code/SKILL.md +20 -2
  195. package/corpus/templates/chat/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
  196. package/corpus/templates/chat/AGENTS.md +4 -0
  197. package/corpus/templates/chat/app/hooks/use-navigation-state.ts +1 -1
  198. package/corpus/templates/chat/app/routes/settings.tsx +2 -2
  199. package/corpus/templates/chat/app/routes/team.tsx +1 -1
  200. package/corpus/templates/clips/.agents/skills/actions/SKILL.md +5 -0
  201. package/corpus/templates/clips/.agents/skills/security/SKILL.md +7 -0
  202. package/corpus/templates/clips/.agents/skills/self-modifying-code/SKILL.md +20 -2
  203. package/corpus/templates/clips/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
  204. package/corpus/templates/clips/AGENTS.md +4 -0
  205. package/corpus/templates/clips/actions/finalize-recording.ts +9 -3
  206. package/corpus/templates/clips/actions/set-thumbnail.ts +11 -2
  207. package/corpus/templates/clips/app/components/meetings/canvas-editor.tsx +1 -7
  208. package/corpus/templates/clips/app/components/player/player-controls.tsx +21 -13
  209. package/corpus/templates/clips/app/components/player/video-player.tsx +30 -75
  210. package/corpus/templates/clips/app/i18n/ar-SA.ts +6 -5
  211. package/corpus/templates/clips/app/i18n/de-DE.ts +6 -6
  212. package/corpus/templates/clips/app/i18n/en-US.ts +6 -5
  213. package/corpus/templates/clips/app/i18n/es-ES.ts +6 -5
  214. package/corpus/templates/clips/app/i18n/fr-FR.ts +6 -6
  215. package/corpus/templates/clips/app/i18n/hi-IN.ts +6 -5
  216. package/corpus/templates/clips/app/i18n/ja-JP.ts +6 -5
  217. package/corpus/templates/clips/app/i18n/ko-KR.ts +6 -5
  218. package/corpus/templates/clips/app/i18n/pt-BR.ts +6 -5
  219. package/corpus/templates/clips/app/i18n/zh-CN.ts +6 -5
  220. package/corpus/templates/clips/app/i18n/zh-TW.ts +6 -5
  221. package/corpus/templates/clips/app/routes/_app.meetings.$meetingId.tsx +51 -118
  222. package/corpus/templates/clips/changelog/2026-07-08-desktop-meeting-notes-stay-active-from-tray-and-shortcut-controls.md +6 -0
  223. package/corpus/templates/clips/changelog/2026-07-08-desktop-meeting-popovers-can-start-notes-and-join-the-meetin.md +6 -0
  224. package/corpus/templates/clips/changelog/2026-07-08-hosted-clip-uploads-now-clear-failed-buffered-chunks.md +6 -0
  225. package/corpus/templates/clips/changelog/2026-07-08-hosted-recording-uploads-now-avoid-sql-chunk-storage.md +6 -0
  226. package/corpus/templates/clips/changelog/2026-07-08-meeting-notes-keep-their-recording-state-when-the-desktop.md +6 -0
  227. package/corpus/templates/clips/changelog/2026-07-08-meeting-recaps-now-keep-summaries-action-items-and-transcrip.md +6 -0
  228. package/corpus/templates/clips/changelog/2026-07-08-meeting-reminder-dropdowns-now-expand-fully-instead-of-being.md +6 -0
  229. package/corpus/templates/clips/changelog/2026-07-08-video-playback-controls-now-match-loom-style-5-second-skips-.md +6 -0
  230. package/corpus/templates/clips/desktop/src/app.tsx +123 -3
  231. package/corpus/templates/clips/desktop/src/hooks/useMeetingTranscription.ts +15 -1
  232. package/corpus/templates/clips/desktop/src/overlays/meeting-notification.tsx +23 -0
  233. package/corpus/templates/clips/desktop/src/styles.css +23 -1
  234. package/corpus/templates/clips/desktop/src-tauri/src/adhoc_meetings_watcher.rs +1 -3
  235. package/corpus/templates/clips/desktop/src-tauri/src/clips/mod.rs +40 -6
  236. package/corpus/templates/clips/desktop/src-tauri/src/lib.rs +4 -2
  237. package/corpus/templates/clips/desktop/src-tauri/src/meetings_watcher.rs +3 -5
  238. package/corpus/templates/clips/desktop/src-tauri/src/native_screen.rs +23 -19
  239. package/corpus/templates/clips/desktop/src-tauri/src/shortcuts.rs +3 -3
  240. package/corpus/templates/clips/desktop/src-tauri/src/silence_detector.rs +0 -1
  241. package/corpus/templates/clips/desktop/src-tauri/src/state.rs +5 -0
  242. package/corpus/templates/clips/desktop/src-tauri/src/tray.rs +18 -6
  243. package/corpus/templates/clips/server/lib/recording-upload-state.ts +63 -0
  244. package/corpus/templates/clips/server/lib/video-storage.ts +4 -0
  245. package/corpus/templates/clips/server/routes/api/recordings/[recordingId]/thumbnail.post.ts +19 -13
  246. package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/chunk.post.ts +40 -1
  247. package/corpus/templates/content/.agents/skills/actions/SKILL.md +5 -0
  248. package/corpus/templates/content/.agents/skills/real-time-sync/SKILL.md +1 -1
  249. package/corpus/templates/content/.agents/skills/security/SKILL.md +7 -0
  250. package/corpus/templates/content/.agents/skills/self-modifying-code/SKILL.md +20 -2
  251. package/corpus/templates/content/.agents/skills/storing-data/SKILL.md +5 -1
  252. package/corpus/templates/content/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
  253. package/corpus/templates/content/AGENTS.md +4 -0
  254. package/corpus/templates/content/actions/_batch-utils.ts +8 -0
  255. package/corpus/templates/content/actions/_builder-cms-read-client.ts +7 -5
  256. package/corpus/templates/content/actions/_database-source-utils.ts +776 -319
  257. package/corpus/templates/content/actions/_database-utils.ts +6 -1
  258. package/corpus/templates/content/actions/_property-utils.ts +168 -0
  259. package/corpus/templates/content/actions/add-content-database-source-field-property.ts +19 -12
  260. package/corpus/templates/content/actions/bind-content-database-source-field.ts +19 -12
  261. package/corpus/templates/content/actions/delete-document.ts +9 -13
  262. package/corpus/templates/content/actions/refresh-content-database-source.ts +5 -5
  263. package/corpus/templates/content/app/components/editor/body-hydration.ts +35 -11
  264. package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +47 -5
  265. package/corpus/templates/content/app/hooks/use-documents.ts +8 -2
  266. package/corpus/templates/content/app/routes/_app.settings.tsx +2 -2
  267. package/corpus/templates/content/app/routes/_app.team.tsx +1 -1
  268. package/corpus/templates/content/changelog/2026-07-08-builder-source-sync-now-completes-reliably-on-hosted-databases.md +6 -0
  269. package/corpus/templates/content/changelog/2026-07-08-fixed-builder-database-sync-so-large-sources-continue-past-t.md +6 -0
  270. package/corpus/templates/content/server/plugins/db.ts +19 -0
  271. package/corpus/templates/design/.agents/skills/actions/SKILL.md +5 -0
  272. package/corpus/templates/design/.agents/skills/security/SKILL.md +7 -0
  273. package/corpus/templates/design/.agents/skills/self-modifying-code/SKILL.md +20 -2
  274. package/corpus/templates/design/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
  275. package/corpus/templates/design/AGENTS.md +4 -0
  276. package/corpus/templates/design/actions/take-design-screenshot.ts +12 -9
  277. package/corpus/templates/design/app/components/design/inspector/ImageFillControls.tsx +57 -13
  278. package/corpus/templates/design/app/routes/team.tsx +1 -1
  279. package/corpus/templates/design/changelog/2026-07-08-local-images-added-to-designs-now-upload-to-file-storage-ins.md +6 -0
  280. package/corpus/templates/dispatch/.agents/skills/actions/SKILL.md +5 -0
  281. package/corpus/templates/dispatch/.agents/skills/security/SKILL.md +7 -0
  282. package/corpus/templates/dispatch/.agents/skills/self-modifying-code/SKILL.md +20 -2
  283. package/corpus/templates/dispatch/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
  284. package/corpus/templates/dispatch/AGENTS.md +4 -0
  285. package/corpus/templates/dispatch/app/hooks/use-navigation-state.ts +1 -1
  286. package/corpus/templates/dispatch/app/routes/settings.tsx +2 -2
  287. package/corpus/templates/dispatch/app/routes/team.tsx +1 -1
  288. package/corpus/templates/forms/.agents/skills/actions/SKILL.md +5 -0
  289. package/corpus/templates/forms/.agents/skills/real-time-sync/SKILL.md +1 -1
  290. package/corpus/templates/forms/.agents/skills/security/SKILL.md +7 -0
  291. package/corpus/templates/forms/.agents/skills/self-modifying-code/SKILL.md +20 -2
  292. package/corpus/templates/forms/.agents/skills/storing-data/SKILL.md +5 -1
  293. package/corpus/templates/forms/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
  294. package/corpus/templates/forms/AGENTS.md +4 -0
  295. package/corpus/templates/forms/app/routes/_app.settings.tsx +2 -2
  296. package/corpus/templates/forms/app/routes/_app.team.tsx +1 -1
  297. package/corpus/templates/forms/shared/navigation.ts +1 -1
  298. package/corpus/templates/macros/.agents/skills/security/SKILL.md +7 -0
  299. package/corpus/templates/macros/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
  300. package/corpus/templates/macros/AGENTS.md +4 -0
  301. package/corpus/templates/macros/app/routes/settings.tsx +2 -2
  302. package/corpus/templates/macros/app/routes/team.tsx +1 -1
  303. package/corpus/templates/mail/.agents/skills/actions/SKILL.md +5 -0
  304. package/corpus/templates/mail/.agents/skills/email-drafts/SKILL.md +1 -1
  305. package/corpus/templates/mail/.agents/skills/real-time-sync/SKILL.md +1 -1
  306. package/corpus/templates/mail/.agents/skills/security/SKILL.md +7 -0
  307. package/corpus/templates/mail/.agents/skills/self-modifying-code/SKILL.md +20 -2
  308. package/corpus/templates/mail/.agents/skills/storing-data/SKILL.md +5 -1
  309. package/corpus/templates/mail/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
  310. package/corpus/templates/mail/AGENTS.md +4 -0
  311. package/corpus/templates/mail/changelog/2026-07-08-mail-attachments-in-hosted-environments-now-require-file-sto.md +6 -0
  312. package/corpus/templates/mail/server/handlers/media.ts +26 -1
  313. package/corpus/templates/mail/server/lib/outgoing-email.ts +24 -1
  314. package/corpus/templates/mail/server/lib/upload-store.ts +2 -1
  315. package/corpus/templates/plan/.agents/skills/actions/SKILL.md +5 -0
  316. package/corpus/templates/plan/.agents/skills/adding-a-feature/SKILL.md +5 -0
  317. package/corpus/templates/plan/.agents/skills/real-time-sync/SKILL.md +1 -1
  318. package/corpus/templates/plan/.agents/skills/security/SKILL.md +7 -0
  319. package/corpus/templates/plan/.agents/skills/self-modifying-code/SKILL.md +20 -2
  320. package/corpus/templates/plan/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
  321. package/corpus/templates/plan/AGENTS.md +4 -0
  322. package/corpus/templates/plan/app/hooks/use-navigation-state.ts +1 -1
  323. package/corpus/templates/plan/app/routes/settings.tsx +2 -2
  324. package/corpus/templates/plan/app/routes/team.tsx +1 -1
  325. package/corpus/templates/plan/changelog/2026-07-08-hosted-plan-images-now-require-connected-storage.md +6 -0
  326. package/corpus/templates/plan/server/lib/plan-assets.ts +33 -4
  327. package/corpus/templates/slides/.agents/skills/actions/SKILL.md +5 -0
  328. package/corpus/templates/slides/.agents/skills/security/SKILL.md +7 -0
  329. package/corpus/templates/slides/.agents/skills/self-modifying-code/SKILL.md +20 -2
  330. package/corpus/templates/slides/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
  331. package/corpus/templates/slides/AGENTS.md +4 -0
  332. package/corpus/templates/slides/actions/generate-image-api.ts +15 -3
  333. package/corpus/templates/slides/app/routes/settings.tsx +2 -2
  334. package/corpus/templates/slides/app/routes/team.tsx +1 -1
  335. package/corpus/templates/slides/changelog/2026-07-08-generated-slide-images-now-return-hosted-file-storage-urls-i.md +6 -0
  336. package/corpus/templates/slides/shared/api.ts +1 -1
  337. package/corpus/templates/videos/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
  338. package/corpus/templates/voice/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
  339. package/dist/agent/production-agent.d.ts +5 -1
  340. package/dist/agent/production-agent.d.ts.map +1 -1
  341. package/dist/agent/production-agent.js +112 -42
  342. package/dist/agent/production-agent.js.map +1 -1
  343. package/dist/agent/tool-search.d.ts +2 -0
  344. package/dist/agent/tool-search.d.ts.map +1 -1
  345. package/dist/agent/tool-search.js +60 -4
  346. package/dist/agent/tool-search.js.map +1 -1
  347. package/dist/application-state/store.d.ts.map +1 -1
  348. package/dist/application-state/store.js +8 -2
  349. package/dist/application-state/store.js.map +1 -1
  350. package/dist/cli/index.js +19 -0
  351. package/dist/cli/index.js.map +1 -1
  352. package/dist/cli/upgrade.d.ts +100 -0
  353. package/dist/cli/upgrade.d.ts.map +1 -0
  354. package/dist/cli/upgrade.js +678 -0
  355. package/dist/cli/upgrade.js.map +1 -0
  356. package/dist/client/AssistantChat.d.ts.map +1 -1
  357. package/dist/client/AssistantChat.js +25 -14
  358. package/dist/client/AssistantChat.js.map +1 -1
  359. package/dist/client/HighlightedCodeBlock.d.ts +2 -0
  360. package/dist/client/HighlightedCodeBlock.d.ts.map +1 -1
  361. package/dist/client/HighlightedCodeBlock.js +10 -1
  362. package/dist/client/HighlightedCodeBlock.js.map +1 -1
  363. package/dist/client/PoweredByBadge.d.ts +1 -1
  364. package/dist/client/PoweredByBadge.d.ts.map +1 -1
  365. package/dist/client/PoweredByBadge.js +3 -9
  366. package/dist/client/PoweredByBadge.js.map +1 -1
  367. package/dist/client/agent-chat-adapter.d.ts.map +1 -1
  368. package/dist/client/agent-chat-adapter.js +60 -13
  369. package/dist/client/agent-chat-adapter.js.map +1 -1
  370. package/dist/client/chat/message-components.d.ts.map +1 -1
  371. package/dist/client/chat/message-components.js +61 -8
  372. package/dist/client/chat/message-components.js.map +1 -1
  373. package/dist/client/chat/tool-call-display.d.ts +12 -0
  374. package/dist/client/chat/tool-call-display.d.ts.map +1 -1
  375. package/dist/client/chat/tool-call-display.js +136 -42
  376. package/dist/client/chat/tool-call-display.js.map +1 -1
  377. package/dist/client/chat/widgets/DataTableWidget.d.ts.map +1 -1
  378. package/dist/client/chat/widgets/DataTableWidget.js +19 -2
  379. package/dist/client/chat/widgets/DataTableWidget.js.map +1 -1
  380. package/dist/client/code-agent-chat-adapter.js +2 -9
  381. package/dist/client/code-agent-chat-adapter.js.map +1 -1
  382. package/dist/client/db-admin/TableEditor.d.ts.map +1 -1
  383. package/dist/client/db-admin/TableEditor.js +19 -2
  384. package/dist/client/db-admin/TableEditor.js.map +1 -1
  385. package/dist/client/db-admin/export-utils.d.ts +2 -0
  386. package/dist/client/db-admin/export-utils.d.ts.map +1 -1
  387. package/dist/client/db-admin/export-utils.js +11 -3
  388. package/dist/client/db-admin/export-utils.js.map +1 -1
  389. package/dist/client/db-admin/useAgentSync.d.ts.map +1 -1
  390. package/dist/client/db-admin/useAgentSync.js +63 -0
  391. package/dist/client/db-admin/useAgentSync.js.map +1 -1
  392. package/dist/client/error-capture.d.ts.map +1 -1
  393. package/dist/client/error-capture.js +41 -7
  394. package/dist/client/error-capture.js.map +1 -1
  395. package/dist/client/extensions/EmbeddedExtension.d.ts.map +1 -1
  396. package/dist/client/extensions/EmbeddedExtension.js +3 -1
  397. package/dist/client/extensions/EmbeddedExtension.js.map +1 -1
  398. package/dist/client/extensions/ExtensionViewer.d.ts.map +1 -1
  399. package/dist/client/extensions/ExtensionViewer.js +32 -5
  400. package/dist/client/extensions/ExtensionViewer.js.map +1 -1
  401. package/dist/client/extensions/InlineExtensionFrame.d.ts.map +1 -1
  402. package/dist/client/extensions/InlineExtensionFrame.js +3 -1
  403. package/dist/client/extensions/InlineExtensionFrame.js.map +1 -1
  404. package/dist/client/extensions/portable-extension.d.ts.map +1 -1
  405. package/dist/client/extensions/portable-extension.js +1 -0
  406. package/dist/client/extensions/portable-extension.js.map +1 -1
  407. package/dist/client/org/OrgSwitcher.d.ts +1 -1
  408. package/dist/client/org/OrgSwitcher.d.ts.map +1 -1
  409. package/dist/client/org/OrgSwitcher.js +11 -6
  410. package/dist/client/org/OrgSwitcher.js.map +1 -1
  411. package/dist/client/org/TeamPage.d.ts.map +1 -1
  412. package/dist/client/org/TeamPage.js +5 -5
  413. package/dist/client/org/TeamPage.js.map +1 -1
  414. package/dist/client/session-replay.d.ts +0 -8
  415. package/dist/client/session-replay.d.ts.map +1 -1
  416. package/dist/client/session-replay.js +3 -80
  417. package/dist/client/session-replay.js.map +1 -1
  418. package/dist/client/settings/SettingsPanel.d.ts.map +1 -1
  419. package/dist/client/settings/SettingsPanel.js +89 -33
  420. package/dist/client/settings/SettingsPanel.js.map +1 -1
  421. package/dist/client/settings/SettingsSection.d.ts +19 -4
  422. package/dist/client/settings/SettingsSection.d.ts.map +1 -1
  423. package/dist/client/settings/SettingsSection.js +33 -4
  424. package/dist/client/settings/SettingsSection.js.map +1 -1
  425. package/dist/client/settings/SettingsTabsPage.d.ts.map +1 -1
  426. package/dist/client/settings/SettingsTabsPage.js +21 -10
  427. package/dist/client/settings/SettingsTabsPage.js.map +1 -1
  428. package/dist/client/sse-event-processor.d.ts +9 -0
  429. package/dist/client/sse-event-processor.d.ts.map +1 -1
  430. package/dist/client/sse-event-processor.js +20 -2
  431. package/dist/client/sse-event-processor.js.map +1 -1
  432. package/dist/db-admin/agent-tools.d.ts.map +1 -1
  433. package/dist/db-admin/agent-tools.js +7 -2
  434. package/dist/db-admin/agent-tools.js.map +1 -1
  435. package/dist/db-admin/operations.d.ts.map +1 -1
  436. package/dist/db-admin/operations.js +90 -4
  437. package/dist/db-admin/operations.js.map +1 -1
  438. package/dist/db-admin/routes.d.ts.map +1 -1
  439. package/dist/db-admin/routes.js +1 -0
  440. package/dist/db-admin/routes.js.map +1 -1
  441. package/dist/db-admin/types.d.ts +4 -0
  442. package/dist/db-admin/types.d.ts.map +1 -1
  443. package/dist/db-admin/types.js.map +1 -1
  444. package/dist/extensions/actions.d.ts.map +1 -1
  445. package/dist/extensions/actions.js +85 -5
  446. package/dist/extensions/actions.js.map +1 -1
  447. package/dist/extensions/html-shell.d.ts +5 -4
  448. package/dist/extensions/html-shell.d.ts.map +1 -1
  449. package/dist/extensions/html-shell.js.map +1 -1
  450. package/dist/extensions/routes.d.ts.map +1 -1
  451. package/dist/extensions/routes.js +8 -0
  452. package/dist/extensions/routes.js.map +1 -1
  453. package/dist/navigation/index.d.ts +1 -1
  454. package/dist/navigation/index.d.ts.map +1 -1
  455. package/dist/navigation/index.js +1 -1
  456. package/dist/navigation/index.js.map +1 -1
  457. package/dist/notifications/channels.d.ts +8 -3
  458. package/dist/notifications/channels.d.ts.map +1 -1
  459. package/dist/notifications/channels.js +61 -22
  460. package/dist/notifications/channels.js.map +1 -1
  461. package/dist/notifications/registry.d.ts.map +1 -1
  462. package/dist/notifications/registry.js +14 -3
  463. package/dist/notifications/registry.js.map +1 -1
  464. package/dist/notifications/types.d.ts +4 -1
  465. package/dist/notifications/types.d.ts.map +1 -1
  466. package/dist/notifications/types.js.map +1 -1
  467. package/dist/resources/handlers.d.ts +5 -0
  468. package/dist/resources/handlers.d.ts.map +1 -1
  469. package/dist/resources/handlers.js +9 -8
  470. package/dist/resources/handlers.js.map +1 -1
  471. package/dist/server/agent-chat-plugin.d.ts +5 -1
  472. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  473. package/dist/server/agent-chat-plugin.js +2 -2
  474. package/dist/server/agent-chat-plugin.js.map +1 -1
  475. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  476. package/dist/server/poll.d.ts +12 -4
  477. package/dist/server/poll.d.ts.map +1 -1
  478. package/dist/server/poll.js +236 -9
  479. package/dist/server/poll.js.map +1 -1
  480. package/dist/server/request-context.d.ts +7 -0
  481. package/dist/server/request-context.d.ts.map +1 -1
  482. package/dist/server/request-context.js.map +1 -1
  483. package/dist/styles/agent-conversation.css +1 -1
  484. package/dist/styles/agent-native.css +27 -0
  485. package/dist/templates/default/.agents/skills/actions/SKILL.md +5 -0
  486. package/dist/templates/default/.agents/skills/adding-a-feature/SKILL.md +5 -0
  487. package/dist/templates/default/.agents/skills/real-time-sync/SKILL.md +1 -1
  488. package/dist/templates/default/.agents/skills/security/SKILL.md +7 -0
  489. package/dist/templates/default/.agents/skills/self-modifying-code/SKILL.md +20 -2
  490. package/dist/templates/default/.agents/skills/storing-data/SKILL.md +5 -1
  491. package/dist/templates/default/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
  492. package/dist/templates/default/AGENTS.md +14 -5
  493. package/dist/templates/default/package.json +2 -1
  494. package/dist/templates/headless/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
  495. package/dist/templates/headless/AGENTS.md +13 -3
  496. package/dist/templates/headless/package.json +1 -0
  497. package/dist/templates/workspace-core/.agents/skills/actions/SKILL.md +5 -0
  498. package/dist/templates/workspace-core/.agents/skills/adding-a-feature/SKILL.md +5 -0
  499. package/dist/templates/workspace-core/.agents/skills/context-awareness/SKILL.md +4 -0
  500. package/dist/templates/workspace-core/.agents/skills/extensions/SKILL.md +6 -0
  501. package/dist/templates/workspace-core/.agents/skills/performance/SKILL.md +4 -0
  502. package/dist/templates/workspace-core/.agents/skills/real-time-sync/SKILL.md +1 -1
  503. package/dist/templates/workspace-core/.agents/skills/security/SKILL.md +7 -0
  504. package/dist/templates/workspace-core/.agents/skills/self-modifying-code/SKILL.md +20 -2
  505. package/dist/templates/workspace-core/.agents/skills/storing-data/SKILL.md +5 -1
  506. package/dist/templates/workspace-core/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
  507. package/dist/templates/workspace-core/AGENTS.md +7 -1
  508. package/dist/templates/workspace-root/AGENTS.md +17 -5
  509. package/dist/templates/workspace-root/package.json +1 -0
  510. package/docs/content/faq.mdx +17 -0
  511. package/docs/content/notifications.mdx +12 -6
  512. package/package.json +2 -2
  513. package/src/templates/default/.agents/skills/actions/SKILL.md +5 -0
  514. package/src/templates/default/.agents/skills/adding-a-feature/SKILL.md +5 -0
  515. package/src/templates/default/.agents/skills/real-time-sync/SKILL.md +1 -1
  516. package/src/templates/default/.agents/skills/security/SKILL.md +7 -0
  517. package/src/templates/default/.agents/skills/self-modifying-code/SKILL.md +20 -2
  518. package/src/templates/default/.agents/skills/storing-data/SKILL.md +5 -1
  519. package/src/templates/default/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
  520. package/src/templates/default/AGENTS.md +14 -5
  521. package/src/templates/default/package.json +2 -1
  522. package/src/templates/headless/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
  523. package/src/templates/headless/AGENTS.md +13 -3
  524. package/src/templates/headless/package.json +1 -0
  525. package/src/templates/workspace-core/.agents/skills/actions/SKILL.md +5 -0
  526. package/src/templates/workspace-core/.agents/skills/adding-a-feature/SKILL.md +5 -0
  527. package/src/templates/workspace-core/.agents/skills/context-awareness/SKILL.md +4 -0
  528. package/src/templates/workspace-core/.agents/skills/extensions/SKILL.md +6 -0
  529. package/src/templates/workspace-core/.agents/skills/performance/SKILL.md +4 -0
  530. package/src/templates/workspace-core/.agents/skills/real-time-sync/SKILL.md +1 -1
  531. package/src/templates/workspace-core/.agents/skills/security/SKILL.md +7 -0
  532. package/src/templates/workspace-core/.agents/skills/self-modifying-code/SKILL.md +20 -2
  533. package/src/templates/workspace-core/.agents/skills/storing-data/SKILL.md +5 -1
  534. package/src/templates/workspace-core/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
  535. package/src/templates/workspace-core/AGENTS.md +7 -1
  536. package/src/templates/workspace-root/AGENTS.md +17 -5
  537. package/src/templates/workspace-root/package.json +1 -0
  538. package/corpus/templates/analytics/changelog/2026-07-08-session-replay-clamps-ultra-wide-viewports-while-keeping-the.md +0 -6
@@ -3,6 +3,7 @@ import type { ActionRunContext } from "../action.js";
3
3
  import type { ActionEntry } from "../agent/production-agent.js";
4
4
  import type { AgentChatAttachment } from "../agent/types.js";
5
5
  import { writeAppState } from "../application-state/script-helpers.js";
6
+ import { getRequestRunContext } from "../server/request-context.js";
6
7
  import { resolveAccess } from "../sharing/access.js";
7
8
  import type {
8
9
  ExtensionContentEdit,
@@ -38,6 +39,8 @@ import {
38
39
  unhideExtension,
39
40
  updateExtension,
40
41
  updateExtensionContent,
42
+ type ExtensionHistoryDetail,
43
+ type ExtensionHistoryEntry,
41
44
  type ExtensionRow,
42
45
  } from "./store.js";
43
46
 
@@ -126,7 +129,7 @@ export function createExtensionActionEntries(): Record<string, ActionEntry> {
126
129
  "get-extension": {
127
130
  tool: {
128
131
  description:
129
- "Get one existing extension by id. Use this when <current-screen> or <current-url> contains extensionId for the current extension; do not call list-extensions just to rediscover that id. Defaults to including the full Alpine.js content so you can make a targeted update-extension edit.",
132
+ "Get one existing extension by id. Use this when <current-screen> or <current-url> contains extensionId for the current extension; do not call list-extensions just to rediscover that id. Defaults to including the full Alpine.js content once per run so you can make a targeted update-extension edit; repeated unchanged reads return compact metadata unless forceContent=true.",
130
133
  parameters: {
131
134
  type: "object",
132
135
  properties: {
@@ -140,6 +143,11 @@ export function createExtensionActionEntries(): Record<string, ActionEntry> {
140
143
  description:
141
144
  "Include full Alpine.js content. Defaults to true for targeted edits.",
142
145
  },
146
+ forceContent: {
147
+ type: "boolean",
148
+ description:
149
+ "Return full content even if this run already read the same unchanged body. Use sparingly; prefer update-extension edits after the first read.",
150
+ },
143
151
  },
144
152
  required: ["id"],
145
153
  },
@@ -151,14 +159,16 @@ export function createExtensionActionEntries(): Record<string, ActionEntry> {
151
159
  args?.includeContent === undefined
152
160
  ? true
153
161
  : coerceBoolean(args.includeContent);
162
+ const forceContent = coerceBoolean(args?.forceContent);
154
163
  const localExtension = await getLocalExtension(id);
155
164
  if (localExtension) {
156
165
  return {
157
166
  ok: true,
158
- extension: await summarizeExtension(
167
+ extension: await summarizeExtensionForAgentRead(
159
168
  localExtension,
160
169
  new Set(),
161
170
  includeContent,
171
+ forceContent,
162
172
  ),
163
173
  };
164
174
  }
@@ -167,10 +177,11 @@ export function createExtensionActionEntries(): Record<string, ActionEntry> {
167
177
  const hiddenIds = await getHiddenExtensionIdsForCurrentUser();
168
178
  return {
169
179
  ok: true,
170
- extension: await summarizeExtension(
180
+ extension: await summarizeExtensionForAgentRead(
171
181
  extension,
172
182
  hiddenIds,
173
183
  includeContent,
184
+ forceContent,
174
185
  ),
175
186
  };
176
187
  },
@@ -223,7 +234,7 @@ export function createExtensionActionEntries(): Record<string, ActionEntry> {
223
234
  "get-extension-history-version": {
224
235
  tool: {
225
236
  description:
226
- "Get one extension history version with its previous-version diff. Use after list-extension-history when the user wants to inspect exactly what changed.",
237
+ "Get one extension history version with its previous-version diff. Use after list-extension-history when the user wants to inspect exactly what changed. Full HTML bodies are omitted by default; set includeContent=true only when restoring or manually comparing full source.",
227
238
  parameters: {
228
239
  type: "object",
229
240
  properties: {
@@ -235,6 +246,11 @@ export function createExtensionActionEntries(): Record<string, ActionEntry> {
235
246
  type: "number",
236
247
  description: "History version number to inspect.",
237
248
  },
249
+ includeContent: {
250
+ type: "boolean",
251
+ description:
252
+ "Include full HTML for the current and previous versions. Defaults to false to keep agent context compact.",
253
+ },
238
254
  },
239
255
  required: ["id", "version"],
240
256
  },
@@ -252,7 +268,13 @@ export function createExtensionActionEntries(): Record<string, ActionEntry> {
252
268
  if (!detail) {
253
269
  return `Error: extension history version not found: ${id}#${version}`;
254
270
  }
255
- return { ok: true, ...detail };
271
+ return {
272
+ ok: true,
273
+ ...compactExtensionHistoryDetail(
274
+ detail,
275
+ coerceBoolean(args?.includeContent),
276
+ ),
277
+ };
256
278
  },
257
279
  readOnly: true,
258
280
  },
@@ -1059,11 +1081,97 @@ async function summarizeExtension(
1059
1081
  hiddenBy: row.hiddenBy,
1060
1082
  createdAt: row.createdAt,
1061
1083
  updatedAt: row.updatedAt,
1084
+ contentLength: row.content.length,
1085
+ contentHash: contentFingerprint(row.content),
1062
1086
  ...(local ? { source: row.source } : {}),
1063
1087
  ...(includeContent ? { content: row.content } : {}),
1064
1088
  };
1065
1089
  }
1066
1090
 
1091
+ async function summarizeExtensionForAgentRead(
1092
+ row: ExtensionRow | LocalExtensionRow,
1093
+ hiddenIds: Set<string>,
1094
+ includeContent: boolean,
1095
+ forceContent: boolean,
1096
+ ) {
1097
+ if (!includeContent) {
1098
+ return summarizeExtension(row, hiddenIds, false);
1099
+ }
1100
+
1101
+ const fingerprint = contentFingerprint(row.content);
1102
+ const runCtx = getRequestRunContext();
1103
+ const reads = runCtx ? (runCtx.extensionContentReads ??= {}) : undefined;
1104
+ const alreadySent = !forceContent && reads?.[row.id] === fingerprint;
1105
+ if (!alreadySent && reads) {
1106
+ reads[row.id] = fingerprint;
1107
+ }
1108
+
1109
+ const summary = await summarizeExtension(row, hiddenIds, !alreadySent);
1110
+ if (!alreadySent) return summary;
1111
+
1112
+ return {
1113
+ ...summary,
1114
+ contentOmitted: {
1115
+ reason: "unchanged-content-already-returned-this-run",
1116
+ contentHash: fingerprint,
1117
+ contentLength: row.content.length,
1118
+ next: "Use the content already returned earlier in this run and call update-extension with focused edits/patches. Set forceContent=true only if you truly need the full body again.",
1119
+ },
1120
+ };
1121
+ }
1122
+
1123
+ function compactExtensionHistoryDetail(
1124
+ detail: ExtensionHistoryDetail,
1125
+ includeContent: boolean,
1126
+ ): ExtensionHistoryDetail & {
1127
+ diffOmitted?: { omittedLines: number; maxLines: number };
1128
+ } {
1129
+ const diffMaxLines = 400;
1130
+ const fullDiff = detail.diff ?? [];
1131
+ const diff =
1132
+ fullDiff.length > diffMaxLines
1133
+ ? [...fullDiff.slice(0, 200), ...fullDiff.slice(fullDiff.length - 200)]
1134
+ : fullDiff;
1135
+ return {
1136
+ ...detail,
1137
+ entry: compactHistoryEntry(detail.entry, includeContent),
1138
+ previous: detail.previous
1139
+ ? compactHistoryEntry(detail.previous, includeContent)
1140
+ : null,
1141
+ diff,
1142
+ ...(fullDiff.length > diff.length
1143
+ ? {
1144
+ diffOmitted: {
1145
+ omittedLines: fullDiff.length - diff.length,
1146
+ maxLines: diffMaxLines,
1147
+ },
1148
+ }
1149
+ : {}),
1150
+ };
1151
+ }
1152
+
1153
+ function compactHistoryEntry(
1154
+ entry: ExtensionHistoryEntry,
1155
+ includeContent: boolean,
1156
+ ): ExtensionHistoryEntry & { contentHash?: string } {
1157
+ const content = entry.content ?? "";
1158
+ const withHash = {
1159
+ ...entry,
1160
+ ...(content ? { contentHash: contentFingerprint(content) } : {}),
1161
+ };
1162
+ if (includeContent) return withHash;
1163
+ const { content: _content, ...withoutContent } = withHash;
1164
+ return withoutContent;
1165
+ }
1166
+
1167
+ function contentFingerprint(content: string): string {
1168
+ let hash = 5381;
1169
+ for (let i = 0; i < content.length; i++) {
1170
+ hash = (hash * 33) ^ content.charCodeAt(i);
1171
+ }
1172
+ return `${content.length.toString(36)}-${(hash >>> 0).toString(36)}`;
1173
+ }
1174
+
1067
1175
  async function localExtensionEditMessage(id: string): Promise<string | null> {
1068
1176
  const localExtension = await getLocalExtension(id);
1069
1177
  if (!localExtension) return null;
@@ -24,10 +24,11 @@ export const EXTENSION_IFRAME_META_CSP = EXTENSION_IFRAME_CSP_BASE;
24
24
  *
25
25
  * 1. The iframe MUST be rendered with a `sandbox` attribute that does NOT
26
26
  * include `allow-same-origin`. The viewer (`ExtensionViewer.tsx`,
27
- * `EmbeddedExtension.tsx`) sets `sandbox="allow-scripts allow-forms"` —
28
- * and that is the only acceptable shape. Adding `allow-same-origin`
29
- * would give the extension full DOM access to the parent window via
30
- * cross-frame script.
27
+ * `EmbeddedExtension.tsx`) normalizes the sandbox through
28
+ * `normalizeAgentNativeExtensionSandbox()`, which permits scripts, forms,
29
+ * popups, and downloads but strips `allow-same-origin`. Adding
30
+ * `allow-same-origin` would give the extension full DOM access to the
31
+ * parent window via cross-frame script.
31
32
  *
32
33
  * 2. Every reachable parent action must treat the postMessage payload as
33
34
  * hostile. The bridge in `iframe-bridge.ts` enforces a path allowlist,
@@ -107,6 +107,8 @@ export function createExtensionsHandler() {
107
107
  });
108
108
  }
109
109
 
110
+ const MAX_EXTENSION_DATA_BYTES = 1024 * 1024;
111
+
110
112
  function normalizeExtensionUserEmail(email: string): string {
111
113
  return email.trim().toLowerCase();
112
114
  }
@@ -544,6 +546,14 @@ async function handleExtensionDataUpsert(
544
546
  const itemId = String(body.id || randomUUID());
545
547
  const data =
546
548
  typeof body.data === "string" ? body.data : JSON.stringify(body.data);
549
+ if (Buffer.byteLength(data, "utf8") > MAX_EXTENSION_DATA_BYTES) {
550
+ setResponseStatus(event, 413);
551
+ return {
552
+ error:
553
+ "Extension data is too large for SQL storage. Store large files, base64, or blobs in file storage and save only a URL or handle.",
554
+ maxBytes: MAX_EXTENSION_DATA_BYTES,
555
+ };
556
+ }
547
557
  const now = new Date().toISOString();
548
558
  const scope = body.scope === "org" ? "org" : "user";
549
559
  const orgId = getRequestOrgId();
@@ -15,7 +15,7 @@ export const STANDARD_SETTINGS_TABS = {
15
15
  providers: "providers",
16
16
  connections: "connections",
17
17
  secrets: "secrets",
18
- team: "team",
18
+ team: "organization",
19
19
  usage: "usage",
20
20
  language: "language",
21
21
  whatsNew: "whats-new",
@@ -1,17 +1,22 @@
1
1
  /**
2
2
  * Built-in notification channels.
3
3
  *
4
- * Set environment variables to auto-register the webhook channel at startup.
4
+ * Webhook and Slack are always registered. Delivery uses (in order):
5
+ * 1. per-notification `metadata.webhookUrl` / `metadata.slackWebhookUrl`
6
+ * 2. the matching `NOTIFICATIONS_*` env URL (workspace default)
7
+ * If neither is set, that channel no-ops for the emission.
8
+ *
5
9
  * Extra channels can be registered at any time via
6
10
  * `registerNotificationChannel()` from a server plugin.
7
11
  *
8
- * NOTIFICATIONS_WEBHOOK_URL → POST notifications as JSON to this URL.
12
+ * NOTIFICATIONS_WEBHOOK_URL → default POST JSON URL when metadata omits one.
9
13
  * Supports `${keys.NAME}` substitution — the raw
10
14
  * value never enters the agent context.
11
15
  * NOTIFICATIONS_WEBHOOK_AUTH → optional `Authorization` header value (also
12
16
  * supports `${keys.NAME}`).
13
17
  * NOTIFICATIONS_SLACK_WEBHOOK_URL
14
- * → POST notifications to a Slack incoming webhook.
18
+ * → default Slack incoming webhook when metadata
19
+ * omits `slackWebhookUrl`.
15
20
  * Supports `${keys.NAME}` substitution.
16
21
  * NOTIFICATIONS_EMAIL_CHANNEL=1
17
22
  * → enable the built-in email channel for
@@ -30,7 +35,7 @@ import {
30
35
  } from "../secrets/substitution.js";
31
36
  import { sendEmail } from "../server/email.js";
32
37
  import { registerNotificationChannel } from "./registry.js";
33
- import type { NotificationChannel } from "./types.js";
38
+ import type { NotificationChannel, NotificationInput } from "./types.js";
34
39
 
35
40
  let _registered = false;
36
41
 
@@ -38,30 +43,38 @@ export function registerBuiltinNotificationChannels(): void {
38
43
  if (_registered) return;
39
44
  _registered = true;
40
45
 
41
- const url = process.env.NOTIFICATIONS_WEBHOOK_URL;
42
- if (url) {
43
- registerNotificationChannel(createWebhookChannel(url));
44
- }
45
-
46
- const slackUrl = process.env.NOTIFICATIONS_SLACK_WEBHOOK_URL;
47
- if (slackUrl) {
48
- registerNotificationChannel(createSlackWebhookChannel(slackUrl));
49
- }
50
-
51
- const emailRecipients = process.env.NOTIFICATIONS_EMAIL_RECIPIENTS?.trim();
52
- if (process.env.NOTIFICATIONS_EMAIL_CHANNEL === "1" || emailRecipients) {
53
- registerNotificationChannel(createEmailChannel());
54
- }
46
+ registerNotificationChannel(
47
+ createWebhookChannel(process.env.NOTIFICATIONS_WEBHOOK_URL),
48
+ );
49
+ registerNotificationChannel(
50
+ createSlackWebhookChannel(process.env.NOTIFICATIONS_SLACK_WEBHOOK_URL),
51
+ );
52
+ // Email is always registered so per-notification `metadata.emailRecipients`
53
+ // work without a workspace-wide env flag (same pattern as webhook/slack).
54
+ registerNotificationChannel(createEmailChannel());
55
55
  }
56
56
 
57
- function createWebhookChannel(urlTemplate: string): NotificationChannel {
57
+ function createWebhookChannel(
58
+ envUrlTemplate: string | undefined,
59
+ ): NotificationChannel {
58
60
  const authTemplate = process.env.NOTIFICATIONS_WEBHOOK_AUTH;
59
61
  return {
60
62
  name: "webhook",
61
63
  async deliver(input, meta) {
64
+ const overrideUrlTemplate = deliveryMetadataString(
65
+ input.metadata,
66
+ "webhookUrl",
67
+ );
68
+ const urlTemplate =
69
+ overrideUrlTemplate ??
70
+ metadataString(input.metadata, "webhookUrl") ??
71
+ envUrlTemplate?.trim();
72
+ // No-op when neither a per-notification nor workspace URL is set —
73
+ // mirrors email's empty-recipients behavior so notify-all stays quiet.
74
+ if (!urlTemplate) return false;
62
75
  const { url, headers } = await resolveWebhookRequest(
63
76
  urlTemplate,
64
- authTemplate,
77
+ overrideUrlTemplate ? undefined : authTemplate,
65
78
  meta.owner,
66
79
  "webhook",
67
80
  );
@@ -74,7 +87,7 @@ function createWebhookChannel(urlTemplate: string): NotificationChannel {
74
87
  severity: input.severity,
75
88
  title: input.title,
76
89
  body: input.body,
77
- metadata: input.metadata,
90
+ metadata: scrubDeliveryMetadata(input.metadata),
78
91
  owner: meta.owner,
79
92
  emittedAt: new Date().toISOString(),
80
93
  }),
@@ -92,14 +105,25 @@ function createWebhookChannel(urlTemplate: string): NotificationChannel {
92
105
  };
93
106
  }
94
107
 
95
- function createSlackWebhookChannel(urlTemplate: string): NotificationChannel {
108
+ function createSlackWebhookChannel(
109
+ envUrlTemplate: string | undefined,
110
+ ): NotificationChannel {
96
111
  const authTemplate = process.env.NOTIFICATIONS_SLACK_WEBHOOK_AUTH;
97
112
  return {
98
113
  name: "slack",
99
114
  async deliver(input, meta) {
115
+ const overrideUrlTemplate = deliveryMetadataString(
116
+ input.metadata,
117
+ "slackWebhookUrl",
118
+ );
119
+ const urlTemplate =
120
+ overrideUrlTemplate ??
121
+ metadataString(input.metadata, "slackWebhookUrl") ??
122
+ envUrlTemplate?.trim();
123
+ if (!urlTemplate) return false;
100
124
  const { url, headers } = await resolveWebhookRequest(
101
125
  urlTemplate,
102
- authTemplate,
126
+ overrideUrlTemplate ? undefined : authTemplate,
103
127
  meta.owner,
104
128
  "Slack webhook",
105
129
  );
@@ -159,7 +183,7 @@ function createEmailChannel(): NotificationChannel {
159
183
  name: "email",
160
184
  async deliver(input) {
161
185
  const recipients = notificationEmailRecipients(input.metadata);
162
- if (recipients.length === 0) return;
186
+ if (recipients.length === 0) return false;
163
187
  const subject =
164
188
  typeof input.metadata?.emailSubject === "string" &&
165
189
  input.metadata.emailSubject.trim()
@@ -240,6 +264,41 @@ async function resolveWebhookRequest(
240
264
  return { url, headers };
241
265
  }
242
266
 
267
+ function metadataString(
268
+ metadata: NotificationInput["metadata"],
269
+ key: string,
270
+ ): string | undefined {
271
+ const value = metadata?.[key];
272
+ if (typeof value !== "string") return undefined;
273
+ const trimmed = value.trim();
274
+ return trimmed || undefined;
275
+ }
276
+
277
+ function deliveryMetadataString(
278
+ metadata: NotificationInput["metadata"],
279
+ key: string,
280
+ ): string | undefined {
281
+ const delivery = metadata?.delivery;
282
+ if (!delivery || typeof delivery !== "object" || Array.isArray(delivery)) {
283
+ return undefined;
284
+ }
285
+ const value = (delivery as Record<string, unknown>)[key];
286
+ if (typeof value !== "string") return undefined;
287
+ const trimmed = value.trim();
288
+ return trimmed || undefined;
289
+ }
290
+
291
+ function scrubDeliveryMetadata(
292
+ metadata: Record<string, unknown> | undefined,
293
+ ): Record<string, unknown> | undefined {
294
+ if (!metadata) return undefined;
295
+ const entries = Object.entries(metadata).filter(
296
+ ([key]) =>
297
+ key !== "delivery" && key !== "webhookUrl" && key !== "slackWebhookUrl",
298
+ );
299
+ return entries.length ? Object.fromEntries(entries) : undefined;
300
+ }
301
+
243
302
  function notificationEmailRecipients(
244
303
  metadata: Record<string, unknown> | undefined,
245
304
  ): string[] {
@@ -275,7 +334,11 @@ function scrubEmailMetadata(
275
334
  ): Record<string, unknown> | null {
276
335
  if (!metadata) return null;
277
336
  const entries = Object.entries(metadata).filter(
278
- ([key]) => key !== "emailRecipients" && key !== "emailSubject",
337
+ ([key]) =>
338
+ key !== "emailRecipients" &&
339
+ key !== "emailSubject" &&
340
+ key !== "webhookUrl" &&
341
+ key !== "slackWebhookUrl",
279
342
  );
280
343
  return entries.length ? Object.fromEntries(entries) : null;
281
344
  }
@@ -105,6 +105,7 @@ export async function notifyWithDelivery(
105
105
  body: truncate(input.body, MAX_BODY_LEN),
106
106
  };
107
107
  const channels = selectChannels(input.channels);
108
+ const storedMetadata = scrubStoredMetadata(input.metadata);
108
109
 
109
110
  // The inbox channel is always included unless explicitly excluded.
110
111
  const runInbox = !input.channels || input.channels.includes("inbox");
@@ -120,7 +121,7 @@ export async function notifyWithDelivery(
120
121
  severity: input.severity,
121
122
  title: input.title,
122
123
  body: input.body,
123
- metadata: input.metadata,
124
+ metadata: storedMetadata,
124
125
  deliveredChannels: ["inbox"],
125
126
  });
126
127
  delivered.push("inbox");
@@ -132,13 +133,15 @@ export async function notifyWithDelivery(
132
133
  // Await every channel so a 500-ing webhook doesn't end up in `delivered`.
133
134
  const results = await Promise.allSettled(
134
135
  channels.map(async (channel) => {
135
- await channel.deliver(input, meta);
136
+ const delivered = await channel.deliver(input, meta);
137
+ // Explicit `false` means the channel skipped (no URL / recipients).
138
+ if (delivered === false) return null;
136
139
  return channel.name;
137
140
  }),
138
141
  );
139
142
  results.forEach((r, i) => {
140
143
  if (r.status === "fulfilled") {
141
- delivered.push(r.value);
144
+ if (r.value) delivered.push(r.value);
142
145
  } else {
143
146
  console.error(
144
147
  `[notifications] channel "${channels[i].name}" failed:`,
@@ -181,6 +184,17 @@ export async function notifyWithDelivery(
181
184
  return { notification: stored, deliveredChannels: delivered };
182
185
  }
183
186
 
187
+ function scrubStoredMetadata(
188
+ metadata: Record<string, unknown> | undefined,
189
+ ): Record<string, unknown> | undefined {
190
+ if (!metadata) return undefined;
191
+ const entries = Object.entries(metadata).filter(
192
+ ([key]) =>
193
+ key !== "delivery" && key !== "webhookUrl" && key !== "slackWebhookUrl",
194
+ );
195
+ return entries.length ? Object.fromEntries(entries) : undefined;
196
+ }
197
+
184
198
  function selectChannels(allowlist?: string[]): NotificationChannel[] {
185
199
  const registry = getRegistry();
186
200
  const all = Array.from(registry.values());
@@ -41,9 +41,12 @@ export interface NotificationChannel {
41
41
  /**
42
42
  * Deliver the notification. Must be best-effort — throwing will be logged
43
43
  * but will not block other channels from running.
44
+ *
45
+ * Return `false` to skip (e.g. no URL / no recipients configured) so the
46
+ * channel is not recorded in `deliveredChannels`.
44
47
  */
45
48
  deliver(
46
49
  input: NotificationInput,
47
50
  meta: NotificationMeta,
48
- ): void | Promise<void>;
51
+ ): void | boolean | Promise<void | boolean>;
49
52
  }
@@ -607,10 +607,9 @@ export async function handleUploadResource(event: any) {
607
607
  }
608
608
  const owner = await resolveOwner(event, shared);
609
609
 
610
- // Prefer a registered file upload provider (e.g. Builder.io) for binary
611
- // assets so we get a real CDN URL instead of a base64 blob in SQL.
612
- // Text resources still live in SQL they're edited inline and benefit
613
- // from the resource store's metadata/search features.
610
+ // Binary assets must live in file storage so resource rows do not become
611
+ // base64 blobs in SQL. Text resources still live in SQL because they are
612
+ // edited inline and benefit from the resource store's metadata/search.
614
613
  const isText =
615
614
  mimeType.startsWith("text/") || mimeType === "application/json";
616
615
 
@@ -638,12 +637,15 @@ export async function handleUploadResource(event: any) {
638
637
  setResponseStatus(event, 201);
639
638
  return { ...resource, url: uploaded.url, provider: uploaded.provider };
640
639
  }
640
+ setResponseStatus(event, 503);
641
+ return {
642
+ error:
643
+ "File storage is not configured. Connect Builder.io or register an S3/R2/GCS file upload provider before uploading binary resources.",
644
+ storageSetupRequired: true,
645
+ };
641
646
  }
642
647
 
643
- // Fallback: store contents in SQL (base64 for binary, text as-is).
644
- const content = isText
645
- ? Buffer.from(filePart.data).toString("utf-8")
646
- : Buffer.from(filePart.data).toString("base64");
648
+ const content = Buffer.from(filePart.data).toString("utf-8");
647
649
 
648
650
  const resource = await resourcePut(owner, path, content, mimeType);
649
651
 
@@ -2739,7 +2739,11 @@ export interface AgentChatPluginOptions {
2739
2739
  * agent starts with only these tools plus `tool-search`; the live registry
2740
2740
  * remains searchable, and matching schemas from `tool-search` results are
2741
2741
  * loaded into the next model request. Use this for domain-focused apps that
2742
- * have a few common actions and many rare framework utilities.
2742
+ * have a few common actions and many rare framework utilities. Common
2743
+ * provider/corpus/code-execution tools are promoted automatically when present
2744
+ * in the current app/mode registry, so broad integration guidance stays
2745
+ * immediately callable without overloading apps that do not expose those
2746
+ * tools.
2743
2747
  */
2744
2748
  initialToolNames?: string[];
2745
2749
  /**
@@ -3127,7 +3131,7 @@ Keep \`create-extension\` payloads compact enough to finish quickly. For complex
3127
3131
 
3128
3132
  Generated UI content can use appAction(), appFetch(), dbQuery(), extensionFetch(), extensionData, agentNative.ui.output(value, opts?), and agentNative.chat.send(...)/sendToAgentChat(...). Use appAction() for app data writes, and dbQuery() only for read-only inspection of known app SQL tables. It can receive chat inputs through slotContext/window.onSlotContext. Use agentNative.ui.output for passive current values from knobs, sliders, selections, and controls; it writes application state at \`inline-ui:<extensionId>:output\` scoped to the inline extension id returned by \`render-inline-extension\` or \`show-extension-inline\`. When the user later says "use that value", "apply the current setting", or similar, read it with \`readAppState("inline-ui:<id>:output")\` instead of asking them to send it again. Use agentNative.chat.send for visible submit/apply actions that should put a message into chat. Transient extensionData is browser-local and not agent-readable, synced, promoted, or garbage-collected; use application_state/appFetch, appAction, ui.output, or chat.send for anything the agent or app must observe. Use semantic Tailwind classes like bg-background, text-foreground, bg-primary, border-border, and text-muted-foreground so the UI inherits the parent app theme.
3129
3133
 
3130
- If the user asks to change, edit, fix, style, rename, or add behavior to an existing extension/widget/dashboard/calculator/mini-app, use the current extension id from \`<current-screen>\` or \`<current-url>\` when present. Call \`get-extension\` only if you need to inspect its content, then \`update-extension\` with that id. Use \`list-extensions\` only when no current id/name is available. Existing extension edits are SQL data updates, not source-code changes, even when the request says "change the UI" or "fix this". Do **NOT** call \`connect-builder\` for existing extension edits.
3134
+ If the user asks to change, edit, fix, style, rename, or add behavior to an existing extension/widget/dashboard/calculator/mini-app, use the current extension id from \`<current-screen>\` or \`<current-url>\` when present. Call \`get-extension\` only if you need to inspect its content, then \`update-extension\` with that id. After one content read, keep the body in working memory and move to focused \`update-extension\` \`edits\`/\`patches\`; do not loop on repeated \`get-extension\` + \`run-code\` string scans before writing. Use \`list-extensions\` only when no current id/name is available. Existing extension edits are SQL data updates, not source-code changes, even when the request says "change the UI" or "fix this". Do **NOT** call \`connect-builder\` for existing extension edits.
3131
3135
 
3132
3136
  In Act mode, when in doubt — if the request asks for a new small interactive utility and does not need reuse, choose \`render-inline-extension\`; if it mentions saving/reuse or asks for an extension/widget/dashboard/calculator/mini-app, choose \`create-extension\`. If it references an existing one or the current extension page, choose \`update-extension\`. Do **not** preface the call with planning text like "let me build the dashboard…" — just call the right extension action directly.
3133
3137
 
@@ -3165,7 +3169,7 @@ Keep the first \`create-extension\` call compact and working. If the request is
3165
3169
 
3166
3170
  Generated UI can read chat inputs from slotContext/window.onSlotContext, see/update app state through appFetch/appAction, use extensionData, record passive current values through agentNative.ui.output(value, opts?), and send visible results through agentNative.chat.send(...) or sendToAgentChat(...). ui.output writes \`inline-ui:<extensionId>:output\` in application state; when the user asks to use the current slider/selection/value, read \`readAppState("inline-ui:<id>:output")\`. Transient extensionData is browser-local only, so do not rely on it for values the agent or app must observe. Use semantic Tailwind theme classes.
3167
3171
 
3168
- If the user asks to change, edit, fix, style, rename, or add behavior to an existing extension/widget/dashboard/calculator/mini-app, use the current extension id from \`<current-screen>\` or \`<current-url>\` when present. Call \`get-extension\` only if you need to inspect its content, then \`update-extension\` with that id. Use \`list-extensions\` only when no current id/name is available. Existing extension edits are SQL data updates, not source-code changes. Do NOT call \`connect-builder\` for them.
3172
+ If the user asks to change, edit, fix, style, rename, or add behavior to an existing extension/widget/dashboard/calculator/mini-app, use the current extension id from \`<current-screen>\` or \`<current-url>\` when present. Call \`get-extension\` only if you need to inspect its content, then \`update-extension\` with that id. After one content read, use focused \`update-extension\` \`edits\`/\`patches\`; do not repeatedly re-read and scan the same HTML with \`run-code\` before writing. Use \`list-extensions\` only when no current id/name is available. Existing extension edits are SQL data updates, not source-code changes. Do NOT call \`connect-builder\` for them.
3169
3173
 
3170
3174
  For existing extensions, use \`get-extension\` or \`update-extension\` directly when \`<current-screen>\` or \`<current-url>\` provides an \`extensionId\`. Use \`list-extensions\` only to browse or resolve an unknown name. Use \`hide-extension\` when the user wants a shared extension removed only from their own view. Do not query the legacy \`tools\` table directly.
3171
3175