@agent-native/core 0.121.2 → 0.122.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 (588) hide show
  1. package/README.md +4 -12
  2. package/corpus/README.md +2 -2
  3. package/corpus/core/CHANGELOG.md +148 -0
  4. package/corpus/core/docs/content/actions.mdx +2 -2
  5. package/corpus/core/docs/content/agent-surfaces.mdx +1 -1
  6. package/corpus/core/docs/content/authentication.mdx +2 -0
  7. package/corpus/core/docs/content/deployment.mdx +36 -0
  8. package/corpus/core/docs/content/http-api.mdx +266 -0
  9. package/corpus/core/docs/content/syncing-template-changes.mdx +159 -0
  10. package/corpus/core/package.json +2 -1
  11. package/corpus/core/src/a2a/activity.ts +38 -27
  12. package/corpus/core/src/a2a/client.ts +57 -4
  13. package/corpus/core/src/agent/engine/builder-engine.ts +35 -4
  14. package/corpus/core/src/agent/run-manager.ts +20 -1
  15. package/corpus/core/src/agent/run-store.ts +4 -1
  16. package/corpus/core/src/agent/types.ts +28 -8
  17. package/corpus/core/src/chat-threads/store.ts +45 -0
  18. package/corpus/core/src/checkpoints/index.ts +2 -0
  19. package/corpus/core/src/checkpoints/route-match.ts +13 -0
  20. package/corpus/core/src/cli/create.ts +105 -17
  21. package/corpus/core/src/cli/index.ts +20 -0
  22. package/corpus/core/src/cli/template-baseline.ts +410 -0
  23. package/corpus/core/src/cli/template-sync.ts +1004 -0
  24. package/corpus/core/src/cli/templates-meta.ts +1 -0
  25. package/corpus/core/src/client/AssistantChat.tsx +38 -12
  26. package/corpus/core/src/client/NewWorkspaceAppFlow.tsx +75 -10
  27. package/corpus/core/src/client/chat/message-components.tsx +127 -66
  28. package/corpus/core/src/client/chat/tool-call-display.tsx +29 -5
  29. package/corpus/core/src/client/error-format.ts +18 -0
  30. package/corpus/core/src/client/org/OrgSwitcher.tsx +30 -8
  31. package/corpus/core/src/client/org/TeamPage.tsx +7 -6
  32. package/corpus/core/src/client/settings/SettingsPanel.tsx +9 -9
  33. package/corpus/core/src/client/settings/SettingsTabsPage.tsx +12 -2
  34. package/corpus/core/src/client/sse-event-processor.ts +3 -0
  35. package/corpus/core/src/data-widgets/index.ts +41 -0
  36. package/corpus/core/src/deploy/build.ts +11 -9
  37. package/corpus/core/src/extensions/url-safety.ts +67 -4
  38. package/corpus/core/src/integrations/webhook-handler.ts +63 -9
  39. package/corpus/core/src/org/auto-join-domain.ts +4 -3
  40. package/corpus/core/src/org/context.ts +108 -39
  41. package/corpus/core/src/org/index.ts +5 -0
  42. package/corpus/core/src/org/service-identity.ts +60 -0
  43. package/corpus/core/src/provider-api/index.ts +22 -1
  44. package/corpus/core/src/scripts/docs/search.ts +12 -1
  45. package/corpus/core/src/server/agent-chat/context-tools.ts +9 -4
  46. package/corpus/core/src/server/agent-chat/framework-prompts.ts +38 -66
  47. package/corpus/core/src/server/agent-chat-plugin.ts +17 -10
  48. package/corpus/core/src/server/agents-bundle.ts +84 -5
  49. package/corpus/core/src/server/auth.ts +4 -3
  50. package/corpus/core/src/server/builder-browser.ts +47 -19
  51. package/corpus/core/src/server/core-routes-plugin.ts +2 -2
  52. package/corpus/core/src/server/credential-provider.ts +209 -68
  53. package/corpus/core/src/server/index.ts +3 -0
  54. package/corpus/core/src/server/prompts/framework-core-compact.ts +6 -13
  55. package/corpus/core/src/server/prompts/framework-core.ts +9 -21
  56. package/corpus/core/src/server/prompts/index.ts +0 -1
  57. package/corpus/core/src/server/prompts/shared-rules.ts +19 -11
  58. package/corpus/core/src/server/ssr-handler.ts +13 -2
  59. package/corpus/core/src/settings/user-settings.ts +13 -1
  60. package/corpus/core/src/shared/cache-control.ts +141 -0
  61. package/corpus/core/src/templates/chat/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
  62. package/corpus/core/src/templates/chat/_gitignore +1 -0
  63. package/corpus/core/src/templates/chat/app/components/layout/Sidebar.tsx +0 -7
  64. package/corpus/core/src/templates/default/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
  65. package/corpus/core/src/templates/default/app/root.tsx +1 -1
  66. package/corpus/core/src/templates/default/public/manifest.json +2 -2
  67. package/corpus/core/src/templates/headless/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
  68. package/corpus/core/src/templates/workspace-core/.agents/skills/performance/SKILL.md +19 -0
  69. package/corpus/core/src/templates/workspace-core/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
  70. package/corpus/core/src/templates/workspace-core/.agents/skills/visual-answer/SKILL.md +1 -0
  71. package/corpus/core/src/vite/agents-bundle-plugin.ts +7 -6
  72. package/corpus/core/src/vite/client.ts +69 -3
  73. package/corpus/templates/analytics/.agents/skills/adhoc-analysis/SKILL.md +4 -5
  74. package/corpus/templates/analytics/.agents/skills/admin-surfaces/SKILL.md +55 -0
  75. package/corpus/templates/analytics/.agents/skills/dashboard-management/SKILL.md +10 -0
  76. package/corpus/templates/analytics/.agents/skills/dashboard-management/references/template-catalog-and-demo.md +62 -0
  77. package/corpus/templates/analytics/.agents/skills/dashboard-ops/SKILL.md +85 -0
  78. package/corpus/templates/analytics/.agents/skills/data-querying/SKILL.md +27 -2
  79. package/corpus/templates/analytics/.agents/skills/data-querying/references/inline-chart-embeds.md +139 -0
  80. package/corpus/templates/analytics/.agents/skills/monitoring/SKILL.md +77 -0
  81. package/corpus/templates/analytics/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
  82. package/corpus/templates/analytics/AGENTS.md +91 -563
  83. package/corpus/templates/analytics/_gitignore +1 -0
  84. package/corpus/templates/analytics/actions/bigquery.ts +12 -4
  85. package/corpus/templates/analytics/actions/generate-chart.ts +5 -5
  86. package/corpus/templates/analytics/app/components/dashboard/SqlChart.tsx +30 -1
  87. package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +1 -23
  88. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/DashboardFilterBar.tsx +3 -0
  89. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/SqlChartCard.tsx +1 -1
  90. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/index.tsx +1 -0
  91. package/corpus/templates/analytics/app/routes/_index.tsx +1 -1
  92. package/corpus/templates/analytics/changelog/2026-07-24-analytics-finds-saved-dashboards-and-queries-far-more-reliab.md +6 -0
  93. package/corpus/templates/analytics/changelog/2026-07-24-notion-access-errors-now-explain-that-a-page-needs-sharing-w.md +6 -0
  94. package/corpus/templates/analytics/changelog/2026-07-25-app-branding-now-uses-the-product-name-without-the-agent-nat.md +6 -0
  95. package/corpus/templates/analytics/changelog/2026-07-25-settings-navigation-now-keeps-manage-agent-as-a-dedicated-li.md +6 -0
  96. package/corpus/templates/analytics/package.json +1 -1
  97. package/corpus/templates/analytics/public/manifest.json +1 -1
  98. package/corpus/templates/analytics/server/lib/agent-chat-plan-mode.ts +7 -0
  99. package/corpus/templates/analytics/server/lib/analytics-query-catalog.ts +191 -30
  100. package/corpus/templates/analytics/server/lib/bigquery.ts +11 -1
  101. package/corpus/templates/analytics/server/lib/notion.ts +15 -4
  102. package/corpus/templates/analytics/server/plugins/agent-chat.ts +10 -0
  103. package/corpus/templates/analytics/server/plugins/auth.ts +1 -1
  104. package/corpus/templates/assets/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
  105. package/corpus/templates/assets/app/components/layout/Sidebar.tsx +0 -2
  106. package/corpus/templates/assets/app/routes/_index.tsx +1 -1
  107. package/corpus/templates/assets/changelog/2026-07-25-app-branding-now-uses-the-product-name-without-the-agent-nat.md +6 -0
  108. package/corpus/templates/assets/changelog/2026-07-25-settings-navigation-now-keeps-manage-agent-as-a-dedicated-li.md +6 -0
  109. package/corpus/templates/assets/server/plugins/auth.ts +1 -1
  110. package/corpus/templates/brain/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
  111. package/corpus/templates/brain/_gitignore +1 -0
  112. package/corpus/templates/brain/app/lib/brain.ts +0 -7
  113. package/corpus/templates/brain/app/routes/_index.tsx +1 -2
  114. package/corpus/templates/brain/changelog/2026-07-25-app-branding-now-uses-the-product-name-without-the-agent-nat.md +6 -0
  115. package/corpus/templates/brain/changelog/2026-07-25-settings-navigation-now-keeps-manage-agent-as-a-dedicated-li.md +6 -0
  116. package/corpus/templates/brain/package.json +1 -1
  117. package/corpus/templates/brain/public/manifest.json +1 -1
  118. package/corpus/templates/brain/server/plugins/auth.ts +1 -1
  119. package/corpus/templates/calendar/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
  120. package/corpus/templates/calendar/_gitignore +1 -0
  121. package/corpus/templates/calendar/app/components/layout/Sidebar.tsx +0 -6
  122. package/corpus/templates/calendar/app/routes/_app._index.tsx +1 -1
  123. package/corpus/templates/calendar/changelog/2026-07-25-app-branding-now-uses-the-product-name-without-the-agent-nat.md +6 -0
  124. package/corpus/templates/calendar/changelog/2026-07-25-settings-navigation-now-keeps-manage-agent-as-a-dedicated-li.md +6 -0
  125. package/corpus/templates/calendar/package.json +1 -1
  126. package/corpus/templates/calendar/public/manifest.json +1 -1
  127. package/corpus/templates/calendar/server/plugins/auth.ts +1 -1
  128. package/corpus/templates/chat/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
  129. package/corpus/templates/chat/_gitignore +1 -0
  130. package/corpus/templates/chat/app/components/layout/Sidebar.tsx +0 -7
  131. package/corpus/templates/chat/changelog/2026-07-25-settings-navigation-now-keeps-manage-agent-as-a-dedicated-li.md +6 -0
  132. package/corpus/templates/clips/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
  133. package/corpus/templates/clips/.agents/skills/video-sharing/SKILL.md +34 -0
  134. package/corpus/templates/clips/AGENTS.md +5 -4
  135. package/corpus/templates/clips/_gitignore +1 -0
  136. package/corpus/templates/clips/actions/cleanup-transcript.ts +5 -0
  137. package/corpus/templates/clips/actions/get-recording-insights.ts +44 -8
  138. package/corpus/templates/clips/actions/get-recording-player-data.ts +39 -70
  139. package/corpus/templates/clips/actions/import-loom-recording.ts +53 -98
  140. package/corpus/templates/clips/actions/lib/loom-import-job.ts +260 -0
  141. package/corpus/templates/clips/actions/list-clip-views.ts +2 -4
  142. package/corpus/templates/clips/actions/list-recordings.ts +69 -19
  143. package/corpus/templates/clips/actions/list-viewers.ts +5 -2
  144. package/corpus/templates/clips/actions/regenerate-summary.ts +5 -1
  145. package/corpus/templates/clips/actions/request-transcript.ts +28 -1
  146. package/corpus/templates/clips/app/components/editor/stitch-manager.tsx +21 -1
  147. package/corpus/templates/clips/app/components/library/library-layout.tsx +0 -7
  148. package/corpus/templates/clips/app/components/meetings/quick-ask-sidebar.tsx +14 -1
  149. package/corpus/templates/clips/app/components/player/insights-panel.tsx +8 -20
  150. package/corpus/templates/clips/app/components/player/recording-views-badge.tsx +335 -0
  151. package/corpus/templates/clips/app/components/player/video-player.tsx +13 -8
  152. package/corpus/templates/clips/app/components/sharing/share-ui.tsx +2 -1
  153. package/corpus/templates/clips/app/i18n/en-US.ts +13 -2
  154. package/corpus/templates/clips/app/lib/capture-permissions.ts +110 -0
  155. package/corpus/templates/clips/app/lib/recording-link.ts +32 -0
  156. package/corpus/templates/clips/app/routes/_app.library._index.tsx +1 -1
  157. package/corpus/templates/clips/app/routes/_app.meetings.$meetingId.tsx +27 -0
  158. package/corpus/templates/clips/app/routes/_index.tsx +1 -1
  159. package/corpus/templates/clips/app/routes/r.$recordingId.tsx +52 -15
  160. package/corpus/templates/clips/app/routes/record.tsx +82 -31
  161. package/corpus/templates/clips/app/routes/share.$shareId.tsx +42 -31
  162. package/corpus/templates/clips/changelog/2026-07-24-clip-pages-now-show-a-view-count-with-viewer-avatars-next-to.md +6 -0
  163. package/corpus/templates/clips/changelog/2026-07-24-clip-summaries-read-like-a-description-you-d-write-yourself-.md +6 -0
  164. package/corpus/templates/clips/changelog/2026-07-24-clip-view-counts-now-separate-human-views-from-agent-views-s.md +6 -0
  165. package/corpus/templates/clips/changelog/2026-07-24-clips-actions-can-now-be-called-by-org-service-tokens-so-ext.md +6 -0
  166. package/corpus/templates/clips/changelog/2026-07-24-clips-no-longer-briefly-shows-a-dock-icon-while-launching.md +6 -0
  167. package/corpus/templates/clips/changelog/2026-07-24-fixed-owner-and-editor-share-links-redirecting-to-the-record.md +6 -0
  168. package/corpus/templates/clips/changelog/2026-07-24-meeting-and-note-recordings-now-start-as-a-compact-pill-on-t.md +6 -0
  169. package/corpus/templates/clips/changelog/2026-07-24-new-clips-now-copy-a-shareable-link-instead-of-the-owner-onl.md +6 -0
  170. package/corpus/templates/clips/changelog/2026-07-24-opening-a-share-link-as-the-clip-s-owner-now-goes-straight-t.md +6 -0
  171. package/corpus/templates/clips/changelog/2026-07-24-permissions-and-rewind-controls-now-use-compact-consistent-h.md +6 -0
  172. package/corpus/templates/clips/changelog/2026-07-24-quitting-the-desktop-app-no-longer-shows-a-false-macos-crash.md +6 -0
  173. package/corpus/templates/clips/changelog/2026-07-24-screen-recording-permission-errors-now-name-the-exact-app-to.md +6 -0
  174. package/corpus/templates/clips/changelog/2026-07-24-the-desktop-app-now-copies-a-new-clip-s-share-link-to-your-c.md +6 -0
  175. package/corpus/templates/clips/changelog/2026-07-24-the-recording-toolbar-now-stays-above-other-apps-including-o.md +6 -0
  176. package/corpus/templates/clips/changelog/2026-07-24-transcript-captions-now-use-real-speech-timings-instead-of-a.md +6 -0
  177. package/corpus/templates/clips/changelog/2026-07-24-video-playback-no-longer-stutters-and-replays-the-last-momen.md +6 -0
  178. package/corpus/templates/clips/changelog/2026-07-25-app-branding-now-uses-the-product-name-without-the-agent-nat.md +6 -0
  179. package/corpus/templates/clips/changelog/2026-07-25-settings-navigation-now-keeps-manage-agent-as-a-dedicated-li.md +6 -0
  180. package/corpus/templates/clips/chrome-extension/src/background.ts +17 -1
  181. package/corpus/templates/clips/desktop/package.json +2 -0
  182. package/corpus/templates/clips/desktop/src/app.tsx +89 -0
  183. package/corpus/templates/clips/desktop/src/hooks/useMeetingTranscription.ts +9 -3
  184. package/corpus/templates/clips/desktop/src/lib/audio-meter.ts +51 -0
  185. package/corpus/templates/clips/desktop/src/lib/native-notification.ts +44 -0
  186. package/corpus/templates/clips/desktop/src/lib/recording-link.ts +67 -0
  187. package/corpus/templates/clips/desktop/src/overlays/live-audio-bars.tsx +35 -35
  188. package/corpus/templates/clips/desktop/src/overlays/live-transcript.tsx +3 -2
  189. package/corpus/templates/clips/desktop/src/overlays/recording-pill.tsx +47 -46
  190. package/corpus/templates/clips/desktop/src/styles.css +127 -78
  191. package/corpus/templates/clips/desktop/src-tauri/Cargo.toml +7 -0
  192. package/corpus/templates/clips/desktop/src-tauri/Info.plist +6 -0
  193. package/corpus/templates/clips/desktop/src-tauri/capabilities/default.json +1 -0
  194. package/corpus/templates/clips/desktop/src-tauri/src/clips/mod.rs +7 -3
  195. package/corpus/templates/clips/desktop/src-tauri/src/lib.rs +4 -1
  196. package/corpus/templates/clips/desktop/src-tauri/src/main.rs +8 -0
  197. package/corpus/templates/clips/desktop/src-tauri/src/recording_indicator.rs +21 -10
  198. package/corpus/templates/clips/desktop/src-tauri/src/util.rs +40 -0
  199. package/corpus/templates/clips/server/db/schema.ts +27 -0
  200. package/corpus/templates/clips/server/lib/agent-views.ts +145 -0
  201. package/corpus/templates/clips/server/lib/post-finalize-dispatch.ts +2 -1
  202. package/corpus/templates/clips/server/lib/public-agent-context.ts +7 -0
  203. package/corpus/templates/clips/server/lib/recording-share-grant.ts +79 -0
  204. package/corpus/templates/clips/server/lib/recordings.ts +51 -3
  205. package/corpus/templates/clips/server/plugins/auth.ts +1 -1
  206. package/corpus/templates/clips/server/plugins/db.ts +31 -0
  207. package/corpus/templates/clips/server/routes/api/_agent-native-background/post-finalize-worker.post.ts +56 -3
  208. package/corpus/templates/clips/server/routes/api/public-recording.get.ts +49 -17
  209. package/corpus/templates/clips/shared/recording-link.ts +43 -0
  210. package/corpus/templates/clips/shared/share-attribution.ts +4 -0
  211. package/corpus/templates/clips/shared/share-dashboard-redirect.ts +42 -0
  212. package/corpus/templates/clips/shared/view-analytics.ts +26 -0
  213. package/corpus/templates/content/.agents/skills/content/SKILL.md +5 -0
  214. package/corpus/templates/content/.agents/skills/content/references/local-file-mode.md +135 -0
  215. package/corpus/templates/content/.agents/skills/document-editing/SKILL.md +12 -0
  216. package/corpus/templates/content/.agents/skills/document-editing/references/databases.md +238 -0
  217. package/corpus/templates/content/.agents/skills/document-editing/references/document-behavior.md +91 -0
  218. package/corpus/templates/content/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
  219. package/corpus/templates/content/AGENTS.md +62 -583
  220. package/corpus/templates/content/_gitignore +1 -0
  221. package/corpus/templates/content/app/components/sidebar/DocumentSidebar.tsx +1 -39
  222. package/corpus/templates/content/app/routes/_app._index.tsx +1 -2
  223. package/corpus/templates/content/changelog/2026-07-25-app-branding-now-uses-the-product-name-without-the-agent-nat.md +6 -0
  224. package/corpus/templates/content/changelog/2026-07-25-settings-navigation-now-keeps-manage-agent-as-a-dedicated-li.md +6 -0
  225. package/corpus/templates/content/package.json +1 -1
  226. package/corpus/templates/content/public/manifest.json +1 -1
  227. package/corpus/templates/content/server/plugins/auth.ts +1 -1
  228. package/corpus/templates/design/.agents/skills/creative-context/SKILL.md +11 -0
  229. package/corpus/templates/design/.agents/skills/design-generation/SKILL.md +50 -8
  230. package/corpus/templates/design/.agents/skills/design-generation/references/code-layers.md +81 -0
  231. package/corpus/templates/design/.agents/skills/design-generation/references/code-workspace.md +42 -0
  232. package/corpus/templates/design/.agents/skills/design-generation/references/editor-extensions.md +34 -0
  233. package/corpus/templates/design/.agents/skills/responsive-breakpoints/SKILL.md +4 -1
  234. package/corpus/templates/design/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
  235. package/corpus/templates/design/.agents/skills/visual-edit/SKILL.md +17 -0
  236. package/corpus/templates/design/.generated/bridge/editor-chrome.generated.ts +8196 -0
  237. package/corpus/templates/design/.generated/bridge/embedded-wheel.generated.ts +265 -0
  238. package/corpus/templates/design/.generated/bridge/hit-test.generated.ts +642 -0
  239. package/corpus/templates/design/.generated/bridge/motion-preview.generated.ts +571 -0
  240. package/corpus/templates/design/.generated/bridge/nav.generated.ts +91 -0
  241. package/corpus/templates/design/.generated/bridge/sample.generated.ts +23 -0
  242. package/corpus/templates/design/.generated/bridge/shader-fill-preview.generated.ts +263 -0
  243. package/corpus/templates/design/.generated/bridge/shader-runtime.generated.ts +518 -0
  244. package/corpus/templates/design/.generated/bridge/tweak.generated.ts +20 -0
  245. package/corpus/templates/design/.generated/bridge/zoom.generated.ts +32 -0
  246. package/corpus/templates/design/AGENTS.md +88 -503
  247. package/corpus/templates/design/_gitignore +1 -0
  248. package/corpus/templates/design/app/components/layout/Sidebar.tsx +0 -2
  249. package/corpus/templates/design/app/routes/_index.tsx +1 -1
  250. package/corpus/templates/design/changelog/2026-07-25-app-branding-now-uses-the-product-name-without-the-agent-nat.md +6 -0
  251. package/corpus/templates/design/changelog/2026-07-25-settings-navigation-now-keeps-manage-agent-as-a-dedicated-li.md +6 -0
  252. package/corpus/templates/design/server/plugins/auth.ts +1 -1
  253. package/corpus/templates/dispatch/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
  254. package/corpus/templates/dispatch/_gitignore +1 -0
  255. package/corpus/templates/dispatch/app/dispatch-extensions.tsx +1 -10
  256. package/corpus/templates/dispatch/app/routes/overview.tsx +1 -1
  257. package/corpus/templates/dispatch/changelog/2026-07-24-signing-in-now-puts-you-in-your-companys-workspace.md +6 -0
  258. package/corpus/templates/dispatch/changelog/2026-07-25-app-branding-now-uses-the-product-name-without-the-agent-nat.md +6 -0
  259. package/corpus/templates/dispatch/changelog/2026-07-25-settings-navigation-now-keeps-manage-agent-as-a-dedicated-li.md +6 -0
  260. package/corpus/templates/dispatch/package.json +1 -1
  261. package/corpus/templates/dispatch/public/manifest.json +1 -1
  262. package/corpus/templates/forms/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
  263. package/corpus/templates/forms/_gitignore +1 -0
  264. package/corpus/templates/forms/app/components/layout/Sidebar.tsx +0 -35
  265. package/corpus/templates/forms/changelog/2026-07-25-app-branding-now-uses-the-product-name-without-the-agent-nat.md +6 -0
  266. package/corpus/templates/forms/changelog/2026-07-25-settings-navigation-now-keeps-manage-agent-as-a-dedicated-li.md +6 -0
  267. package/corpus/templates/forms/package.json +1 -1
  268. package/corpus/templates/forms/public/manifest.json +1 -1
  269. package/corpus/templates/forms/server/lib/public-form-ssr.ts +2 -2
  270. package/corpus/templates/forms/server/plugins/auth.ts +1 -1
  271. package/corpus/templates/macros/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
  272. package/corpus/templates/macros/_gitignore +1 -0
  273. package/corpus/templates/macros/app/components/layout/AppLayout.tsx +0 -2
  274. package/corpus/templates/macros/changelog/2026-07-25-app-branding-now-uses-the-product-name-without-the-agent-nat.md +6 -0
  275. package/corpus/templates/macros/changelog/2026-07-25-settings-navigation-now-keeps-manage-agent-as-a-dedicated-li.md +6 -0
  276. package/corpus/templates/macros/package.json +1 -1
  277. package/corpus/templates/macros/server/plugins/auth.ts +2 -2
  278. package/corpus/templates/mail/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
  279. package/corpus/templates/mail/_gitignore +1 -0
  280. package/corpus/templates/mail/app/components/layout/AppLayout.tsx +0 -39
  281. package/corpus/templates/mail/app/routes/$view.$threadId.tsx +1 -1
  282. package/corpus/templates/mail/app/routes/$view.tsx +1 -1
  283. package/corpus/templates/mail/app/routes/_index.tsx +1 -1
  284. package/corpus/templates/mail/changelog/2026-07-25-app-branding-now-uses-the-product-name-without-the-agent-nat.md +6 -0
  285. package/corpus/templates/mail/changelog/2026-07-25-settings-navigation-now-keeps-manage-agent-as-a-dedicated-li.md +6 -0
  286. package/corpus/templates/mail/package.json +1 -1
  287. package/corpus/templates/mail/public/manifest.json +1 -1
  288. package/corpus/templates/mail/server/plugins/auth.ts +1 -1
  289. package/corpus/templates/plan/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
  290. package/corpus/templates/plan/_gitignore +1 -0
  291. package/corpus/templates/plan/agent-native.app-skill.json +1 -1
  292. package/corpus/templates/plan/app/components/layout/Sidebar.tsx +4 -9
  293. package/corpus/templates/plan/app/lib/app-config.ts +1 -1
  294. package/corpus/templates/plan/changelog/2026-07-25-app-branding-now-uses-the-product-name-without-the-agent-nat.md +6 -0
  295. package/corpus/templates/plan/changelog/2026-07-25-settings-navigation-now-keeps-manage-agent-as-a-dedicated-li.md +6 -0
  296. package/corpus/templates/plan/package.json +1 -1
  297. package/corpus/templates/plan/public/manifest.json +1 -1
  298. package/corpus/templates/plan/server/plugins/auth.ts +1 -1
  299. package/corpus/templates/slides/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
  300. package/corpus/templates/slides/_gitignore +1 -0
  301. package/corpus/templates/slides/app/components/layout/Sidebar.tsx +0 -2
  302. package/corpus/templates/slides/app/routes/_index.tsx +1 -1
  303. package/corpus/templates/slides/changelog/2026-07-25-app-branding-now-uses-the-product-name-without-the-agent-nat.md +6 -0
  304. package/corpus/templates/slides/changelog/2026-07-25-settings-navigation-now-keeps-manage-agent-as-a-dedicated-li.md +6 -0
  305. package/corpus/templates/slides/package.json +1 -1
  306. package/corpus/templates/slides/public/manifest.json +1 -1
  307. package/corpus/templates/slides/server/plugins/auth.ts +1 -1
  308. package/corpus/templates/slides/server/plugins/db.ts +4 -0
  309. package/corpus/templates/tasks/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
  310. package/corpus/templates/tasks/AGENTS.md +1 -1
  311. package/corpus/templates/tasks/_gitignore +1 -0
  312. package/dist/a2a/activity.d.ts +4 -1
  313. package/dist/a2a/activity.d.ts.map +1 -1
  314. package/dist/a2a/activity.js +27 -16
  315. package/dist/a2a/activity.js.map +1 -1
  316. package/dist/a2a/client.d.ts.map +1 -1
  317. package/dist/a2a/client.js +58 -4
  318. package/dist/a2a/client.js.map +1 -1
  319. package/dist/agent/engine/builder-engine.d.ts +1 -0
  320. package/dist/agent/engine/builder-engine.d.ts.map +1 -1
  321. package/dist/agent/engine/builder-engine.js +31 -4
  322. package/dist/agent/engine/builder-engine.js.map +1 -1
  323. package/dist/agent/run-manager.d.ts.map +1 -1
  324. package/dist/agent/run-manager.js +18 -1
  325. package/dist/agent/run-manager.js.map +1 -1
  326. package/dist/agent/run-store.d.ts +1 -0
  327. package/dist/agent/run-store.d.ts.map +1 -1
  328. package/dist/agent/run-store.js +2 -1
  329. package/dist/agent/run-store.js.map +1 -1
  330. package/dist/agent/types.d.ts +12 -1
  331. package/dist/agent/types.d.ts.map +1 -1
  332. package/dist/agent/types.js +21 -1
  333. package/dist/agent/types.js.map +1 -1
  334. package/dist/chat-threads/store.d.ts +10 -0
  335. package/dist/chat-threads/store.d.ts.map +1 -1
  336. package/dist/chat-threads/store.js +41 -0
  337. package/dist/chat-threads/store.js.map +1 -1
  338. package/dist/checkpoints/index.d.ts +1 -0
  339. package/dist/checkpoints/index.d.ts.map +1 -1
  340. package/dist/checkpoints/index.js +1 -0
  341. package/dist/checkpoints/index.js.map +1 -1
  342. package/dist/checkpoints/route-match.d.ts +8 -0
  343. package/dist/checkpoints/route-match.d.ts.map +1 -0
  344. package/dist/checkpoints/route-match.js +13 -0
  345. package/dist/checkpoints/route-match.js.map +1 -0
  346. package/dist/cli/create.d.ts +35 -4
  347. package/dist/cli/create.d.ts.map +1 -1
  348. package/dist/cli/create.js +69 -19
  349. package/dist/cli/create.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/template-baseline.d.ts +54 -0
  353. package/dist/cli/template-baseline.d.ts.map +1 -0
  354. package/dist/cli/template-baseline.js +334 -0
  355. package/dist/cli/template-baseline.js.map +1 -0
  356. package/dist/cli/template-sync.d.ts +57 -0
  357. package/dist/cli/template-sync.d.ts.map +1 -0
  358. package/dist/cli/template-sync.js +787 -0
  359. package/dist/cli/template-sync.js.map +1 -0
  360. package/dist/cli/templates-meta.d.ts.map +1 -1
  361. package/dist/cli/templates-meta.js +1 -0
  362. package/dist/cli/templates-meta.js.map +1 -1
  363. package/dist/client/AssistantChat.d.ts +2 -1
  364. package/dist/client/AssistantChat.d.ts.map +1 -1
  365. package/dist/client/AssistantChat.js +38 -10
  366. package/dist/client/AssistantChat.js.map +1 -1
  367. package/dist/client/NewWorkspaceAppFlow.d.ts.map +1 -1
  368. package/dist/client/NewWorkspaceAppFlow.js +32 -2
  369. package/dist/client/NewWorkspaceAppFlow.js.map +1 -1
  370. package/dist/client/chat/message-components.d.ts +20 -0
  371. package/dist/client/chat/message-components.d.ts.map +1 -1
  372. package/dist/client/chat/message-components.js +81 -46
  373. package/dist/client/chat/message-components.js.map +1 -1
  374. package/dist/client/chat/tool-call-display.d.ts.map +1 -1
  375. package/dist/client/chat/tool-call-display.js +14 -6
  376. package/dist/client/chat/tool-call-display.js.map +1 -1
  377. package/dist/client/error-format.d.ts.map +1 -1
  378. package/dist/client/error-format.js +13 -0
  379. package/dist/client/error-format.js.map +1 -1
  380. package/dist/client/org/OrgSwitcher.d.ts +8 -1
  381. package/dist/client/org/OrgSwitcher.d.ts.map +1 -1
  382. package/dist/client/org/OrgSwitcher.js +3 -2
  383. package/dist/client/org/OrgSwitcher.js.map +1 -1
  384. package/dist/client/org/TeamPage.d.ts.map +1 -1
  385. package/dist/client/org/TeamPage.js +1 -1
  386. package/dist/client/org/TeamPage.js.map +1 -1
  387. package/dist/client/settings/SettingsPanel.js +9 -9
  388. package/dist/client/settings/SettingsPanel.js.map +1 -1
  389. package/dist/client/settings/SettingsTabsPage.d.ts.map +1 -1
  390. package/dist/client/settings/SettingsTabsPage.js +7 -4
  391. package/dist/client/settings/SettingsTabsPage.js.map +1 -1
  392. package/dist/client/sse-event-processor.d.ts.map +1 -1
  393. package/dist/client/sse-event-processor.js +3 -0
  394. package/dist/client/sse-event-processor.js.map +1 -1
  395. package/dist/collab/awareness.d.ts +2 -2
  396. package/dist/collab/awareness.d.ts.map +1 -1
  397. package/dist/collab/struct-routes.d.ts +1 -1
  398. package/dist/data-widgets/index.d.ts +3 -0
  399. package/dist/data-widgets/index.d.ts.map +1 -1
  400. package/dist/data-widgets/index.js +33 -0
  401. package/dist/data-widgets/index.js.map +1 -1
  402. package/dist/deploy/build.d.ts.map +1 -1
  403. package/dist/deploy/build.js +11 -7
  404. package/dist/deploy/build.js.map +1 -1
  405. package/dist/eject/provider-api-definitions.d.ts +1 -0
  406. package/dist/eject/provider-api-definitions.d.ts.map +1 -1
  407. package/dist/extensions/url-safety.d.ts +9 -16
  408. package/dist/extensions/url-safety.d.ts.map +1 -1
  409. package/dist/extensions/url-safety.js +48 -4
  410. package/dist/extensions/url-safety.js.map +1 -1
  411. package/dist/file-upload/actions/upload-image.d.ts +1 -1
  412. package/dist/integrations/webhook-handler.d.ts.map +1 -1
  413. package/dist/integrations/webhook-handler.js +46 -9
  414. package/dist/integrations/webhook-handler.js.map +1 -1
  415. package/dist/notifications/routes.d.ts +2 -2
  416. package/dist/observability/routes.d.ts +3 -3
  417. package/dist/org/auto-join-domain.d.ts +3 -2
  418. package/dist/org/auto-join-domain.d.ts.map +1 -1
  419. package/dist/org/auto-join-domain.js +1 -1
  420. package/dist/org/auto-join-domain.js.map +1 -1
  421. package/dist/org/context.d.ts.map +1 -1
  422. package/dist/org/context.js +84 -28
  423. package/dist/org/context.js.map +1 -1
  424. package/dist/org/index.d.ts +1 -0
  425. package/dist/org/index.d.ts.map +1 -1
  426. package/dist/org/index.js +1 -0
  427. package/dist/org/index.js.map +1 -1
  428. package/dist/org/service-identity.d.ts +43 -0
  429. package/dist/org/service-identity.d.ts.map +1 -0
  430. package/dist/org/service-identity.js +34 -0
  431. package/dist/org/service-identity.js.map +1 -0
  432. package/dist/provider-api/actions/custom-provider-registration.d.ts +14 -14
  433. package/dist/provider-api/actions/provider-api.d.ts +13 -11
  434. package/dist/provider-api/actions/provider-api.d.ts.map +1 -1
  435. package/dist/provider-api/index.d.ts +4 -0
  436. package/dist/provider-api/index.d.ts.map +1 -1
  437. package/dist/provider-api/index.js +17 -1
  438. package/dist/provider-api/index.js.map +1 -1
  439. package/dist/scripts/docs/search.d.ts.map +1 -1
  440. package/dist/scripts/docs/search.js +12 -1
  441. package/dist/scripts/docs/search.js.map +1 -1
  442. package/dist/server/agent-chat/context-tools.d.ts.map +1 -1
  443. package/dist/server/agent-chat/context-tools.js +3 -3
  444. package/dist/server/agent-chat/context-tools.js.map +1 -1
  445. package/dist/server/agent-chat/framework-prompts.d.ts +8 -3
  446. package/dist/server/agent-chat/framework-prompts.d.ts.map +1 -1
  447. package/dist/server/agent-chat/framework-prompts.js +33 -62
  448. package/dist/server/agent-chat/framework-prompts.js.map +1 -1
  449. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  450. package/dist/server/agent-chat-plugin.js +16 -10
  451. package/dist/server/agent-chat-plugin.js.map +1 -1
  452. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  453. package/dist/server/agents-bundle.d.ts +18 -0
  454. package/dist/server/agents-bundle.d.ts.map +1 -1
  455. package/dist/server/agents-bundle.js +70 -4
  456. package/dist/server/agents-bundle.js.map +1 -1
  457. package/dist/server/auth.d.ts.map +1 -1
  458. package/dist/server/auth.js +4 -3
  459. package/dist/server/auth.js.map +1 -1
  460. package/dist/server/builder-browser.d.ts.map +1 -1
  461. package/dist/server/builder-browser.js +43 -19
  462. package/dist/server/builder-browser.js.map +1 -1
  463. package/dist/server/core-routes-plugin.js +2 -2
  464. package/dist/server/core-routes-plugin.js.map +1 -1
  465. package/dist/server/credential-provider.d.ts +38 -2
  466. package/dist/server/credential-provider.d.ts.map +1 -1
  467. package/dist/server/credential-provider.js +142 -64
  468. package/dist/server/credential-provider.js.map +1 -1
  469. package/dist/server/index.d.ts +1 -1
  470. package/dist/server/index.d.ts.map +1 -1
  471. package/dist/server/index.js +1 -1
  472. package/dist/server/index.js.map +1 -1
  473. package/dist/server/prompts/framework-core-compact.d.ts +1 -1
  474. package/dist/server/prompts/framework-core-compact.d.ts.map +1 -1
  475. package/dist/server/prompts/framework-core-compact.js +7 -13
  476. package/dist/server/prompts/framework-core-compact.js.map +1 -1
  477. package/dist/server/prompts/framework-core.d.ts +1 -1
  478. package/dist/server/prompts/framework-core.d.ts.map +1 -1
  479. package/dist/server/prompts/framework-core.js +10 -21
  480. package/dist/server/prompts/framework-core.js.map +1 -1
  481. package/dist/server/prompts/index.d.ts +1 -1
  482. package/dist/server/prompts/index.d.ts.map +1 -1
  483. package/dist/server/prompts/index.js +1 -1
  484. package/dist/server/prompts/index.js.map +1 -1
  485. package/dist/server/prompts/shared-rules.d.ts +16 -10
  486. package/dist/server/prompts/shared-rules.d.ts.map +1 -1
  487. package/dist/server/prompts/shared-rules.js +19 -10
  488. package/dist/server/prompts/shared-rules.js.map +1 -1
  489. package/dist/server/ssr-handler.d.ts +1 -1
  490. package/dist/server/ssr-handler.d.ts.map +1 -1
  491. package/dist/server/ssr-handler.js +10 -3
  492. package/dist/server/ssr-handler.js.map +1 -1
  493. package/dist/server/transcribe-voice.d.ts +1 -1
  494. package/dist/settings/user-settings.d.ts.map +1 -1
  495. package/dist/settings/user-settings.js +13 -1
  496. package/dist/settings/user-settings.js.map +1 -1
  497. package/dist/shared/cache-control.d.ts +52 -0
  498. package/dist/shared/cache-control.d.ts.map +1 -1
  499. package/dist/shared/cache-control.js +107 -0
  500. package/dist/shared/cache-control.js.map +1 -1
  501. package/dist/templates/chat/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
  502. package/dist/templates/chat/_gitignore +1 -0
  503. package/dist/templates/chat/app/components/layout/Sidebar.tsx +0 -7
  504. package/dist/templates/chat/changelog/2026-07-25-settings-navigation-now-keeps-manage-agent-as-a-dedicated-li.md +6 -0
  505. package/dist/templates/default/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
  506. package/dist/templates/default/app/root.tsx +1 -1
  507. package/dist/templates/default/public/manifest.json +2 -2
  508. package/dist/templates/headless/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
  509. package/dist/templates/workspace-core/.agents/skills/performance/SKILL.md +19 -0
  510. package/dist/templates/workspace-core/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
  511. package/dist/templates/workspace-core/.agents/skills/visual-answer/SKILL.md +1 -0
  512. package/dist/vite/agents-bundle-plugin.d.ts.map +1 -1
  513. package/dist/vite/agents-bundle-plugin.js +8 -7
  514. package/dist/vite/agents-bundle-plugin.js.map +1 -1
  515. package/dist/vite/client.d.ts.map +1 -1
  516. package/dist/vite/client.js +66 -1
  517. package/dist/vite/client.js.map +1 -1
  518. package/docs/content/actions.mdx +2 -2
  519. package/docs/content/agent-surfaces.mdx +1 -1
  520. package/docs/content/authentication.mdx +2 -0
  521. package/docs/content/deployment.mdx +36 -0
  522. package/docs/content/http-api.mdx +266 -0
  523. package/docs/content/syncing-template-changes.mdx +159 -0
  524. package/package.json +4 -3
  525. package/src/a2a/activity.ts +38 -27
  526. package/src/a2a/client.ts +57 -4
  527. package/src/agent/engine/builder-engine.ts +35 -4
  528. package/src/agent/run-manager.ts +20 -1
  529. package/src/agent/run-store.ts +4 -1
  530. package/src/agent/types.ts +28 -8
  531. package/src/chat-threads/store.ts +45 -0
  532. package/src/checkpoints/index.ts +2 -0
  533. package/src/checkpoints/route-match.ts +13 -0
  534. package/src/cli/create.ts +105 -17
  535. package/src/cli/index.ts +20 -0
  536. package/src/cli/template-baseline.ts +410 -0
  537. package/src/cli/template-sync.ts +1004 -0
  538. package/src/cli/templates-meta.ts +1 -0
  539. package/src/client/AssistantChat.tsx +38 -12
  540. package/src/client/NewWorkspaceAppFlow.tsx +75 -10
  541. package/src/client/chat/message-components.tsx +127 -66
  542. package/src/client/chat/tool-call-display.tsx +29 -5
  543. package/src/client/error-format.ts +18 -0
  544. package/src/client/org/OrgSwitcher.tsx +30 -8
  545. package/src/client/org/TeamPage.tsx +7 -6
  546. package/src/client/settings/SettingsPanel.tsx +9 -9
  547. package/src/client/settings/SettingsTabsPage.tsx +12 -2
  548. package/src/client/sse-event-processor.ts +3 -0
  549. package/src/data-widgets/index.ts +41 -0
  550. package/src/deploy/build.ts +11 -9
  551. package/src/extensions/url-safety.ts +67 -4
  552. package/src/integrations/webhook-handler.ts +63 -9
  553. package/src/org/auto-join-domain.ts +4 -3
  554. package/src/org/context.ts +108 -39
  555. package/src/org/index.ts +5 -0
  556. package/src/org/service-identity.ts +60 -0
  557. package/src/provider-api/index.ts +22 -1
  558. package/src/scripts/docs/search.ts +12 -1
  559. package/src/server/__snapshots__/agent-chat-plugin.surface.spec.ts.snap +25 -36
  560. package/src/server/agent-chat/context-tools.ts +9 -4
  561. package/src/server/agent-chat/framework-prompts.ts +38 -66
  562. package/src/server/agent-chat-plugin.ts +17 -10
  563. package/src/server/agents-bundle.ts +84 -5
  564. package/src/server/auth.ts +4 -3
  565. package/src/server/builder-browser.ts +47 -19
  566. package/src/server/core-routes-plugin.ts +2 -2
  567. package/src/server/credential-provider.ts +209 -68
  568. package/src/server/index.ts +3 -0
  569. package/src/server/prompts/framework-core-compact.ts +6 -13
  570. package/src/server/prompts/framework-core.ts +9 -21
  571. package/src/server/prompts/index.ts +0 -1
  572. package/src/server/prompts/shared-rules.ts +19 -11
  573. package/src/server/ssr-handler.ts +13 -2
  574. package/src/settings/user-settings.ts +13 -1
  575. package/src/shared/cache-control.ts +141 -0
  576. package/src/templates/chat/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
  577. package/src/templates/chat/_gitignore +1 -0
  578. package/src/templates/chat/app/components/layout/Sidebar.tsx +0 -7
  579. package/src/templates/chat/changelog/2026-07-25-settings-navigation-now-keeps-manage-agent-as-a-dedicated-li.md +6 -0
  580. package/src/templates/default/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
  581. package/src/templates/default/app/root.tsx +1 -1
  582. package/src/templates/default/public/manifest.json +2 -2
  583. package/src/templates/headless/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
  584. package/src/templates/workspace-core/.agents/skills/performance/SKILL.md +19 -0
  585. package/src/templates/workspace-core/.agents/skills/upgrade-agent-native/SKILL.md +24 -2
  586. package/src/templates/workspace-core/.agents/skills/visual-answer/SKILL.md +1 -0
  587. package/src/vite/agents-bundle-plugin.ts +7 -6
  588. package/src/vite/client.ts +69 -3
@@ -0,0 +1,60 @@
1
+ /**
2
+ * Implicit org membership for synthetic service-token identities.
3
+ *
4
+ * Org service tokens authenticate as `svc-<name>@service.<orgId>` and are
5
+ * deliberately never inserted into `org_members` (see
6
+ * `mcp/actions/service-token-access.ts`), so any template that authorizes by
7
+ * looking up a physical membership row rejects them. The ownable/sharing layer
8
+ * already admits them via the signed `org_id` claim; this closes the gap for
9
+ * the role-lookup layer.
10
+ *
11
+ * Two constraints are load-bearing and must survive future edits:
12
+ *
13
+ * 1. The implicit role is always `member`, never admin or owner. Member-gated
14
+ * actions (create/read org data) work; admin-gated ones (invite/remove
15
+ * members, change roles, org settings, minting further service tokens) stay
16
+ * closed, so a leaked service token cannot escalate.
17
+ * 2. `requestOrgId` must independently agree with the target org. The email
18
+ * alone is not proof: a human account registered under a `@service.<orgId>`
19
+ * address would otherwise mint itself membership. A signed-in user's request
20
+ * org id is membership-derived through `getOrgContext`, so a non-member
21
+ * cannot present the target org id, while a service token carries it in its
22
+ * signed `org_id` claim.
23
+ */
24
+ import type { OrgRole } from "./types.js";
25
+
26
+ const SERVICE_IDENTITY_PATTERN = /^svc-([a-z0-9-]+)@service\.(.+)$/;
27
+
28
+ /**
29
+ * Parse `svc-<name>@service.<orgId>` into its parts, or null when the address
30
+ * is not a service identity. Counterpart to `serviceIdentityEmail()` in
31
+ * `mcp/connect-store.ts`.
32
+ */
33
+ export function parseServiceIdentityEmail(
34
+ email: string | null | undefined,
35
+ ): { serviceName: string; orgId: string } | null {
36
+ const trimmed = email?.trim();
37
+ if (!trimmed) return null;
38
+ const match = SERVICE_IDENTITY_PATTERN.exec(trimmed.toLowerCase());
39
+ if (!match) return null;
40
+ const orgId = trimmed.slice(trimmed.length - match[2].length);
41
+ if (!orgId) return null;
42
+ return { serviceName: match[1], orgId };
43
+ }
44
+
45
+ /**
46
+ * Resolve the implicit org role for a service-token caller, or null when the
47
+ * caller is not a service identity acting for the org it was minted against.
48
+ */
49
+ export function implicitServiceOrgRole(params: {
50
+ email: string | null | undefined;
51
+ orgId: string | null | undefined;
52
+ requestOrgId: string | null | undefined;
53
+ }): OrgRole | null {
54
+ const orgId = params.orgId?.trim();
55
+ if (!orgId) return null;
56
+ if (params.requestOrgId?.trim() !== orgId) return null;
57
+ const parsed = parseServiceIdentityEmail(params.email);
58
+ if (!parsed || parsed.orgId !== orgId) return null;
59
+ return "member";
60
+ }
@@ -396,6 +396,7 @@ export interface ProviderApiConfig {
396
396
  placeholders?: readonly ProviderApiPlaceholder[];
397
397
  examples?: readonly ProviderApiExample[];
398
398
  notes?: readonly string[];
399
+ accessErrorGuidance?: string;
399
400
  corpusRecipes?: readonly ProviderApiCorpusRecipe[];
400
401
  templateUses?: readonly WorkspaceConnectionTemplateUse[];
401
402
  }
@@ -1326,6 +1327,11 @@ const PROVIDER_CONFIGS: Record<ProviderApiId, ProviderApiConfig> = {
1326
1327
  defaultHeaders: { "Notion-Version": "2026-03-11" },
1327
1328
  templateUses: ["analytics", "brain", "content", "dispatch"],
1328
1329
  examples: [{ label: "Search", method: "POST", path: "/search", body: {} }],
1330
+ notes: [
1331
+ "The name GET /users/me returns is the label whoever minted the token typed into Notion, so it often names an unrelated product or team. Call it the Notion-side integration label and never restate it as the workspace, app, or product the user is currently in.",
1332
+ ],
1333
+ accessErrorGuidance:
1334
+ "Notion 401/403/404 on a specific page or database usually means that object was never shared with the integration, not that the id is wrong or the key is invalid. Fix: open the page or database in Notion, then ••• → Connections → add the integration. When naming the integration, describe it as the Notion-side integration label from GET /users/me and note that it may not match this app or workspace.",
1329
1335
  corpusRecipes: [
1330
1336
  {
1331
1337
  label: "Search a Notion data source with complete cursor coverage",
@@ -1624,6 +1630,7 @@ export function listProviderApiCatalog(
1624
1630
  defaultHeaders: config.defaultHeaders ?? {},
1625
1631
  examples: config.examples ?? [],
1626
1632
  notes: config.notes ?? [],
1633
+ accessErrorGuidance: config.accessErrorGuidance ?? null,
1627
1634
  corpusRecipes: config.corpusRecipes ?? [],
1628
1635
  templateUses: config.templateUses ?? [],
1629
1636
  }));
@@ -1990,11 +1997,25 @@ export async function executeProviderApiRequest(
1990
1997
  ...(args.connectionId ? { connectionId: args.connectionId } : {}),
1991
1998
  },
1992
1999
  response,
1993
- guidance:
2000
+ guidance: [
1994
2001
  "This was a raw provider API request. Use provider docs/spec URLs to choose endpoints and include method/path/status plus relevant filters in the methodology. Prefer this escape hatch whenever canned actions are too narrow.",
2002
+ providerAccessErrorGuidance(config, response.status),
2003
+ ]
2004
+ .filter(Boolean)
2005
+ .join(" "),
1995
2006
  };
1996
2007
  }
1997
2008
 
2009
+ const PROVIDER_ACCESS_ERROR_STATUSES = new Set([401, 403, 404]);
2010
+
2011
+ function providerAccessErrorGuidance(
2012
+ config: ProviderApiConfig,
2013
+ status: number,
2014
+ ): string | null {
2015
+ if (!PROVIDER_ACCESS_ERROR_STATUSES.has(status)) return null;
2016
+ return config.accessErrorGuidance ?? null;
2017
+ }
2018
+
1998
2019
  /**
1999
2020
  * Resolve a provider OAuth token for a trusted server-side integration bridge
2000
2021
  * such as a CRM adapter or Google Picker. Callers must keep the result out of
@@ -143,7 +143,7 @@ function slugifyDocId(value: string): string {
143
143
 
144
144
  async function loadAgentBundleDocs(): Promise<DocFull[]> {
145
145
  try {
146
- const { loadAgentsBundle, getRuntimeSkills } =
146
+ const { loadAgentsBundle, getRuntimeSkills, skillSubfileDocsSlug } =
147
147
  await import("../../server/agents-bundle.js");
148
148
  const bundle = await loadAgentsBundle();
149
149
  const docs: DocFull[] = [];
@@ -174,6 +174,17 @@ async function loadAgentBundleDocs(): Promise<DocFull[]> {
174
174
  description: skill.meta.description,
175
175
  body: skill.content,
176
176
  });
177
+ // Progressive-disclosure sub-files (e.g. `references/*.md`) get their
178
+ // own searchable/readable doc so the "also contains" pointers the
179
+ // skill prompt block advertises actually resolve to something.
180
+ for (const [relPath, content] of Object.entries(skill.files)) {
181
+ docs.push({
182
+ slug: skillSubfileDocsSlug(skill.meta.name, relPath),
183
+ title: `Skill: ${skill.meta.name} — ${relPath}`,
184
+ description: `Reference file from the "${skill.meta.name}" skill (${relPath}).`,
185
+ body: content,
186
+ });
187
+ }
177
188
  }
178
189
  return docs;
179
190
  } catch {
@@ -1,6 +1,11 @@
1
1
  import { ACTION_CHAT_UI_DATA_WIDGET_RENDERER } from "../../action-ui.js";
2
2
  import type { ActionEntry } from "../../agent/production-agent.js";
3
- import { dataWidgetResultSchema } from "../../data-widgets/index.js";
3
+ import {
4
+ clampDataWidgetRows,
5
+ DATA_WIDGET_MAX_CHART_POINTS,
6
+ DATA_WIDGET_MAX_ROWS,
7
+ dataWidgetResultSchema,
8
+ } from "../../data-widgets/index.js";
4
9
  import { getRequestRunContext } from "../request-context.js";
5
10
 
6
11
  // ---------------------------------------------------------------------------
@@ -559,8 +564,7 @@ export function createDataWidgetActionEntries(): Record<string, ActionEntry> {
559
564
  description: "Render a validated native data table or chart in chat.",
560
565
  },
561
566
  tool: {
562
- description:
563
- "Render a native Agent-Native chat data widget from compact, real data you already retrieved or the user provided. Use this for in-chat tables, charts, graphs, trends, and compact reports when no domain-specific action already returns a native widget. Never fabricate rows or metrics just to make a chart.",
567
+ description: `Render a native Agent-Native chat data widget from compact, real data you already retrieved or the user provided. Use this for in-chat tables, charts, graphs, trends, and compact reports when no domain-specific action already returns a native widget. Never fabricate rows or metrics just to make a chart. Rows travel as tool arguments you type out one token at a time, so this is only for already-summarized data: at most ${DATA_WIDGET_MAX_ROWS} table rows and ${DATA_WIDGET_MAX_CHART_POINTS} chart points (anything beyond that is dropped). For a larger result set, aggregate it first, or state the total and show only the top rows — never re-serialize a full query result here.`,
564
568
  parameters: {
565
569
  type: "object",
566
570
  properties: {
@@ -602,7 +606,8 @@ export function createDataWidgetActionEntries(): Record<string, ActionEntry> {
602
606
  required: ["widget"],
603
607
  },
604
608
  },
605
- run: async (args) => dataWidgetResultSchema.parse(args),
609
+ run: async (args) =>
610
+ clampDataWidgetRows(dataWidgetResultSchema.parse(args)),
606
611
  },
607
612
  };
608
613
  }
@@ -15,7 +15,6 @@ import {
15
15
  FRAMEWORK_CONTEXT_SECTIONS,
16
16
  } from "./context-tools.js";
17
17
  import { lazyFs } from "./lazy-fs.js";
18
- import { compactPromptLine } from "./prompt-resources.js";
19
18
 
20
19
  // ---------------------------------------------------------------------------
21
20
  // Framework-level system prompt assembly (production/dev, full/compact),
@@ -23,8 +22,6 @@ import { compactPromptLine } from "./prompt-resources.js";
23
22
  // block, and the codebase file-tree walker used by a few dev-mode tools.
24
23
  // ---------------------------------------------------------------------------
25
24
 
26
- const MAX_ACTION_SUMMARY_DESCRIPTION_CHARS = 140;
27
-
28
25
  /**
29
26
  * Framework-level instructions injected into every agent's system prompt.
30
27
  * Prompt text lives in packages/core/src/server/prompts/ so this file stays
@@ -60,68 +57,30 @@ export function buildFrameworkPrompts(
60
57
  const extensionInstructionsFull = extensionToolsEnabled
61
58
  ? `### Generative UI and Extensions (Mini-Apps)
62
59
 
63
- In Act mode, if the user asks for generated interactive UI in chat, choose the smallest extension action that matches the lifetime:
64
-
65
- - For a **one-time inline UI** that answers the current chat turn (knobs, controls, pickers, calculators, temporary dashboards, visualizers), call \`render-inline-extension\` immediately with a self-contained Alpine.js HTML body. It renders inside the transcript and is not saved.
66
- - For a **reusable or saved UI** (an extension/widget/dashboard/calculator/mini-app the user can reopen from Extensions), call \`create-extension\` with a self-contained Alpine.js HTML body. It saves to the Extensions view and also renders inline in chat.
67
- - To **reuse an existing saved extension inline**, call \`show-extension-inline\` with its id, or a search string when the id is unknown.
68
-
69
- These are **NOT** source-code changes and do **NOT** go through \`connect-builder\`. Extensions are sandboxed mini-apps — no source files are touched, no PR is opened, no build is required. Saved extensions can be edited later via \`update-extension\`.
60
+ In Act mode, if the user asks for generated interactive UI in chat, choose the smallest extension action for the lifetime: \`render-inline-extension\` (one-off, chat-only), \`create-extension\` (saved/reusable), \`show-extension-inline\` (reopen a saved one), or \`update-extension\` (edit an existing one) — call the right one directly, without a "let me build…" preamble. Each tool's own description covers its exact use case, arguments, and available helpers (appAction, dbQuery, extensionData, agentNative.ui.output, etc.). Extensions are sandboxed mini-apps, not source-code changes, and never go through \`connect-builder\`.
70
61
 
71
62
  If the app exposes native actions or instructions for dashboards, reports, analyses, charts, documents, decks, or other domain artifacts, use those app-native actions first. Choose an extension only when the user explicitly asks for an extension/custom mini-app, or when the app's native artifact format cannot faithfully express the requested interaction.
72
63
 
73
- Keep \`create-extension\` payloads compact enough to finish quickly. For complex extensions, create a useful working v1 first, then call \`update-extension\` with focused edits for refinements instead of trying to assemble one enormous initial tool input.
74
-
75
- 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.
76
-
77
- 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 call \`update-extension\` with exactly \`id\`, \`operation\`, and \`payloadJson\`; encode the operation payload as a JSON string and never send empty placeholder fields. After one content read, keep the body in working memory and use \`operation="edit"\` with focused \`edits\`/\`patches\` inside \`payloadJson\`; do not loop on repeated \`get-extension\` + \`run-code\` string scans before writing. For a data-only repair, preserve the existing layout, CSS, copy, and interactions. Use \`operation="replace"\` only when the user explicitly requests a broad visual rewrite or supplies a complete replacement body. Use \`operation="metadata"\` for name/description/icon, and use \`set-resource-visibility\` for sharing changes. If a focused patch fails, read the current body and change the target rather than retrying identical arguments. 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.
78
-
79
- 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.
80
-
81
- Note: "extension" is the user-facing primitive (the sandboxed Alpine.js mini-app). Don't confuse it with the LLM concept of "tools" (function calls) — those are how you invoke ANY action, including \`create-extension\` itself.
82
-
83
- 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. If the user wants a shared extension removed only from their view, use \`hide-extension\` — do not query or mutate the legacy \`tools\` table directly.
84
-
85
- ### Extensions vs. Code Changes — Pick the Right Path
86
-
87
- Route by the exact outcome, not by whether the user calls it an extension. Extensions render in their own sandboxed iframe, either on their own page or inside an existing named slot. They CANNOT change the host app's nav, restyle or inject elements into existing native components, replace built-in views, or render at an arbitrary location that has no slot.
64
+ Editing an existing extension (fix, restyle, rename, add behavior) is a SQL data update call \`update-extension\` directly using the extensionId from \`<current-screen>\`/\`<current-url>\` when present; never call \`connect-builder\` for it.
88
65
 
89
- <routing>
90
- | The request is for… | Path |
91
- | ---------------------------------------------------------------- | ------------------------------ |
92
- | A one-off interactive answer inside chat (controls, picker, calculator, temporary visualizer) | \`render-inline-extension\` — inline only |
93
- | A new self-contained surface (widget, dashboard, calculator, viewer, list, tracker) | \`create-extension\` — ships instantly, no PR |
94
- | Loading a saved extension inside chat | \`show-extension-inline\` |
95
- | Editing an existing extension (fix, restyle, rename, add behavior) | \`update-extension\` |
96
- | The host app's own chrome (nav bar, sidebar, layout, routes, shipped components, existing styles, business logic) | \`connect-builder\` — a real source-code change |
97
- | UI inside or beside a native component where no named slot exists | \`connect-builder\` — add the native UI or a suitable slot in source |
98
- | Ambiguous, satisfiable either way (e.g. "give me an unread view") | \`render-inline-extension\` for chat-only, \`create-extension\` for reusable |
99
- </routing>
66
+ Extensions render only on their own page or inside an existing named slot; they cannot inject UI into arbitrary native components. If an extension could only approximate the request in a different location, do not silently downgrade the requirement and do not end with "extensions cannot do that." Briefly explain the boundary, then follow the normal source-code handoff so the app can still be customized fully.
100
67
 
101
- If an extension could only approximate the request in a different location, do not silently downgrade the requirement and do not end with "extensions cannot do that." Briefly explain the boundary, then follow the normal source-code handoff so the app can still be customized fully.
102
-
103
- Worked examples: "a widget showing unread emails grouped by sender", "a tracker for my newsletter subscriptions", "a custom kanban board with drag-and-drop rules the app does not have" → \`create-extension\`. "Add an Unread tab to the left navigation", "show local time beside every native Calendar attendee row", "make the subject lines wrap", "change the inbox grouping logic", "add a field to the compose form" → \`connect-builder\`.`
68
+ For helper APIs, Alpine.js patterns, the extension-vs-code-change boundary, and worked examples, read the \`extensions\` and \`generative-ui\` skills.`
104
69
  : `### Extensions Disabled
105
70
 
106
71
  Extension creation and management tools are disabled for this app. Do not claim you can create, edit, hide, or delete Agent-Native extensions unless the template exposes its own typed action for that workflow. For requests that would otherwise be handled as an extension/widget/dashboard/calculator mini-app, explain that this app has disabled extension tools and use the app's available actions instead.`;
107
72
  const extensionInstructionsCompact = extensionToolsEnabled
108
73
  ? `### Generative UI and Extensions (Mini-Apps)
109
74
 
110
- In Act mode, if the user asks for generated interactive UI in chat, call \`render-inline-extension\` for one-time inline controls/knobs/calculators/visualizers that do not need saving. If the user asks for an **extension**, **widget**, **dashboard**, **calculator**, or **mini-app** that should be reusable or saved, call \`create-extension\` with a self-contained Alpine.js HTML body. To load a saved extension inline, call \`show-extension-inline\`. These are NOT code changes extensions are sandboxed mini-apps. Do not preface with "let me build…" — just call the right extension action.
75
+ In Act mode, choose the smallest extension action for the lifetime: \`render-inline-extension\` (one-off, chat-only), \`create-extension\` (saved/reusable), \`show-extension-inline\` (reopen a saved one), or \`update-extension\` (edit an existing one) each tool's own description covers its use case and helpers. These are sandboxed mini-apps, not code changes; never route them through \`connect-builder\`. Do not preface with "let me build…" — just call the right extension action.
111
76
 
112
77
  Use app-native artifact actions first when they exist for dashboards, reports, analyses, charts, documents, decks, or similar domain artifacts. Pick \`create-extension\` only for explicit extension/custom mini-app requests or for behavior the native artifact format cannot support.
113
78
 
114
- Keep the first \`create-extension\` call compact and working. If the request is complex, create the v1 first and then refine with focused \`update-extension\` edits.
115
-
116
- 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.
117
-
118
- 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 call \`update-extension\` with exactly \`id\`, \`operation\`, and \`payloadJson\`; encode the operation payload as a JSON string and never send empty placeholder fields. After one content read, use \`operation="edit"\` with focused \`edits\`/\`patches\` inside \`payloadJson\`; do not repeatedly re-read and scan the same HTML with \`run-code\` before writing. For a data-only repair, preserve the existing layout, CSS, copy, and interactions. Use \`operation="replace"\` only when the user explicitly requests a broad visual rewrite or supplies a complete replacement body. Use \`operation="metadata"\` for name/description/icon, and use \`set-resource-visibility\` for sharing changes. If a focused patch fails, read the current body and change the target rather than retrying identical arguments. 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.
79
+ Editing an existing extension is a data update call \`update-extension\` directly using the extensionId from \`<current-screen>\`/\`<current-url>\` when present; never \`connect-builder\`.
119
80
 
120
- 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.
81
+ Extensions can render only on their own page or in an existing named slot; they cannot inject UI into arbitrary native components. If the exact request changes host chrome, native components, layout, styles, routes, business logic, or needs placement where no slot exists, treat it as a source-code change and use the normal \`connect-builder\` flow even if the user called it an extension. Never stop at "extensions cannot do that" or silently offer a different placement; explain the boundary briefly and continue the code-change handoff.
121
82
 
122
- ### Extensions vs. Code Changes Pick the Right Path
123
-
124
- If the user wants a **one-off interactive answer in chat**, use \`render-inline-extension\`. If they want a **new reusable self-contained surface** (custom widget, dashboard, list, viewer, calculator), use \`create-extension\` — extensions ship instantly without a PR. Extensions can render only on their own page or in an existing named slot; they cannot inject UI into arbitrary native components. If the exact request changes host chrome, native components, layout, styles, routes, business logic, or needs placement where no slot exists, treat it as a source-code change and use the normal \`connect-builder\` flow even if the user called it an extension. Never stop at "extensions cannot do that" or silently offer a different placement; explain the boundary briefly and continue the code-change handoff.`
83
+ See the \`extensions\` and \`generative-ui\` skills for helper APIs, Alpine.js patterns, and worked examples.`
125
84
  : `### Extensions Disabled
126
85
 
127
86
  Extension creation and management tools are disabled for this app. Do not claim you can create, edit, hide, or delete Agent-Native extensions unless the template exposes its own typed action for that workflow.`;
@@ -265,15 +224,20 @@ export async function buildSchemaBlock(
265
224
 
266
225
  /**
267
226
  * Generates a system prompt section describing registered template actions.
268
- * This helps the agent prefer template-specific actions over raw db-query/db-exec.
269
227
  *
270
228
  * Two output modes:
271
229
  *
272
230
  * - `"tool"` — used in production, where template actions are registered
273
- * as native Anthropic tools. Output reads `name(arg*: type; ...) desc`.
231
+ * as native Anthropic tools. The native tool schema already carries each
232
+ * action's name, full description, and parameters, so this mode does NOT
233
+ * re-list every action — it only surfaces what the tool list can't:
234
+ * native-chat-widget annotations and a `tool-search` pointer for actions
235
+ * omitted from the initial tool set.
274
236
  * - `"cli"` — used in dev, where template actions are NOT registered as
275
237
  * native tools and must be invoked via `bash(command="pnpm action ...")`.
276
- * Output reads `pnpm action name --arg <type> [--opt <type>] desc`.
238
+ * This listing is load-bearing here (there is no tool schema to fall
239
+ * back on), so it still emits the full
240
+ * `pnpm action name --arg <type> [--opt <type>] — desc` line per action.
277
241
  */
278
242
  export function generateActionsPrompt(
279
243
  registry: Record<string, ActionEntry>,
@@ -294,23 +258,31 @@ export function generateActionsPrompt(
294
258
  : "";
295
259
 
296
260
  if (mode === "tool") {
297
- const summaryLines = actionEntries.map(([name, entry]) => {
298
- const desc = compactPromptLine(
299
- entry.tool.description,
300
- MAX_ACTION_SUMMARY_DESCRIPTION_CHARS,
261
+ // Native tool schemas already carry name + full description + params
262
+ // for every action, so this section only needs to surface what the tool
263
+ // list itself can't: which actions render a native chat widget, and
264
+ // which actions exist but aren't loaded as initial tools yet.
265
+ const widgetLines = actionEntries
266
+ .filter(([, entry]) => typeof entry.chatUI?.renderer === "string")
267
+ .map(
268
+ ([name, entry]) =>
269
+ `- \`${name}\` — Native chat widget: \`${entry.chatUI?.renderer ?? ""}\`.`,
301
270
  );
302
- return `- \`${name}\` — ${desc}${nativeWidgetNote(entry)}`;
303
- });
304
271
 
305
- return `\n\n## Available Actions
306
-
307
- **Use these actions directly as tool calls.** They handle database access, validation, and business logic internally. The native tool schemas contain the full parameter details.
272
+ const sections: string[] = [];
273
+ if (widgetLines.length > 0) {
274
+ sections.push(
275
+ `**Actions that render a native chat widget** — call these directly for their table/chart/insights view instead of recreating it in prose:\n\n${widgetLines.join("\n")}`,
276
+ );
277
+ }
278
+ if (omittedActionCount > 0) {
279
+ sections.push(
280
+ `${omittedActionCount} less-common app action${omittedActionCount === 1 ? " is" : "s are"} available on demand. Use \`tool-search\` with a specific capability query to load the matching schemas when needed.`,
281
+ );
282
+ }
283
+ if (sections.length === 0) return "";
308
284
 
309
- ${summaryLines.join("\n")}${
310
- omittedActionCount > 0
311
- ? `\n\n${omittedActionCount} less-common app action${omittedActionCount === 1 ? " is" : "s are"} available on demand. Use \`tool-search\` with a specific capability query to load the matching schemas when needed.`
312
- : ""
313
- }`;
285
+ return `\n\n## Available Actions\n\n${sections.join("\n\n")}`;
314
286
  }
315
287
 
316
288
  const lines = actionEntries.map(([name, entry]) => {
@@ -123,6 +123,7 @@ import {
123
123
  type ChatThreadScope,
124
124
  type ForkThreadSourceSnapshot,
125
125
  } from "../chat-threads/store.js";
126
+ import { isCheckpointRestorePath } from "../checkpoints/route-match.js";
126
127
  import { createDbAdminAgentTools } from "../db-admin/agent-tools.js";
127
128
  import { isTransientDatabaseError } from "../db/client.js";
128
129
  import {
@@ -4770,11 +4771,9 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
4770
4771
  }
4771
4772
  }
4772
4773
 
4773
- // POST /checkpoints — restore to a checkpoint
4774
- // h3 prefix-matches, so /checkpoints/restore hits this handler with
4775
- // event.path containing "/restore".
4776
- const remainder = (event.path || "").replace(/^\/+/, "");
4777
- if (method === "POST" && remainder.startsWith("restore")) {
4774
+ // POST /checkpoints/restore — restore to a checkpoint.
4775
+ const restorePath = event.path || event.node?.req?.url || "";
4776
+ if (method === "POST" && isCheckpointRestorePath(restorePath)) {
4778
4777
  if (!canToggle) {
4779
4778
  setResponseStatus(event, 403);
4780
4779
  return { error: "Checkpoints only available in dev mode" };
@@ -4785,17 +4784,25 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
4785
4784
  }
4786
4785
  const body = await readBody(event);
4787
4786
  const checkpointId = body?.checkpointId;
4788
- if (!checkpointId) {
4787
+ const restoreRunId =
4788
+ typeof body?.runId === "string" ? body.runId : "";
4789
+ if (!checkpointId && !restoreRunId) {
4789
4790
  setResponseStatus(event, 400);
4790
- return { error: "checkpointId is required" };
4791
+ return { error: "checkpointId or runId is required" };
4791
4792
  }
4792
4793
  try {
4793
- const { getCheckpointById } =
4794
+ const { getCheckpointById, getCheckpointByRunId } =
4794
4795
  await import("../checkpoints/store.js");
4795
- const checkpoint = await getCheckpointById(checkpointId);
4796
+ const checkpoint = checkpointId
4797
+ ? await getCheckpointById(checkpointId)
4798
+ : await getCheckpointByRunId(restoreRunId);
4796
4799
  if (!checkpoint) {
4797
4800
  setResponseStatus(event, 404);
4798
- return { error: "Checkpoint not found" };
4801
+ return {
4802
+ error: restoreRunId
4803
+ ? "No checkpoint was saved for this turn, so there is nothing to restore."
4804
+ : "Checkpoint not found",
4805
+ };
4799
4806
  }
4800
4807
  const owner = await getOwnerFromEvent(event);
4801
4808
  const thread = await getThread(checkpoint.threadId);
@@ -60,6 +60,16 @@ export interface Skill {
60
60
  * `ls` call. Empty array if the skill is single-file.
61
61
  */
62
62
  extraFiles: string[];
63
+ /**
64
+ * Text content of eligible sub-files (progressive-disclosure references),
65
+ * keyed by the same skill-dir-relative path used in `extraFiles`. Only
66
+ * populated for text extensions under the per-file/per-skill caps in
67
+ * `readSkillsDir` — files that exist but were skipped for size still show
68
+ * up in `extraFiles`, just not here. This is what makes reference content
69
+ * actually readable by the runtime agent (via docs-search); it is never
70
+ * injected into a prompt.
71
+ */
72
+ files: Record<string, string>;
63
73
  }
64
74
 
65
75
  export interface AgentsBundle {
@@ -176,6 +186,23 @@ const TEMPLATE_SKILLS_DIRS = [
176
186
  path.join(".agent", "skills"),
177
187
  ] as const;
178
188
 
189
+ /**
190
+ * Extensions eligible to have their content inlined into `Skill.files`.
191
+ * Binary/asset sub-files (images, scripts, etc.) are always listed in
192
+ * `extraFiles` but never read into memory.
193
+ */
194
+ const READABLE_SUBFILE_EXTENSIONS = new Set([".md", ".txt", ".json"]);
195
+ /**
196
+ * Per-file and per-skill caps on inlined reference content. This content is
197
+ * bundled into the virtual module (and therefore the server bundle) for
198
+ * every deployment target, so it must stay small even though it's never
199
+ * added to a prompt — only fetched on demand via docs-search. Measured
200
+ * against this repo's skills (largest single sub-file ~20KB, largest
201
+ * per-skill sub-file total ~83KB), these caps have generous headroom.
202
+ */
203
+ const MAX_SUBFILE_BYTES = 64 * 1024;
204
+ const MAX_SKILL_FILES_BYTES = 256 * 1024;
205
+
179
206
  /**
180
207
  * Paths to a workspace-core's agent resources, for merging into a template's
181
208
  * bundle. All fields optional — pass null for any missing piece.
@@ -217,6 +244,8 @@ function readSkillsDir(
217
244
  if (skipExistingNames && out[name]) continue; // Template wins
218
245
 
219
246
  const extraFiles: string[] = [];
247
+ const files: Record<string, string> = {};
248
+ let skillFilesBytes = 0;
220
249
  try {
221
250
  const walk = (subdir: string, prefix: string) => {
222
251
  for (const e of fs.readdirSync(subdir, { withFileTypes: true })) {
@@ -229,6 +258,17 @@ function readSkillsDir(
229
258
  } catch {}
230
259
  } else if (e.isFile() && e.name !== "SKILL.md") {
231
260
  extraFiles.push(rel);
261
+ const ext = path.extname(e.name).toLowerCase();
262
+ if (!READABLE_SUBFILE_EXTENSIONS.has(ext)) continue;
263
+ try {
264
+ const stat = fs.statSync(abs);
265
+ if (stat.size > MAX_SUBFILE_BYTES) continue;
266
+ if (skillFilesBytes + stat.size > MAX_SKILL_FILES_BYTES) {
267
+ continue;
268
+ }
269
+ files[rel] = fs.readFileSync(abs, "utf-8");
270
+ skillFilesBytes += stat.size;
271
+ } catch {}
232
272
  }
233
273
  }
234
274
  };
@@ -245,6 +285,7 @@ function readSkillsDir(
245
285
  content,
246
286
  dir: path.relative(rootForRelative, skillDirAbs).replace(/\\/g, "/"),
247
287
  extraFiles,
288
+ files,
248
289
  };
249
290
  } catch {
250
291
  // Skip unreadable skills
@@ -397,7 +438,7 @@ export function getDevelopmentSkills(bundle: AgentsBundle): Skill[] {
397
438
  );
398
439
  }
399
440
 
400
- function skillDocsSlug(name: string): string {
441
+ export function skillDocsSlug(name: string): string {
401
442
  return `skill-${name
402
443
  .trim()
403
444
  .toLowerCase()
@@ -405,6 +446,28 @@ function skillDocsSlug(name: string): string {
405
446
  .replace(/^-+|-+$/g, "")}`;
406
447
  }
407
448
 
449
+ function subfileSlugSuffix(relPath: string): string {
450
+ return relPath
451
+ .replace(/\.[^./]+$/, "")
452
+ .trim()
453
+ .toLowerCase()
454
+ .replace(/[^a-z0-9]+/g, "-")
455
+ .replace(/^-+|-+$/g, "");
456
+ }
457
+
458
+ /**
459
+ * Slug docs-search resolves a skill sub-file (reference) content by. Kept in
460
+ * sync with the `skill-<name>--<subpath-slug>` docs it emits in
461
+ * `scripts/docs/search.ts` so the prompt hint always points at something the
462
+ * agent can actually read.
463
+ */
464
+ export function skillSubfileDocsSlug(
465
+ skillName: string,
466
+ relPath: string,
467
+ ): string {
468
+ return `${skillDocsSlug(skillName)}--${subfileSlugSuffix(relPath)}`;
469
+ }
470
+
408
471
  function generateSkillsPromptBlockForEntries(
409
472
  entries: Skill[],
410
473
  mode: "runtime" | "development",
@@ -412,10 +475,26 @@ function generateSkillsPromptBlockForEntries(
412
475
  if (entries.length === 0) return "";
413
476
 
414
477
  const lines = entries.map((s) => {
415
- const extras =
416
- s.extraFiles.length > 0
417
- ? ` (also contains: ${s.extraFiles.join(", ")})`
418
- : "";
478
+ let extras = "";
479
+ if (s.extraFiles.length > 0) {
480
+ if (mode === "runtime") {
481
+ const readable = s.extraFiles.filter((f) => f in s.files);
482
+ const unreadable = s.extraFiles.filter((f) => !(f in s.files));
483
+ const parts: string[] = [];
484
+ if (readable.length > 0) {
485
+ const refIds = readable.map((f) => subfileSlugSuffix(f)).join(", ");
486
+ parts.push(
487
+ `refs via docs-search --slug "${skillDocsSlug(s.meta.name)}--<ref>": ${refIds}`,
488
+ );
489
+ }
490
+ if (unreadable.length > 0) {
491
+ parts.push(`also contains: ${unreadable.join(", ")}`);
492
+ }
493
+ extras = ` (${parts.join("; ")})`;
494
+ } else {
495
+ extras = ` (also contains: ${s.extraFiles.join(", ")})`;
496
+ }
497
+ }
419
498
  const runtimeHint =
420
499
  mode === "runtime"
421
500
  ? ` Read with \`docs-search --slug "${skillDocsSlug(s.meta.name)}"\` before starting a task it applies to.`
@@ -81,7 +81,7 @@ import {
81
81
  } from "../mcp/route-paths.js";
82
82
  import { readBody } from "../server/h3-helpers.js";
83
83
  import { putSetting } from "../settings/store.js";
84
- import { DEFAULT_SSR_CACHE_HEADERS } from "../shared/cache-control.js";
84
+ import { resolveSsrCacheHeaders } from "../shared/cache-control.js";
85
85
  import { extractOAuthStateAppId } from "../shared/oauth-state.js";
86
86
  import {
87
87
  AGENT_NATIVE_SOCIAL_IMAGE_ALT,
@@ -1658,8 +1658,9 @@ function loginHtmlResponse(loginHtml: string, event: H3Event): Response {
1658
1658
  // template roots do not invoke origin just to render anonymous login UI.
1659
1659
  // The login markup is env-INDEPENDENT (a Google-only app always renders
1660
1660
  // a working button); the analytics script is public build configuration,
1661
- // not user/session state. Never downgrade this to private/no-store.
1662
- ...DEFAULT_SSR_CACHE_HEADERS,
1661
+ // not user/session state. Never vary this per request — the
1662
+ // deployment-wide override inside the resolver is the only knob.
1663
+ ...resolveSsrCacheHeaders(),
1663
1664
  "X-Robots-Tag": "noindex, nofollow",
1664
1665
  },
1665
1666
  },