@agent-native/core 0.132.2 → 0.133.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 (437) hide show
  1. package/corpus/README.md +2 -2
  2. package/corpus/core/CHANGELOG.md +181 -0
  3. package/corpus/core/package.json +1 -1
  4. package/corpus/core/src/a2a/correlation.ts +11 -1
  5. package/corpus/core/src/a2a/types.ts +11 -3
  6. package/corpus/core/src/agent/engine/ai-sdk-engine.ts +61 -46
  7. package/corpus/core/src/agent/engine/builder-engine.ts +22 -10
  8. package/corpus/core/src/agent/engine/error-detail.ts +184 -3
  9. package/corpus/core/src/agent/engine/failure-taxonomy.ts +123 -0
  10. package/corpus/core/src/agent/engine/index.ts +8 -0
  11. package/corpus/core/src/agent/engine/registry.ts +92 -8
  12. package/corpus/core/src/agent/engine/translate-ai-sdk.ts +17 -2
  13. package/corpus/core/src/agent/production-agent.ts +13 -33
  14. package/corpus/core/src/agent/run-loop-with-resume.ts +1 -1
  15. package/corpus/core/src/agent/run-manager.ts +43 -14
  16. package/corpus/core/src/agent/run-store.ts +49 -7
  17. package/corpus/core/src/agent/thread-data-builder.ts +36 -4
  18. package/corpus/core/src/cli/templates-meta.ts +13 -0
  19. package/corpus/core/src/cli/workspace-dev.ts +1 -0
  20. package/corpus/core/src/client/error-format.ts +12 -0
  21. package/corpus/core/src/credentials/index.ts +51 -12
  22. package/corpus/core/src/extensions/url-safety.ts +46 -12
  23. package/corpus/core/src/integrations/adapters/slack.ts +32 -10
  24. package/corpus/core/src/integrations/google-docs-poller.ts +12 -1
  25. package/corpus/core/src/integrations/installations-store.ts +30 -0
  26. package/corpus/core/src/integrations/plugin.ts +5 -5
  27. package/corpus/core/src/integrations/types.ts +7 -0
  28. package/corpus/core/src/integrations/webhook-handler.ts +24 -1
  29. package/corpus/core/src/jobs/background-automation-runner.ts +38 -1
  30. package/corpus/core/src/provider-api/index.ts +8 -2
  31. package/corpus/core/src/scripts/call-agent.ts +6 -0
  32. package/corpus/core/src/server/agent-chat-plugin.ts +30 -9
  33. package/corpus/core/src/server/agent-discovery.ts +2 -0
  34. package/corpus/core/src/server/builder-design-systems.ts +21 -0
  35. package/corpus/core/src/server/credential-provider.ts +51 -12
  36. package/corpus/core/src/server/index.ts +1 -0
  37. package/corpus/core/src/server/onboarding-html.ts +37 -2
  38. package/corpus/core/src/shared/reasoning-effort.ts +1 -1
  39. package/corpus/core/src/templates/workspace-core/.agents/skills/a2a-protocol/SKILL.md +11 -0
  40. package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +6 -2
  41. package/corpus/templates/assets/app/components/layout/Sidebar.tsx +39 -19
  42. package/corpus/templates/assets/changelog/2026-07-31-the-agent-native-logo-stays-visible-when-the-sidebar-is-coll.md +6 -0
  43. package/corpus/templates/brain/app/components/layout/Sidebar.tsx +30 -3
  44. package/corpus/templates/brain/changelog/2026-07-31-clicking-the-agent-native-logo-now-toggles-the-app-sidebar.md +6 -0
  45. package/corpus/templates/calendar/app/components/layout/AppLayout.tsx +1 -1
  46. package/corpus/templates/calendar/app/components/layout/Sidebar.tsx +54 -25
  47. package/corpus/templates/calendar/changelog/2026-07-31-the-agent-native-logo-stays-visible-when-the-sidebar-is-coll.md +6 -0
  48. package/corpus/templates/chat/app/components/layout/Sidebar.tsx +30 -3
  49. package/corpus/templates/chat/changelog/2026-07-31-clicking-the-agent-native-logo-now-toggles-the-app-sidebar.md +6 -0
  50. package/corpus/templates/clips/app/components/library/library-layout.tsx +37 -21
  51. package/corpus/templates/clips/changelog/2026-07-31-the-agent-native-logo-stays-visible-when-the-sidebar-is-coll.md +6 -0
  52. package/corpus/templates/clips/desktop/src/hooks/useMediaDevices.ts +1 -1
  53. package/corpus/templates/clips/desktop/src/lib/media-capture-constraints.ts +1 -1
  54. package/corpus/templates/content/app/components/sidebar/DocumentSidebar.tsx +34 -17
  55. package/corpus/templates/content/changelog/2026-07-31-the-agent-native-logo-stays-visible-when-the-sidebar-is-coll.md +6 -0
  56. package/corpus/templates/design/.agents/skills/design-systems/SKILL.md +6 -2
  57. package/corpus/templates/design/actions/create-design-system.ts +1 -0
  58. package/corpus/templates/design/actions/set-default-design-system.ts +34 -26
  59. package/corpus/templates/design/app/components/layout/Sidebar.tsx +21 -4
  60. package/corpus/templates/design/app/i18n-data.ts +39 -0
  61. package/corpus/templates/design/app/pages/DesignSystemSetup.tsx +229 -12
  62. package/corpus/templates/design/app/pages/DesignSystems.tsx +10 -4
  63. package/corpus/templates/design/changelog/2026-07-31-clicking-the-agent-native-logo-now-toggles-the-app-sidebar.md +6 -0
  64. package/corpus/templates/design/changelog/2026-07-31-design-system-indexing-keeps-your-chosen-name-when-you-uploa.md +6 -0
  65. package/corpus/templates/design/server/lib/builder-design-system-proxy.ts +19 -4
  66. package/corpus/templates/dispatch/AGENTS.md +4 -0
  67. package/corpus/templates/factory/.agents/skills/actions/SKILL.md +562 -0
  68. package/corpus/templates/factory/.agents/skills/adding-a-feature/SKILL.md +198 -0
  69. package/corpus/templates/factory/.agents/skills/agent-native-docs/SKILL.md +115 -0
  70. package/corpus/templates/factory/.agents/skills/agent-native-toolkit/SKILL.md +182 -0
  71. package/corpus/templates/factory/.agents/skills/capture-learnings/SKILL.md +89 -0
  72. package/corpus/templates/factory/.agents/skills/create-skill/SKILL.md +221 -0
  73. package/corpus/templates/factory/.agents/skills/customizing-agent-native/SKILL.md +220 -0
  74. package/corpus/templates/factory/.agents/skills/delegate-to-agent/SKILL.md +263 -0
  75. package/corpus/templates/factory/.agents/skills/factory-graphs/SKILL.md +52 -0
  76. package/corpus/templates/factory/.agents/skills/feature-flags/SKILL.md +169 -0
  77. package/corpus/templates/factory/.agents/skills/frontend-design/SKILL.md +174 -0
  78. package/corpus/templates/factory/.agents/skills/real-time-sync/SKILL.md +232 -0
  79. package/corpus/templates/factory/.agents/skills/security/SKILL.md +324 -0
  80. package/corpus/templates/factory/.agents/skills/self-modifying-code/SKILL.md +119 -0
  81. package/corpus/templates/factory/.agents/skills/shadcn-ui/SKILL.md +123 -0
  82. package/corpus/templates/factory/.agents/skills/sharing/SKILL.md +232 -0
  83. package/corpus/templates/factory/.agents/skills/storing-data/SKILL.md +178 -0
  84. package/corpus/templates/factory/.agents/skills/upgrade-agent-native/SKILL.md +122 -0
  85. package/corpus/templates/factory/.env.example +24 -0
  86. package/corpus/templates/factory/.ignore +0 -0
  87. package/corpus/templates/factory/.oxfmtrc.json +8 -0
  88. package/corpus/templates/factory/AGENTS.md +90 -0
  89. package/corpus/templates/factory/CHANGELOG.md +10 -0
  90. package/corpus/templates/factory/DEVELOPING.md +185 -0
  91. package/corpus/templates/factory/README.md +64 -0
  92. package/corpus/templates/factory/_gitignore +42 -0
  93. package/corpus/templates/factory/actions/add-factory-comment.ts +55 -0
  94. package/corpus/templates/factory/actions/approve-factory-item.ts +214 -0
  95. package/corpus/templates/factory/actions/babysit-pull-request.ts +126 -0
  96. package/corpus/templates/factory/actions/evaluate-triage-item.ts +172 -0
  97. package/corpus/templates/factory/actions/get-factory-graph.ts +62 -0
  98. package/corpus/templates/factory/actions/get-triage-config.ts +42 -0
  99. package/corpus/templates/factory/actions/get-triage-item.ts +74 -0
  100. package/corpus/templates/factory/actions/hello.ts +13 -0
  101. package/corpus/templates/factory/actions/ingest-github-observation.ts +100 -0
  102. package/corpus/templates/factory/actions/list-factories.ts +40 -0
  103. package/corpus/templates/factory/actions/list-factory-comments.ts +40 -0
  104. package/corpus/templates/factory/actions/list-triage-items.ts +85 -0
  105. package/corpus/templates/factory/actions/list-triage-rules.ts +44 -0
  106. package/corpus/templates/factory/actions/navigate.ts +41 -0
  107. package/corpus/templates/factory/actions/poll-slack-channel.ts +118 -0
  108. package/corpus/templates/factory/actions/reconcile-triage-run.ts +179 -0
  109. package/corpus/templates/factory/actions/record-triage-feedback.ts +58 -0
  110. package/corpus/templates/factory/actions/run.ts +2 -0
  111. package/corpus/templates/factory/actions/save-factory-graph.ts +129 -0
  112. package/corpus/templates/factory/actions/save-triage-config.ts +67 -0
  113. package/corpus/templates/factory/actions/save-triage-rule.ts +89 -0
  114. package/corpus/templates/factory/actions/suggest-factory-rules.ts +70 -0
  115. package/corpus/templates/factory/actions/view-screen.ts +73 -0
  116. package/corpus/templates/factory/app/components/factory/FactoryCanvas.tsx +441 -0
  117. package/corpus/templates/factory/app/components/factory/FactoryInspector.tsx +388 -0
  118. package/corpus/templates/factory/app/components/layout/Header.tsx +60 -0
  119. package/corpus/templates/factory/app/components/layout/Layout.tsx +190 -0
  120. package/corpus/templates/factory/app/components/layout/Sidebar.tsx +538 -0
  121. package/corpus/templates/factory/app/components/triage/triage-status-pill.tsx +28 -0
  122. package/corpus/templates/factory/app/components/ui/button.tsx +1 -0
  123. package/corpus/templates/factory/app/components/ui/card.tsx +1 -0
  124. package/corpus/templates/factory/app/components/ui/dropdown-menu.tsx +1 -0
  125. package/corpus/templates/factory/app/components/ui/input.tsx +1 -0
  126. package/corpus/templates/factory/app/components/ui/label.tsx +1 -0
  127. package/corpus/templates/factory/app/components/ui/sheet.tsx +1 -0
  128. package/corpus/templates/factory/app/components/ui/textarea.tsx +1 -0
  129. package/corpus/templates/factory/app/components/ui/toolkit-provider.tsx +17 -0
  130. package/corpus/templates/factory/app/components/ui/tooltip.tsx +1 -0
  131. package/corpus/templates/factory/app/design-system.ts +3 -0
  132. package/corpus/templates/factory/app/entry.client.tsx +22 -0
  133. package/corpus/templates/factory/app/entry.server.tsx +10 -0
  134. package/corpus/templates/factory/app/global.css +93 -0
  135. package/corpus/templates/factory/app/hooks/use-navigation-state.ts +113 -0
  136. package/corpus/templates/factory/app/i18n/en-US.ts +211 -0
  137. package/corpus/templates/factory/app/i18n/index.ts +34 -0
  138. package/corpus/templates/factory/app/i18n-data.ts +556 -0
  139. package/corpus/templates/factory/app/lib/agent-page.tsx +49 -0
  140. package/corpus/templates/factory/app/lib/app-config.ts +11 -0
  141. package/corpus/templates/factory/app/lib/tab-id.ts +1 -0
  142. package/corpus/templates/factory/app/lib/utils.ts +1 -0
  143. package/corpus/templates/factory/app/root.tsx +175 -0
  144. package/corpus/templates/factory/app/routes/_index.tsx +94 -0
  145. package/corpus/templates/factory/app/routes/agent.tsx +24 -0
  146. package/corpus/templates/factory/app/routes/chat.$threadId.tsx +1 -0
  147. package/corpus/templates/factory/app/routes/database.tsx +17 -0
  148. package/corpus/templates/factory/app/routes/extensions.$id.$slug.tsx +2 -0
  149. package/corpus/templates/factory/app/routes/extensions.$id.tsx +11 -0
  150. package/corpus/templates/factory/app/routes/extensions._index.tsx +11 -0
  151. package/corpus/templates/factory/app/routes/extensions.tsx +5 -0
  152. package/corpus/templates/factory/app/routes/factory.tsx +1003 -0
  153. package/corpus/templates/factory/app/routes/observability.tsx +19 -0
  154. package/corpus/templates/factory/app/routes/settings.tsx +89 -0
  155. package/corpus/templates/factory/app/routes/team.tsx +11 -0
  156. package/corpus/templates/factory/app/routes.ts +4 -0
  157. package/corpus/templates/factory/app/vite-env.d.ts +6 -0
  158. package/corpus/templates/factory/changelog/2026-06-24-a-new-settings-page-gives-quick-access-to-language-workspace.md +6 -0
  159. package/corpus/templates/factory/changelog/2026-06-24-added-a-language-picker-and-localized-app-chrome-for-support.md +6 -0
  160. package/corpus/templates/factory/changelog/2026-06-27-traditional-chinese-copy-uses-taiwan-terminology.md +6 -0
  161. package/corpus/templates/factory/changelog/2026-06-28-left-sidebar-collapse-motion-and-footer-chrome-are-quieter.md +6 -0
  162. package/corpus/templates/factory/changelog/2026-06-29-chat-layouts-adapt-when-the-agent-sidebar-is-open.md +6 -0
  163. package/corpus/templates/factory/changelog/2026-07-08-settings-are-cleaner-and-searchable.md +5 -0
  164. package/corpus/templates/factory/changelog/2026-07-10-chat-now-makes-ai-connection-setup-clear-without-shifting-th.md +6 -0
  165. package/corpus/templates/factory/changelog/2026-07-13-a-full-agent-page-now-brings-context-files-connections-jobs-.md +6 -0
  166. package/corpus/templates/factory/changelog/2026-07-14-chat-opens-reliably-on-hosted-deployments-instead-of-failing.md +6 -0
  167. package/corpus/templates/factory/changelog/2026-07-14-fixed-chat-template-startup-with-older-core-versions.md +6 -0
  168. package/corpus/templates/factory/changelog/2026-07-15-chat-navigation-focuses-on-chat-and-agent.md +6 -0
  169. package/corpus/templates/factory/changelog/2026-07-17-the-agent-chat-sidebar-stays-closed-until-you-open-it-or-sta.md +6 -0
  170. package/corpus/templates/factory/changelog/2026-07-22-compact-sidebar-footer.md +6 -0
  171. package/corpus/templates/factory/changelog/2026-07-22-full-page-chat-keeps-the-active-conversation-when-moving-to-.md +6 -0
  172. package/corpus/templates/factory/changelog/2026-07-22-manage-agent-navigation-now-uses-the-connected-nodes-icon.md +6 -0
  173. package/corpus/templates/factory/changelog/2026-07-22-recent-chats-are-easier-to-scan-and-expand.md +6 -0
  174. package/corpus/templates/factory/changelog/2026-07-23-full-page-chat-is-better-centered-with-quieter-chat-history-.md +6 -0
  175. package/corpus/templates/factory/changelog/2026-07-24-borderless-secondary-surfaces.md +6 -0
  176. package/corpus/templates/factory/changelog/2026-07-24-sidebar-footer-controls-follow-a-consistent-order.md +6 -0
  177. package/corpus/templates/factory/changelog/2026-07-25-settings-navigation-now-keeps-manage-agent-as-a-dedicated-li.md +6 -0
  178. package/corpus/templates/factory/changelog/2026-07-29-sidebar-footers-now-keep-feedback-search-and-collapse-togeth.md +6 -0
  179. package/corpus/templates/factory/changelog/2026-07-31-added-an-inspectable-observe-only-factory-queue-for-slack-.md +6 -0
  180. package/corpus/templates/factory/changelog/2026-07-31-clicking-the-agent-native-logo-now-toggles-the-app-sidebar.md +6 -0
  181. package/corpus/templates/factory/components.json +20 -0
  182. package/corpus/templates/factory/data/sync-config.json +1 -0
  183. package/corpus/templates/factory/learnings.defaults.md +5 -0
  184. package/corpus/templates/factory/netlify.toml +10 -0
  185. package/corpus/templates/factory/package.json +105 -0
  186. package/corpus/templates/factory/public/agent-native-icon-dark.svg +10 -0
  187. package/corpus/templates/factory/public/agent-native-icon-light.svg +10 -0
  188. package/corpus/templates/factory/public/agent-native-logo-dark.svg +21 -0
  189. package/corpus/templates/factory/public/agent-native-logo-light.svg +21 -0
  190. package/corpus/templates/factory/public/favicon.svg +1 -0
  191. package/corpus/templates/factory/public/icon-180.svg +1 -0
  192. package/corpus/templates/factory/public/icon-192.svg +1 -0
  193. package/corpus/templates/factory/public/icon-512.svg +1 -0
  194. package/corpus/templates/factory/public/manifest.json +21 -0
  195. package/corpus/templates/factory/react-router.config.ts +7 -0
  196. package/corpus/templates/factory/server/connectors/credentials.ts +129 -0
  197. package/corpus/templates/factory/server/connectors/slack.ts +129 -0
  198. package/corpus/templates/factory/server/db/index.ts +6 -0
  199. package/corpus/templates/factory/server/db/schema.ts +193 -0
  200. package/corpus/templates/factory/server/factory-graph/contracts.ts +212 -0
  201. package/corpus/templates/factory/server/factory-graph/store.ts +121 -0
  202. package/corpus/templates/factory/server/lib/require-workspace-member.ts +55 -0
  203. package/corpus/templates/factory/server/middleware/auth.ts +15 -0
  204. package/corpus/templates/factory/server/plugins/agent-chat.ts +58 -0
  205. package/corpus/templates/factory/server/plugins/auth.ts +14 -0
  206. package/corpus/templates/factory/server/plugins/factory-migrations.ts +247 -0
  207. package/corpus/templates/factory/server/plugins/factory-scheduler-job.ts +116 -0
  208. package/corpus/templates/factory/server/plugins/integrations.ts +46 -0
  209. package/corpus/templates/factory/server/routes/[...page].get.ts +5 -0
  210. package/corpus/templates/factory/server/routes/_agent-native/factory/builder-callback.post.ts +116 -0
  211. package/corpus/templates/factory/server/triage/ai-services-git.ts +197 -0
  212. package/corpus/templates/factory/server/triage/builder-executor.ts +118 -0
  213. package/corpus/templates/factory/server/triage/contracts.ts +164 -0
  214. package/corpus/templates/factory/server/triage/github-ingestion.ts +35 -0
  215. package/corpus/templates/factory/server/triage/guards.ts +121 -0
  216. package/corpus/templates/factory/server/triage/ids.ts +27 -0
  217. package/corpus/templates/factory/server/triage/pr-babysit.ts +100 -0
  218. package/corpus/templates/factory/server/triage/pr-monitor.ts +220 -0
  219. package/corpus/templates/factory/server/triage/slack-client.ts +55 -0
  220. package/corpus/templates/factory/server/triage/slack-poller.ts +152 -0
  221. package/corpus/templates/factory/ssr-entry.ts +15 -0
  222. package/corpus/templates/factory/tsconfig.json +21 -0
  223. package/corpus/templates/factory/vite.config.ts +19 -0
  224. package/corpus/templates/forms/app/components/layout/Sidebar.tsx +55 -5
  225. package/corpus/templates/forms/changelog/2026-07-31-the-agent-native-logo-stays-visible-when-the-sidebar-is-coll.md +6 -0
  226. package/corpus/templates/macros/app/components/layout/AppLayout.tsx +6 -2
  227. package/corpus/templates/plan/app/components/layout/Sidebar.tsx +21 -6
  228. package/corpus/templates/plan/changelog/2026-07-31-clicking-the-agent-native-logo-now-toggles-the-app-sidebar.md +6 -0
  229. package/corpus/templates/slides/.agents/skills/create-deck/SKILL.md +12 -0
  230. package/corpus/templates/slides/.agents/skills/design-systems/SKILL.md +9 -0
  231. package/corpus/templates/slides/.agents/skills/slide-editing/SKILL.md +11 -0
  232. package/corpus/templates/slides/AGENTS.md +5 -6
  233. package/corpus/templates/slides/actions/_await-fit-check.ts +20 -10
  234. package/corpus/templates/slides/actions/add-slide.ts +17 -4
  235. package/corpus/templates/slides/actions/create-design-system.ts +16 -4
  236. package/corpus/templates/slides/actions/delete-design-system.ts +18 -2
  237. package/corpus/templates/slides/actions/get-layout-overflows.ts +88 -0
  238. package/corpus/templates/slides/actions/import-file.ts +1 -0
  239. package/corpus/templates/slides/actions/index-design-system-with-builder.ts +8 -0
  240. package/corpus/templates/slides/actions/patch-deck.ts +48 -16
  241. package/corpus/templates/slides/actions/set-default-design-system.ts +49 -19
  242. package/corpus/templates/slides/actions/update-slide.ts +13 -3
  243. package/corpus/templates/slides/actions/view-screen.ts +87 -10
  244. package/corpus/templates/slides/app/components/deck/SlideRenderer.tsx +155 -28
  245. package/corpus/templates/slides/app/components/design-system/DesignSystemCard.tsx +21 -17
  246. package/corpus/templates/slides/app/components/design-system/DesignSystemSetup.tsx +849 -341
  247. package/corpus/templates/slides/app/components/editor/EditorSidebar.tsx +102 -2
  248. package/corpus/templates/slides/app/components/editor/PromptDialog.tsx +13 -16
  249. package/corpus/templates/slides/app/components/editor/SlideEditor.tsx +60 -12
  250. package/corpus/templates/slides/app/components/editor/SlideOverflowWarning.tsx +11 -1
  251. package/corpus/templates/slides/app/components/layout/Sidebar.tsx +66 -19
  252. package/corpus/templates/slides/app/i18n/en-US.ts +23 -0
  253. package/corpus/templates/slides/app/lib/normalize-slide-padding.ts +8 -15
  254. package/corpus/templates/slides/app/pages/DeckEditor.tsx +4 -3
  255. package/corpus/templates/slides/app/pages/DesignSystems.tsx +4 -3
  256. package/corpus/templates/slides/app/pages/Index.tsx +1 -1
  257. package/corpus/templates/slides/changelog/2026-07-31-design-system-details-now-show-their-source-and-indexing-sta.md +6 -0
  258. package/corpus/templates/slides/changelog/2026-07-31-design-system-indexing-keeps-your-chosen-name-when-you-uploa.md +6 -0
  259. package/corpus/templates/slides/changelog/2026-07-31-design-system-setup-keeps-focus-rings-visible-and-uses-a-sim.md +6 -0
  260. package/corpus/templates/slides/changelog/2026-07-31-skip-prompt-is-now-available-in-the-new-deck-prompt-header.md +6 -0
  261. package/corpus/templates/slides/changelog/2026-07-31-slides-now-detect-real-text-and-box-overflow-across-the-deck.md +6 -0
  262. package/corpus/templates/slides/changelog/2026-07-31-the-agent-native-logo-stays-visible-when-the-sidebar-is-coll.md +6 -0
  263. package/corpus/templates/slides/server/handlers/design-systems.ts +1 -0
  264. package/corpus/templates/slides/server/handlers/index-design-system-sources.ts +1 -0
  265. package/corpus/templates/slides/server/lib/builder-design-system-proxy.ts +23 -4
  266. package/corpus/templates/slides/server/plugins/agent-chat.ts +5 -0
  267. package/corpus/templates/slides/server/plugins/creative-context.ts +16 -3
  268. package/corpus/templates/slides/server/workspace-defaults.ts +5 -1
  269. package/corpus/templates/slides/shared/slide-fit.ts +26 -0
  270. package/corpus/templates/tasks/app/components/layout/Sidebar.tsx +30 -3
  271. package/corpus/templates/tasks/changelog/2026-07-31-clicking-the-agent-native-logo-now-toggles-the-app-sidebar.md +6 -0
  272. package/dist/a2a/correlation.d.ts +4 -1
  273. package/dist/a2a/correlation.d.ts.map +1 -1
  274. package/dist/a2a/correlation.js +8 -1
  275. package/dist/a2a/correlation.js.map +1 -1
  276. package/dist/a2a/types.d.ts +11 -3
  277. package/dist/a2a/types.d.ts.map +1 -1
  278. package/dist/a2a/types.js.map +1 -1
  279. package/dist/agent/engine/ai-sdk-engine.d.ts.map +1 -1
  280. package/dist/agent/engine/ai-sdk-engine.js +51 -41
  281. package/dist/agent/engine/ai-sdk-engine.js.map +1 -1
  282. package/dist/agent/engine/builder-engine.d.ts.map +1 -1
  283. package/dist/agent/engine/builder-engine.js +18 -8
  284. package/dist/agent/engine/builder-engine.js.map +1 -1
  285. package/dist/agent/engine/error-detail.d.ts +61 -0
  286. package/dist/agent/engine/error-detail.d.ts.map +1 -1
  287. package/dist/agent/engine/error-detail.js +145 -3
  288. package/dist/agent/engine/error-detail.js.map +1 -1
  289. package/dist/agent/engine/failure-taxonomy.d.ts +24 -0
  290. package/dist/agent/engine/failure-taxonomy.d.ts.map +1 -0
  291. package/dist/agent/engine/failure-taxonomy.js +88 -0
  292. package/dist/agent/engine/failure-taxonomy.js.map +1 -0
  293. package/dist/agent/engine/index.d.ts +2 -1
  294. package/dist/agent/engine/index.d.ts.map +1 -1
  295. package/dist/agent/engine/index.js +2 -1
  296. package/dist/agent/engine/index.js.map +1 -1
  297. package/dist/agent/engine/registry.d.ts +16 -0
  298. package/dist/agent/engine/registry.d.ts.map +1 -1
  299. package/dist/agent/engine/registry.js +71 -6
  300. package/dist/agent/engine/registry.js.map +1 -1
  301. package/dist/agent/engine/translate-ai-sdk.d.ts.map +1 -1
  302. package/dist/agent/engine/translate-ai-sdk.js +14 -2
  303. package/dist/agent/engine/translate-ai-sdk.js.map +1 -1
  304. package/dist/agent/production-agent.d.ts.map +1 -1
  305. package/dist/agent/production-agent.js +13 -24
  306. package/dist/agent/production-agent.js.map +1 -1
  307. package/dist/agent/run-loop-with-resume.js +1 -1
  308. package/dist/agent/run-loop-with-resume.js.map +1 -1
  309. package/dist/agent/run-manager.d.ts.map +1 -1
  310. package/dist/agent/run-manager.js +39 -10
  311. package/dist/agent/run-manager.js.map +1 -1
  312. package/dist/agent/run-store.d.ts +10 -0
  313. package/dist/agent/run-store.d.ts.map +1 -1
  314. package/dist/agent/run-store.js +38 -6
  315. package/dist/agent/run-store.js.map +1 -1
  316. package/dist/agent/thread-data-builder.d.ts.map +1 -1
  317. package/dist/agent/thread-data-builder.js +28 -4
  318. package/dist/agent/thread-data-builder.js.map +1 -1
  319. package/dist/cli/templates-meta.d.ts.map +1 -1
  320. package/dist/cli/templates-meta.js +13 -0
  321. package/dist/cli/templates-meta.js.map +1 -1
  322. package/dist/cli/workspace-dev.d.ts.map +1 -1
  323. package/dist/cli/workspace-dev.js +1 -0
  324. package/dist/cli/workspace-dev.js.map +1 -1
  325. package/dist/client/error-format.d.ts.map +1 -1
  326. package/dist/client/error-format.js +10 -0
  327. package/dist/client/error-format.js.map +1 -1
  328. package/dist/collab/struct-routes.d.ts +1 -1
  329. package/dist/credentials/index.d.ts +9 -2
  330. package/dist/credentials/index.d.ts.map +1 -1
  331. package/dist/credentials/index.js +50 -8
  332. package/dist/credentials/index.js.map +1 -1
  333. package/dist/extensions/url-safety.d.ts.map +1 -1
  334. package/dist/extensions/url-safety.js +38 -12
  335. package/dist/extensions/url-safety.js.map +1 -1
  336. package/dist/file-upload/actions/upload-image.d.ts +1 -1
  337. package/dist/integrations/adapters/slack.d.ts.map +1 -1
  338. package/dist/integrations/adapters/slack.js +25 -8
  339. package/dist/integrations/adapters/slack.js.map +1 -1
  340. package/dist/integrations/google-docs-poller.d.ts.map +1 -1
  341. package/dist/integrations/google-docs-poller.js +13 -1
  342. package/dist/integrations/google-docs-poller.js.map +1 -1
  343. package/dist/integrations/installations-store.d.ts +10 -0
  344. package/dist/integrations/installations-store.d.ts.map +1 -1
  345. package/dist/integrations/installations-store.js +24 -0
  346. package/dist/integrations/installations-store.js.map +1 -1
  347. package/dist/integrations/plugin.d.ts.map +1 -1
  348. package/dist/integrations/plugin.js +6 -5
  349. package/dist/integrations/plugin.js.map +1 -1
  350. package/dist/integrations/types.d.ts +7 -0
  351. package/dist/integrations/types.d.ts.map +1 -1
  352. package/dist/integrations/types.js.map +1 -1
  353. package/dist/integrations/webhook-handler.d.ts.map +1 -1
  354. package/dist/integrations/webhook-handler.js +16 -1
  355. package/dist/integrations/webhook-handler.js.map +1 -1
  356. package/dist/jobs/background-automation-runner.d.ts.map +1 -1
  357. package/dist/jobs/background-automation-runner.js +35 -2
  358. package/dist/jobs/background-automation-runner.js.map +1 -1
  359. package/dist/mcp/screen-memory-stdio.d.ts +7 -7
  360. package/dist/mcp/screen-memory-stdio.d.ts.map +1 -1
  361. package/dist/notifications/routes.d.ts +1 -1
  362. package/dist/observability/routes.d.ts +1 -1
  363. package/dist/provider-api/actions/custom-provider-registration.d.ts +14 -14
  364. package/dist/provider-api/actions/provider-api.d.ts +8 -8
  365. package/dist/provider-api/index.js +7 -3
  366. package/dist/provider-api/index.js.map +1 -1
  367. package/dist/resources/handlers.d.ts +1 -1
  368. package/dist/scripts/call-agent.d.ts.map +1 -1
  369. package/dist/scripts/call-agent.js +6 -1
  370. package/dist/scripts/call-agent.js.map +1 -1
  371. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  372. package/dist/server/agent-chat-plugin.js +25 -7
  373. package/dist/server/agent-chat-plugin.js.map +1 -1
  374. package/dist/server/agent-discovery.d.ts +2 -0
  375. package/dist/server/agent-discovery.d.ts.map +1 -1
  376. package/dist/server/agent-discovery.js.map +1 -1
  377. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  378. package/dist/server/builder-design-systems.d.ts +4 -1
  379. package/dist/server/builder-design-systems.d.ts.map +1 -1
  380. package/dist/server/builder-design-systems.js +11 -1
  381. package/dist/server/builder-design-systems.js.map +1 -1
  382. package/dist/server/credential-provider.d.ts.map +1 -1
  383. package/dist/server/credential-provider.js +49 -12
  384. package/dist/server/credential-provider.js.map +1 -1
  385. package/dist/server/index.d.ts +1 -1
  386. package/dist/server/index.d.ts.map +1 -1
  387. package/dist/server/index.js.map +1 -1
  388. package/dist/server/onboarding-html.d.ts.map +1 -1
  389. package/dist/server/onboarding-html.js +37 -2
  390. package/dist/server/onboarding-html.js.map +1 -1
  391. package/dist/shared/reasoning-effort.d.ts +1 -0
  392. package/dist/shared/reasoning-effort.d.ts.map +1 -1
  393. package/dist/shared/reasoning-effort.js +1 -1
  394. package/dist/shared/reasoning-effort.js.map +1 -1
  395. package/dist/templates/chat/app/components/layout/Sidebar.tsx +30 -3
  396. package/dist/templates/chat/changelog/2026-07-31-clicking-the-agent-native-logo-now-toggles-the-app-sidebar.md +6 -0
  397. package/dist/templates/workspace-core/.agents/skills/a2a-protocol/SKILL.md +11 -0
  398. package/package.json +1 -1
  399. package/src/a2a/correlation.ts +11 -1
  400. package/src/a2a/types.ts +11 -3
  401. package/src/agent/engine/ai-sdk-engine.ts +61 -46
  402. package/src/agent/engine/builder-engine.ts +22 -10
  403. package/src/agent/engine/error-detail.ts +184 -3
  404. package/src/agent/engine/failure-taxonomy.ts +123 -0
  405. package/src/agent/engine/index.ts +8 -0
  406. package/src/agent/engine/registry.ts +92 -8
  407. package/src/agent/engine/translate-ai-sdk.ts +17 -2
  408. package/src/agent/production-agent.ts +13 -33
  409. package/src/agent/run-loop-with-resume.ts +1 -1
  410. package/src/agent/run-manager.ts +43 -14
  411. package/src/agent/run-store.ts +49 -7
  412. package/src/agent/thread-data-builder.ts +36 -4
  413. package/src/cli/templates-meta.ts +13 -0
  414. package/src/cli/workspace-dev.ts +1 -0
  415. package/src/client/error-format.ts +12 -0
  416. package/src/credentials/index.ts +51 -12
  417. package/src/extensions/url-safety.ts +46 -12
  418. package/src/integrations/adapters/slack.ts +32 -10
  419. package/src/integrations/google-docs-poller.ts +12 -1
  420. package/src/integrations/installations-store.ts +30 -0
  421. package/src/integrations/plugin.ts +5 -5
  422. package/src/integrations/types.ts +7 -0
  423. package/src/integrations/webhook-handler.ts +24 -1
  424. package/src/jobs/background-automation-runner.ts +38 -1
  425. package/src/provider-api/index.ts +8 -2
  426. package/src/scripts/call-agent.ts +6 -0
  427. package/src/server/agent-chat-plugin.ts +30 -9
  428. package/src/server/agent-discovery.ts +2 -0
  429. package/src/server/builder-design-systems.ts +21 -0
  430. package/src/server/credential-provider.ts +51 -12
  431. package/src/server/index.ts +1 -0
  432. package/src/server/onboarding-html.ts +37 -2
  433. package/src/shared/reasoning-effort.ts +1 -1
  434. package/src/templates/chat/app/components/layout/Sidebar.tsx +30 -3
  435. package/src/templates/chat/changelog/2026-07-31-clicking-the-agent-native-logo-now-toggles-the-app-sidebar.md +6 -0
  436. package/src/templates/workspace-core/.agents/skills/a2a-protocol/SKILL.md +11 -0
  437. package/corpus/templates/clips/desktop/src/lib/media-device-selection.ts +0 -157
@@ -675,3 +675,33 @@ export async function getActiveIntegrationInstallationForTenant(
675
675
  ? toSafeInstallation(rowToRaw(rows[0] as Record<string, unknown>))
676
676
  : null;
677
677
  }
678
+
679
+ /**
680
+ * Every connected installation for a tenant, newest first.
681
+ *
682
+ * A workspace can legitimately have several apps of the same platform
683
+ * connected at once (e.g. a product-specific Slack app alongside a generic
684
+ * one). Callers that cannot name an app id must see that ambiguity rather
685
+ * than receive an arbitrary winner — picking the most recently updated row
686
+ * silently sends as whichever app happened to reconnect last.
687
+ */
688
+ export async function listActiveIntegrationInstallationsForTenant(
689
+ platform: string,
690
+ tenantId: string,
691
+ ): Promise<IntegrationInstallation[]> {
692
+ await ensureTable();
693
+ const { rows } = await getDbExec().execute({
694
+ sql: `SELECT * FROM ${TABLE}
695
+ WHERE platform = ? AND (team_id = ? OR enterprise_id = ?)
696
+ AND status = 'connected'
697
+ ORDER BY updated_at DESC`,
698
+ args: [
699
+ normalizePlatform(platform),
700
+ required(tenantId, "tenantId"),
701
+ required(tenantId, "tenantId"),
702
+ ],
703
+ });
704
+ return rows.map((row) =>
705
+ toSafeInstallation(rowToRaw(row as Record<string, unknown>)),
706
+ );
707
+ }
@@ -93,7 +93,6 @@ import {
93
93
  INTEGRATION_RETRY_SWEEP_TOKEN_SUBJECT,
94
94
  integrationDispatchScopeValue,
95
95
  isInIntegrationRecoveryRuntime,
96
- isIntegrationDurableDispatchConfigured,
97
96
  isIntegrationDurableDispatchEnabledForTask,
98
97
  } from "./integration-durable-dispatch.js";
99
98
  import {
@@ -1787,15 +1786,16 @@ export function createIntegrationsPlugin(
1787
1786
  setResponseStatus(event, 401);
1788
1787
  return { error: "Invalid or expired internal token" };
1789
1788
  }
1790
- if (!isIntegrationDurableDispatchConfigured()) {
1791
- return { ok: true, disabled: true };
1792
- }
1793
1789
  const webhookBaseUrl = getBaseUrl(event);
1794
1790
  const [pendingTasks, campaigns, a2aContinuations] = await Promise.all([
1791
+ // Portable (fire-and-forget) dispatch loses tasks whenever the
1792
+ // self-dispatch POST dies with the container, and the in-process
1793
+ // retry interval does not survive a serverless freeze. Sweeping only
1794
+ // durable scopes left those deployments with no recovery at all, so
1795
+ // the queue is swept regardless of dispatch mode.
1795
1796
  retryStuckPendingTasks({
1796
1797
  webhookBaseUrl,
1797
1798
  limit: 20,
1798
- durableOnly: true,
1799
1799
  }).catch((error) => {
1800
1800
  console.error(
1801
1801
  "[integrations] Pending-task recovery failed:",
@@ -163,6 +163,13 @@ export interface OutboundTarget {
163
163
  tenantId?: string;
164
164
  /** Managed installation id when the caller already resolved it. */
165
165
  installationId?: string;
166
+ /**
167
+ * Provider installation key identifying which connected app to send as.
168
+ * Required when a tenant has more than one app of the same platform
169
+ * connected — without it the adapter cannot tell them apart and refuses to
170
+ * guess rather than posting under the wrong bot identity.
171
+ */
172
+ installationKey?: string;
166
173
  }
167
174
 
168
175
  /**
@@ -606,7 +606,7 @@ async function enqueueAndDispatch(
606
606
  ),
607
607
  )
608
608
  : PROCESSOR_DISPATCH_SETTLE_WAIT_MS;
609
- await dispatchPendingIntegrationTask({
609
+ const outcome = await dispatchPendingIntegrationTask({
610
610
  taskId,
611
611
  task: {
612
612
  platform: incoming.platform,
@@ -617,6 +617,29 @@ async function enqueueAndDispatch(
617
617
  baseUrl,
618
618
  portableSettleMs: settleWaitMs,
619
619
  });
620
+
621
+ // A definitive dispatch failure leaves a queued task nobody is running while
622
+ // the placeholder above already told the user work had started. Say so
623
+ // instead of leaving that indicator spinning until the sweep — if it runs.
624
+ if (outcome === "failed") {
625
+ console.error(
626
+ `[integrations] dispatch failed for task ${taskId} (${incoming.platform}/${incoming.externalThreadId})`,
627
+ );
628
+ try {
629
+ await options.adapter.sendResponse(
630
+ {
631
+ text: "I couldn't start working on that — the request was accepted but never handed off. Please try again.",
632
+ platformContext: incoming.platformContext,
633
+ },
634
+ incoming,
635
+ );
636
+ } catch (err) {
637
+ console.error(
638
+ "[integrations] failed to report dispatch failure to user:",
639
+ err,
640
+ );
641
+ }
642
+ }
620
643
  }
621
644
 
622
645
  /**
@@ -15,6 +15,7 @@ import {
15
15
  } from "../agent/production-agent.js";
16
16
  import { runAgentLoopDirectWithSoftTimeout } from "../agent/run-loop-with-resume.js";
17
17
  import { resolveRunSoftTimeoutMs, startRun } from "../agent/run-manager.js";
18
+ import { claimBackgroundRun, insertRun } from "../agent/run-store.js";
18
19
  import { attachToolSearch } from "../agent/tool-search.js";
19
20
  import {
20
21
  resolveAutomationExecutionIdentity,
@@ -290,8 +291,23 @@ export async function runBackgroundAutomation(
290
291
  const systemPrompt = await deps.getSystemPrompt(ownerEmail);
291
292
  const thread = await createThread(ownerEmail, { title: threadTitle });
292
293
  const runId = createRunId(options.runIdPrefix);
294
+ // Scheduled work is background work: it has no synchronous serverless
295
+ // caller waiting on it, so it must not inherit the interactive clamp
296
+ // (40s soft timeout, a 30s no-progress backstop at 0.75x that, and 6
297
+ // continuations). A dashboard render or digest legitimately spends
298
+ // minutes across many tool calls, and dies the first time any gap
299
+ // between two of them exceeds 30s — recorded as `no_progress` after
300
+ // several minutes of real work, because the backstop is suspended
301
+ // while a tool is in flight but not between tools.
302
+ //
303
+ // Hardcoded rather than `isInBackgroundFunctionRuntime()` (what
304
+ // webhook-handler.ts uses): a webhook can arrive on either runtime, but
305
+ // a scheduler tick never serves a synchronous request, so the
306
+ // interactive clamp never applies to it. The wider soft ceiling stays
307
+ // bounded by this runner's own BACKGROUND_RUN_HARD_TIMEOUT_MS abort.
293
308
  const softTimeoutMs = resolveRunSoftTimeoutMs(undefined, {
294
309
  useHostedDefault: true,
310
+ backgroundFunction: true,
295
311
  });
296
312
 
297
313
  const usageRef: {
@@ -300,6 +316,26 @@ export async function runBackgroundAutomation(
300
316
  let responseText = "";
301
317
  let hardAbortTimer: ReturnType<typeof setTimeout> | null = null;
302
318
 
319
+ // This runner executes in-process, synchronously — there is no HTTP
320
+ // self-dispatch to a separate worker. Self-claim the row into
321
+ // 'background-processing' right away, exactly like a genuine HTTP
322
+ // background worker does immediately after its own insert (see
323
+ // production-agent.ts's `claimBackgroundWorkerRunEarly`). Without this,
324
+ // the row sits at dispatch_mode='background' for its whole life with no
325
+ // worker ever claiming it, which is indistinguishable from a lost HTTP
326
+ // handoff to the unclaimed-background-run sweep — it gets reaped as
327
+ // "background_worker_never_started" out from under a still-executing
328
+ // job the moment any single tool call runs past the 25s grace window.
329
+ await insertRun(runId, thread.id, undefined, {
330
+ dispatchMode: "background",
331
+ });
332
+ const claimedOwnRun = await claimBackgroundRun(runId);
333
+ if (!claimedOwnRun) {
334
+ throw new Error(
335
+ `Background automation "${automation.name}" (run "${runId}") could not claim its own freshly-inserted run row`,
336
+ );
337
+ }
338
+
303
339
  await new Promise<void>((resolve, reject) => {
304
340
  const activeRun = startRun(
305
341
  runId,
@@ -329,6 +365,7 @@ export async function runBackgroundAutomation(
329
365
  runId,
330
366
  },
331
367
  softTimeoutMs,
368
+ { backgroundFunction: true },
332
369
  );
333
370
  },
334
371
  async (run) => {
@@ -360,7 +397,7 @@ export async function runBackgroundAutomation(
360
397
  },
361
398
  {
362
399
  softTimeoutMs,
363
- dispatchMode: "background",
400
+ backgroundFunction: true,
364
401
  model,
365
402
  engineName: engine.name,
366
403
  },
@@ -3997,8 +3997,14 @@ async function resolveRequiredCredential(options: {
3997
3997
  connectionId?: string | null;
3998
3998
  }): Promise<ProviderApiResolvedCredential> {
3999
3999
  const credential = await resolveOptionalCredential(options);
4000
- if (!credential?.value) throw new Error(`${options.key} not configured`);
4001
- return credential;
4000
+ if (credential?.value) return credential;
4001
+ const scopeGap = await describeCredentialScopeGap([options.key], options.ctx)
4002
+ // coercion-ok: only enriches an error we throw either way — losing the scope
4003
+ // hint still surfaces the real "not configured" failure, never a success.
4004
+ .catch(() => null);
4005
+ throw new Error(
4006
+ `${options.key} not configured${scopeGap ? `. ${scopeGap}` : ""}`,
4007
+ );
4002
4008
  }
4003
4009
 
4004
4010
  async function resolveOptionalCredential(options: {
@@ -30,6 +30,7 @@ import { findAgent, discoverAgents } from "../server/agent-discovery.js";
30
30
  import {
31
31
  getRequestUserEmail,
32
32
  getRequestOrgId,
33
+ getRequestRunContext,
33
34
  isIntegrationCallerRequest,
34
35
  getIntegrationRequestContext,
35
36
  } from "../server/request-context.js";
@@ -93,8 +94,13 @@ function buildDelegationCorrelation(
93
94
  const inheritedDepth = Number.isInteger(context?.delegationDepth)
94
95
  ? Math.max(0, Number(context?.delegationDepth))
95
96
  : 0;
97
+ // The model this turn is actually running on, so a receiver with no model of
98
+ // its own can match the user's selection instead of its own default. A
99
+ // preference only — the receiver bounds it to its own engine's catalog.
100
+ const callerModel = getRequestRunContext()?.model?.trim();
96
101
  return {
97
102
  ...(selfAppId?.trim() ? { callerApp: selfAppId.trim() } : {}),
103
+ ...(callerModel ? { callerModel } : {}),
98
104
  ...(context?.threadId ? { callerThreadId: context.threadId } : {}),
99
105
  ...(context?.runId ? { parentRunId: context.runId } : {}),
100
106
  ...(context?.turnId ? { parentTurnId: context.turnId } : {}),
@@ -58,6 +58,7 @@ import {
58
58
  createAnthropicEngine,
59
59
  getStoredModelForEngine,
60
60
  normalizeModelForEngine,
61
+ resolveDelegatedRunModel,
61
62
  getAgentEngineEntry,
62
63
  isAgentEnginePackageInstalled,
63
64
  isStoredEngineUsableForRequest,
@@ -83,6 +84,7 @@ import {
83
84
  callerHasThreadAccess,
84
85
  } from "../agent/run-ownership.js";
85
86
  import { markTurnAborted, readBackgroundRunClaim } from "../agent/run-store.js";
87
+ import type { UnclaimedBackgroundRunRow } from "../agent/run-store.js";
86
88
  import {
87
89
  buildCurrentTimeUserContext,
88
90
  buildRuntimeContextPrompt,
@@ -1616,13 +1618,17 @@ export function createAgentChatPlugin(
1616
1618
  : await buildSchemaBlock(owner, databaseToolsMode);
1617
1619
  const extra = await resolveExtraContext(context.event, owner);
1618
1620
 
1619
- const a2aModelCandidate =
1620
- options?.model ??
1621
- (await getStoredModelForEngine(a2aEngine, {
1621
+ const model = resolveDelegatedRunModel(a2aEngine, {
1622
+ explicitModel: options?.model,
1623
+ storedModel: await getStoredModelForEngine(a2aEngine, {
1622
1624
  appId: options?.appId,
1623
- })) ??
1624
- a2aEngine.defaultModel;
1625
- const model = normalizeModelForEngine(a2aEngine, a2aModelCandidate);
1625
+ }),
1626
+ // Preference only, and last before the default: an app that pinned
1627
+ // a model keeps it. Read separately from the correlation sanitizer
1628
+ // below so it stays out of every identity/access path.
1629
+ callerModelHint: sanitizeA2ACorrelationMetadata(context.metadata)
1630
+ .callerModel,
1631
+ });
1626
1632
  if (a2aRunContext) {
1627
1633
  a2aRunContext.engine = a2aEngine;
1628
1634
  a2aRunContext.model = model;
@@ -5893,7 +5899,15 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
5893
5899
  const attemptUnclaimedBackgroundRunRedispatch = async (row: {
5894
5900
  id: string;
5895
5901
  startedAt: number;
5902
+ hasDispatchPayload: boolean;
5896
5903
  }): Promise<void> => {
5904
+ // Eligibility for this sweep does not mean the row is redispatchable.
5905
+ // The marker below asserts `payloadRef: true`, and a worker that then
5906
+ // finds no payload fails the run as `dispatch_payload_missing` — so
5907
+ // redispatching a payload-less row does not recover it, it destroys it.
5908
+ // Leave it for the slow sweep's reap, which reports the true cause
5909
+ // (`background_worker_never_started`) and is client-recoverable.
5910
+ if (!row.hasDispatchPayload) return;
5897
5911
  const { updateRunHeartbeat } = await import("../agent/run-store.js");
5898
5912
  const { resolveAgentChatProcessRunDispatchPath } =
5899
5913
  await import("../agent/durable-background.js");
@@ -5974,7 +5988,7 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
5974
5988
  // idempotent, re-checks staleness at UPDATE time and honours
5975
5989
  // the in-flight grace, so it is safe on this cadence.
5976
5990
  await reapAllStaleRuns().catch(() => {});
5977
- let rows: { id: string; startedAt: number }[];
5991
+ let rows: UnclaimedBackgroundRunRow[];
5978
5992
  try {
5979
5993
  rows = await listUnclaimedBackgroundRunRows();
5980
5994
  } catch {
@@ -6019,7 +6033,7 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
6019
6033
  reapUnclaimedBackgroundRun,
6020
6034
  shouldRedispatchUnclaimedBackgroundRun,
6021
6035
  } = await import("../agent/run-store.js");
6022
- let rows: { id: string; startedAt: number }[];
6036
+ let rows: UnclaimedBackgroundRunRow[];
6023
6037
  try {
6024
6038
  rows = await listUnclaimedBackgroundRunRows();
6025
6039
  } catch {
@@ -6027,7 +6041,14 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
6027
6041
  }
6028
6042
  for (const row of rows) {
6029
6043
  try {
6030
- if (shouldRedispatchUnclaimedBackgroundRun(row)) {
6044
+ // A row with no `dispatch_payload` can never be rehydrated by
6045
+ // a redispatched worker, so waiting out the redispatch bound
6046
+ // buys nothing — fall straight through to the reap below and
6047
+ // fail it loudly with its real cause.
6048
+ if (
6049
+ row.hasDispatchPayload &&
6050
+ shouldRedispatchUnclaimedBackgroundRun(row)
6051
+ ) {
6031
6052
  await attemptUnclaimedBackgroundRunRedispatch(row);
6032
6053
  continue;
6033
6054
  }
@@ -101,6 +101,8 @@ export interface WorkspaceAppManifestEntry {
101
101
  description: string;
102
102
  path: string;
103
103
  url?: string | null;
104
+ /** Local-only child port used to authorize loopback A2A calls. */
105
+ port?: number;
104
106
  isDispatch?: boolean;
105
107
  audience?: WorkspaceAppAudience;
106
108
  publicPaths?: string[];
@@ -57,8 +57,15 @@ export interface BuilderDesignSystemProxyFieldsOptions {
57
57
  projectName?: string;
58
58
  description?: string;
59
59
  surface: "design" | "slides";
60
+ sourceKind?: BuilderDesignSystemSourceKind;
60
61
  }
61
62
 
63
+ export type BuilderDesignSystemSourceKind =
64
+ | "figma"
65
+ | "code"
66
+ | "github"
67
+ | "mixed";
68
+
62
69
  export interface BuilderDesignSystemProxyFields {
63
70
  title: string;
64
71
  description: string;
@@ -68,6 +75,7 @@ export interface BuilderDesignSystemProxyFields {
68
75
 
69
76
  export interface BuilderDesignSystemProxyReference {
70
77
  source: "builder";
78
+ sourceKind?: BuilderDesignSystemSourceKind;
71
79
  builderDesignSystemId: string;
72
80
  builderJobId: string;
73
81
  builderProjectId?: string;
@@ -532,6 +540,7 @@ export function createBuilderDesignSystemProxyFields({
532
540
  projectName,
533
541
  description,
534
542
  surface,
543
+ sourceKind,
535
544
  }: BuilderDesignSystemProxyFieldsOptions): BuilderDesignSystemProxyFields {
536
545
  const title = projectName?.trim() || "Builder indexed design system";
537
546
  const fallbackDescription =
@@ -540,6 +549,7 @@ export function createBuilderDesignSystemProxyFields({
540
549
  const spacingKey = surface === "slides" ? "slidePadding" : "pagePadding";
541
550
  const data = JSON.stringify({
542
551
  source: "builder",
552
+ ...(sourceKind ? { sourceKind } : {}),
543
553
  builderDesignSystemId: result.designSystemId,
544
554
  builderJobId: result.jobId,
545
555
  builderProjectId: result.projectId,
@@ -611,8 +621,19 @@ export function parseBuilderDesignSystemProxyReference(
611
621
  if (value.source !== "builder") return null;
612
622
  if (typeof value.builderDesignSystemId !== "string") return null;
613
623
  if (typeof value.builderJobId !== "string") return null;
624
+ const sourceKind = value.sourceKind;
625
+ if (
626
+ sourceKind !== undefined &&
627
+ sourceKind !== "figma" &&
628
+ sourceKind !== "code" &&
629
+ sourceKind !== "github" &&
630
+ sourceKind !== "mixed"
631
+ ) {
632
+ return null;
633
+ }
614
634
  return {
615
635
  source: "builder",
636
+ ...(sourceKind ? { sourceKind } : {}),
616
637
  builderDesignSystemId: value.builderDesignSystemId,
617
638
  builderJobId: value.builderJobId,
618
639
  builderProjectId:
@@ -280,8 +280,23 @@ interface BuilderResolvedCredentials {
280
280
  source: Exclude<BuilderCredentialSource, "env">;
281
281
  }
282
282
 
283
- function isCompleteBuilderConnection(creds: BuilderResolvedCredentials) {
284
- return Boolean(creds.privateKey && creds.publicKey);
283
+ /**
284
+ * A complete key pair is not necessarily a usable one: the gateway may have
285
+ * already rejected this exact private+public pair (see
286
+ * `recordBuilderCredentialAuthFailure`). Treating a marked-bad pair as
287
+ * "complete" is how a rejected credential got resent on every subsequent
288
+ * turn forever — this is the read side of that write, symmetric with
289
+ * `resolveUsableProviderSecret` for every non-Builder provider.
290
+ */
291
+ async function isCompleteBuilderConnection(
292
+ creds: BuilderResolvedCredentials,
293
+ ): Promise<boolean> {
294
+ if (!creds.privateKey || !creds.publicKey) return false;
295
+ const failure = await getBuilderCredentialAuthFailure({
296
+ privateKey: creds.privateKey,
297
+ publicKey: creds.publicKey,
298
+ });
299
+ return !failure;
285
300
  }
286
301
 
287
302
  function readOptionalBuilderBoolean(
@@ -524,14 +539,14 @@ async function resolveScopedBuilderCredentials(): Promise<ScopedBuilderCredentia
524
539
  let orgLookupCause: unknown;
525
540
  try {
526
541
  const { readAppSecrets } = await import("../secrets/storage.js");
527
- const traceScope = (
542
+ const traceScope = async (
528
543
  creds: BuilderResolvedCredentials,
529
544
  scopeId: string,
530
545
  extra = "",
531
546
  ) => {
532
547
  if (!traceLookup) return;
533
548
  console.log(
534
- `[builder-credential] scope=${creds.source} scopeId=${scopeId} email=${email}${extra} complete=${isCompleteBuilderConnection(creds)} private=${Boolean(creds.privateKey)} public=${Boolean(creds.publicKey)}`,
549
+ `[builder-credential] scope=${creds.source} scopeId=${scopeId} email=${email}${extra} complete=${await isCompleteBuilderConnection(creds)} private=${Boolean(creds.privateKey)} public=${Boolean(creds.publicKey)}`,
535
550
  );
536
551
  };
537
552
 
@@ -540,8 +555,8 @@ async function resolveScopedBuilderCredentials(): Promise<ScopedBuilderCredentia
540
555
  "user",
541
556
  email,
542
557
  );
543
- traceScope(userCreds, email);
544
- if (isCompleteBuilderConnection(userCreds)) {
558
+ await traceScope(userCreds, email);
559
+ if (await isCompleteBuilderConnection(userCreds)) {
545
560
  return { creds: userCreds, lookupFailed: false };
546
561
  }
547
562
 
@@ -563,8 +578,8 @@ async function resolveScopedBuilderCredentials(): Promise<ScopedBuilderCredentia
563
578
  "org",
564
579
  orgId,
565
580
  );
566
- traceScope(orgCreds, orgId, ` orgSource=${orgSource}`);
567
- if (isCompleteBuilderConnection(orgCreds)) {
581
+ await traceScope(orgCreds, orgId, ` orgSource=${orgSource}`);
582
+ if (await isCompleteBuilderConnection(orgCreds)) {
568
583
  return { creds: orgCreds, lookupFailed: false };
569
584
  }
570
585
 
@@ -574,8 +589,8 @@ async function resolveScopedBuilderCredentials(): Promise<ScopedBuilderCredentia
574
589
  "workspace",
575
590
  orgId,
576
591
  );
577
- traceScope(workspaceCreds, orgId, ` orgSource=${orgSource}`);
578
- if (isCompleteBuilderConnection(workspaceCreds)) {
592
+ await traceScope(workspaceCreds, orgId, ` orgSource=${orgSource}`);
593
+ if (await isCompleteBuilderConnection(workspaceCreds)) {
579
594
  return { creds: workspaceCreds, lookupFailed: false };
580
595
  }
581
596
  }
@@ -594,12 +609,12 @@ async function resolveScopedBuilderCredentials(): Promise<ScopedBuilderCredentia
594
609
  "workspace",
595
610
  soloScopeId,
596
611
  );
597
- traceScope(
612
+ await traceScope(
598
613
  soloCreds,
599
614
  soloScopeId,
600
615
  ` orgId=${orgId ?? "(none)"} orgSource=${orgSource}`,
601
616
  );
602
- if (isCompleteBuilderConnection(soloCreds)) {
617
+ if (await isCompleteBuilderConnection(soloCreds)) {
603
618
  return { creds: soloCreds, lookupFailed: false };
604
619
  }
605
620
  } catch (err) {
@@ -791,6 +806,30 @@ export async function resolveBuilderCredentialsDetailed(): Promise<BuilderCreden
791
806
  readDeployCredentialEnv("BUILDER_IS_FREE_ACCOUNT"),
792
807
  )
793
808
  : null;
809
+ // The deploy-level fallback is a candidate scope like any other: a pair the
810
+ // gateway already rejected must not be handed back as the "configured"
811
+ // credential just because no per-user/org row exists to shadow it.
812
+ const envFailure =
813
+ privateKey && publicKey
814
+ ? await getBuilderCredentialAuthFailure({ privateKey, publicKey })
815
+ : null;
816
+ if (envFailure) {
817
+ return {
818
+ privateKey: null,
819
+ publicKey: null,
820
+ userId: null,
821
+ orgName: null,
822
+ orgKind: null,
823
+ subscription: null,
824
+ subscriptionLevel: null,
825
+ subscriptionName: null,
826
+ isEnterprise: null,
827
+ isFreeAccount: null,
828
+ source: null,
829
+ lookupFailed,
830
+ cause,
831
+ };
832
+ }
794
833
  return {
795
834
  privateKey,
796
835
  publicKey,
@@ -514,6 +514,7 @@ export {
514
514
  type BuilderDesignSystemProxyFields,
515
515
  type BuilderDesignSystemProxyFieldsOptions,
516
516
  type BuilderDesignSystemProxyReference,
517
+ type BuilderDesignSystemSourceKind,
517
518
  } from "./builder-design-systems.js";
518
519
  export {
519
520
  getBuilderBranchProjectId,
@@ -3264,6 +3264,32 @@ ${
3264
3264
  var RESEND_VERIFICATION_COOLDOWN_SECONDS = 60;
3265
3265
  var resendVerificationCooldownUntil = 0;
3266
3266
  var resendVerificationCooldownTimer = null;
3267
+ var PENDING_SIGNUP_EMAIL_STORAGE_KEY = 'an.onboarding.pendingSignupEmail';
3268
+ // The verification link can open in a new tab, so in-memory pending state
3269
+ // cannot be the only source of the account email. Keep only the address,
3270
+ // never the password, for the manual-login fallback.
3271
+ function pendingSignupEmailStorageKey() {
3272
+ return PENDING_SIGNUP_EMAIL_STORAGE_KEY + ':' + (__anBasePath() || '/');
3273
+ }
3274
+ function rememberPendingSignupEmail(email) {
3275
+ try {
3276
+ if (email) localStorage.setItem(pendingSignupEmailStorageKey(), email);
3277
+ else localStorage.removeItem(pendingSignupEmailStorageKey());
3278
+ // coercion-ok: localStorage is optional; the in-memory and form fallbacks remain available.
3279
+ } catch (e) {}
3280
+ }
3281
+ function readRememberedPendingSignupEmail() {
3282
+ try {
3283
+ var email = localStorage.getItem(pendingSignupEmailStorageKey()) || '';
3284
+ return __anIsValidAuthEmail(email) ? __anNormalizeAuthEmail(email) : '';
3285
+ // coercion-ok: localStorage is optional; callers fall back to the in-memory or form value.
3286
+ } catch (e) {
3287
+ return '';
3288
+ }
3289
+ }
3290
+ function clearRememberedPendingSignupEmail() {
3291
+ rememberPendingSignupEmail('');
3292
+ }
3267
3293
  function setActiveTab(name, opts) {
3268
3294
  if (name !== 'signup' && name !== 'login') return;
3269
3295
  var form = document.getElementById(name + '-form');
@@ -3283,6 +3309,7 @@ ${
3283
3309
  function showVerificationStep(email, password) {
3284
3310
  pendingSignupEmail = email || '';
3285
3311
  pendingSignupPassword = password || '';
3312
+ rememberPendingSignupEmail(pendingSignupEmail);
3286
3313
  tabs.forEach(function(x) { x.classList.remove('active'); });
3287
3314
  forms.forEach(function(x) { x.classList.remove('active'); });
3288
3315
  var card = document.querySelector('.card');
@@ -3313,7 +3340,7 @@ ${
3313
3340
  function getPendingSignupEmail() {
3314
3341
  var signupEmail = document.getElementById('s-email');
3315
3342
  var loginEmail = document.getElementById('l-email');
3316
- return (pendingSignupEmail || (signupEmail && signupEmail.value) || (loginEmail && loginEmail.value) || '').trim();
3343
+ return (pendingSignupEmail || readRememberedPendingSignupEmail() || (signupEmail && signupEmail.value) || (loginEmail && loginEmail.value) || '').trim();
3317
3344
  }
3318
3345
  function getPendingSignupPassword() {
3319
3346
  var signupPassword = document.getElementById('s-pass');
@@ -3366,6 +3393,7 @@ ${
3366
3393
  body: JSON.stringify({ email: email, password: password }),
3367
3394
  });
3368
3395
  if (res.ok) {
3396
+ clearRememberedPendingSignupEmail();
3369
3397
  __anRedirectToSignedInApp();
3370
3398
  return { ok: true };
3371
3399
  }
@@ -3398,6 +3426,7 @@ ${
3398
3426
  });
3399
3427
  var data = await res.json().catch(function() { return {}; });
3400
3428
  if (res.ok && data && data.email && !data.error) {
3429
+ clearRememberedPendingSignupEmail();
3401
3430
  __anRedirectToSignedInApp();
3402
3431
  return;
3403
3432
  }
@@ -3464,7 +3493,7 @@ ${
3464
3493
  async function resendVerificationEmail() {
3465
3494
  var btn = document.getElementById('resend-verification');
3466
3495
  var msg = document.getElementById('verify-msg');
3467
- var email = pendingSignupEmail || document.getElementById('s-email').value;
3496
+ var email = getPendingSignupEmail();
3468
3497
  if (!email) return;
3469
3498
  if (resendVerificationCooldownUntil > Date.now()) {
3470
3499
  updateResendVerificationCooldown();
@@ -3533,6 +3562,9 @@ ${
3533
3562
  setActiveTab(initial, { persist: false });
3534
3563
  try {
3535
3564
  if (__anIsVerifiedRedirectSuccess()) {
3565
+ var rememberedEmail = readRememberedPendingSignupEmail();
3566
+ var loginEmail = document.getElementById('l-email');
3567
+ if (loginEmail && rememberedEmail) loginEmail.value = rememberedEmail;
3536
3568
  var msg = document.getElementById('l-msg');
3537
3569
  if (msg) {
3538
3570
  msg.textContent = __anT('emailVerifiedFinishing');
@@ -3591,6 +3623,7 @@ ${
3591
3623
  body: JSON.stringify({ email: email, password: pass }),
3592
3624
  });
3593
3625
  if (loginRes.ok) {
3626
+ clearRememberedPendingSignupEmail();
3594
3627
  msg.textContent = __anT('accountCreatedSigningIn');
3595
3628
  msg.classList.add('show', 'success');
3596
3629
  __anRedirectToSignedInApp();
@@ -3630,6 +3663,7 @@ ${
3630
3663
  var backToSignup = document.getElementById('back-to-signup');
3631
3664
  if (backToSignup) backToSignup.addEventListener('click', function(e) {
3632
3665
  e.preventDefault();
3666
+ clearRememberedPendingSignupEmail();
3633
3667
  setActiveTab('signup', { persist: true });
3634
3668
  var email = document.getElementById('s-email');
3635
3669
  setTimeout(function() { if (email) email.focus(); }, 0);
@@ -3724,6 +3758,7 @@ ${
3724
3758
  }),
3725
3759
  });
3726
3760
  if (res.ok) {
3761
+ clearRememberedPendingSignupEmail();
3727
3762
  __anRedirectToSignedInApp();
3728
3763
  return;
3729
3764
  }
@@ -156,7 +156,7 @@ export function stepDownReasoningEffort(
156
156
  return REASONING_EFFORT_STEP_DOWN[effort] ?? effort;
157
157
  }
158
158
 
159
- function isGPTReasoningModel(model: string) {
159
+ export function isGPTReasoningModel(model: string) {
160
160
  const id = model.toLowerCase().replace(/^openai\//, "");
161
161
  return /^gpt-5/.test(id) || /^o\d/.test(id);
162
162
  }
@@ -17,6 +17,17 @@ Agents call other agents over A2A, a JSON-RPC protocol for discovery and
17
17
  delegation. Use it when work belongs to a different agent entirely — not the
18
18
  local agent chat.
19
19
 
20
+ **No workarounds when A2A feels flaky.** The strong default is `ask_app` (or
21
+ `call-agent`) working reliably, full stop — not apps reaching around it. Do
22
+ not have app A generate and execute raw SQL against app B's database, and do
23
+ not expose B's internal tools directly to A as a substitute for delegation.
24
+ The receiving agent has context, skills, and guardrails the caller doesn't;
25
+ bypassing it to work around a flaky A2A call reintroduces exactly the bugs A2A
26
+ exists to prevent, and makes the real reliability problem invisible instead of
27
+ fixing it. If A2A delegation is unreliable, fix A2A — file it as a bug in the
28
+ delegation path (timeout handling, retries, typed terminal states), don't
29
+ route around it app by app.
30
+
20
31
  Connecting app A to app B is two independent things, and both must be true:
21
32
 
22
33
  1. **B is registered on A** as a `remote-agents/<id>.json` resource.