@agent-native/core 0.112.0 → 0.114.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1902) hide show
  1. package/agent-native.eject.json +164 -0
  2. package/corpus/README.md +4 -2
  3. package/corpus/core/CHANGELOG.md +33 -0
  4. package/corpus/core/README.md +61 -174
  5. package/corpus/core/agent-native.eject.json +164 -0
  6. package/corpus/core/docs/AGENTS.md +7 -0
  7. package/corpus/core/docs/content/agent-native-toolkit.mdx +38 -0
  8. package/corpus/core/docs/content/integrations.mdx +63 -2
  9. package/corpus/core/docs/content/package-lifecycle.mdx +54 -4
  10. package/corpus/core/docs/design/provider-integration-authority.md +117 -0
  11. package/corpus/core/package.json +20 -2
  12. package/corpus/core/scripts/materialize-source-corpus.mjs +9 -2
  13. package/corpus/core/src/cli/atomic-json-file.ts +324 -0
  14. package/corpus/core/src/cli/claude-code-participant.ts +515 -0
  15. package/corpus/core/src/cli/code-agent-executor.ts +18 -10
  16. package/corpus/core/src/cli/code-agent-runs.concurrent-worker.ts +33 -0
  17. package/corpus/core/src/cli/code-agent-runs.ts +55 -62
  18. package/corpus/core/src/cli/codex-cli-participant.ts +496 -0
  19. package/corpus/core/src/cli/eject.ts +1594 -0
  20. package/corpus/core/src/cli/index.ts +16 -0
  21. package/corpus/core/src/cli/multi-frontier-runs.ts +1246 -135
  22. package/corpus/core/src/client/chat/ChatHistoryList.tsx +7 -404
  23. package/corpus/core/src/client/index.ts +4 -0
  24. package/corpus/core/src/client/resources/McpConnectionSuggestion.tsx +8 -2
  25. package/corpus/core/src/client/resources/McpIntegrationDialog.tsx +7 -2
  26. package/corpus/core/src/client/resources/ResourcesPanel.tsx +17 -3
  27. package/corpus/core/src/client/resources/index.ts +19 -0
  28. package/corpus/core/src/client/resources/mcp-integration-catalog.ts +9 -1
  29. package/corpus/core/src/client/resources/runtime.ts +1 -0
  30. package/corpus/core/src/client/setup-connections/catalog.ts +6 -0
  31. package/corpus/core/src/client/setup-connections/index.ts +1 -0
  32. package/corpus/core/src/client/setup-connections/runtime.ts +1 -0
  33. package/corpus/core/src/connections/catalog.ts +41 -24
  34. package/corpus/core/src/connections/index.ts +1 -0
  35. package/corpus/core/src/connections/runtime.ts +1 -0
  36. package/corpus/core/src/eject/provider-api-definitions.ts +193 -0
  37. package/corpus/core/src/eject/remote-mcp-presets.ts +137 -0
  38. package/corpus/core/src/eject/setup-readiness-ui.tsx +29 -0
  39. package/corpus/core/src/eject/workspace-connections.ts +92 -0
  40. package/corpus/core/src/index.ts +1 -0
  41. package/corpus/core/src/integrations/adapter-overrides.ts +12 -0
  42. package/corpus/core/src/integrations/eject/messaging-adapters.ts +85 -0
  43. package/corpus/core/src/integrations/index.ts +15 -1
  44. package/corpus/core/src/integrations/plugin.ts +34 -12
  45. package/corpus/core/src/integrations/runtime.ts +1 -0
  46. package/corpus/core/src/integrations/slack-oauth.ts +1 -0
  47. package/corpus/core/src/integrations/types.ts +3 -1
  48. package/corpus/core/src/integrations/webhook-delivery.ts +55 -0
  49. package/corpus/core/src/notifications/channels.ts +4 -10
  50. package/corpus/core/src/package-lifecycle/eject-manifest.ts +345 -0
  51. package/corpus/core/src/package-lifecycle/index.ts +1 -0
  52. package/corpus/core/src/provider-api/actions/custom-provider-registration.ts +197 -0
  53. package/corpus/core/src/provider-api/actions/delete-staged-dataset.ts +3 -42
  54. package/corpus/core/src/provider-api/actions/list-staged-datasets.ts +3 -45
  55. package/corpus/core/src/provider-api/actions/provider-api-audit.ts +88 -0
  56. package/corpus/core/src/provider-api/actions/provider-api.ts +460 -0
  57. package/corpus/core/src/provider-api/actions/query-staged-dataset.ts +3 -140
  58. package/corpus/core/src/provider-api/actions/staged-datasets.ts +359 -0
  59. package/corpus/core/src/provider-api/gong.ts +108 -0
  60. package/corpus/core/src/provider-api/index.ts +46 -12
  61. package/corpus/core/src/provider-api/runtime.ts +1 -0
  62. package/corpus/core/src/scripts/docs/source-search.ts +2 -1
  63. package/corpus/core/src/server/google-oauth-credentials.ts +80 -3
  64. package/corpus/core/src/server/index.ts +6 -0
  65. package/corpus/core/src/setup-connections/index.ts +1 -0
  66. package/corpus/core/src/shared/merge-by-id.ts +14 -0
  67. package/corpus/core/src/styles/chat-history-list.css +1 -313
  68. package/corpus/core/src/templates/default/.agents/skills/actions/SKILL.md +32 -12
  69. package/corpus/core/src/templates/default/.agents/skills/agent-native-docs/SKILL.md +21 -9
  70. package/corpus/core/src/templates/default/.agents/skills/customizing-agent-native/SKILL.md +145 -0
  71. package/corpus/core/src/templates/default/.agents/skills/integration-webhooks/SKILL.md +323 -0
  72. package/corpus/core/src/templates/default/.agents/skills/onboarding/SKILL.md +56 -0
  73. package/corpus/core/src/templates/default/.agents/skills/secrets/SKILL.md +273 -0
  74. package/corpus/core/src/templates/default/.agents/skills/self-modifying-code/SKILL.md +14 -2
  75. package/corpus/core/src/templates/default/.agents/skills/upgrade-agent-native/SKILL.md +6 -0
  76. package/corpus/core/src/templates/default/AGENTS.md +26 -18
  77. package/corpus/core/src/templates/headless/.agents/skills/actions/SKILL.md +512 -0
  78. package/corpus/core/src/templates/headless/.agents/skills/agent-native-docs/SKILL.md +21 -9
  79. package/corpus/core/src/templates/headless/.agents/skills/customizing-agent-native/SKILL.md +145 -0
  80. package/corpus/core/src/templates/headless/.agents/skills/integration-webhooks/SKILL.md +323 -0
  81. package/corpus/core/src/templates/headless/.agents/skills/secrets/SKILL.md +273 -0
  82. package/corpus/core/src/templates/headless/.agents/skills/upgrade-agent-native/SKILL.md +6 -0
  83. package/corpus/core/src/templates/headless/AGENTS.md +8 -0
  84. package/corpus/core/src/templates/workspace-core/.agents/skills/actions/SKILL.md +32 -12
  85. package/corpus/core/src/templates/workspace-core/.agents/skills/agent-native-docs/SKILL.md +21 -9
  86. package/corpus/core/src/templates/workspace-core/.agents/skills/agent-native-toolkit/SKILL.md +7 -0
  87. package/corpus/core/src/templates/workspace-core/.agents/skills/customizing-agent-native/SKILL.md +145 -0
  88. package/corpus/core/src/templates/workspace-core/.agents/skills/self-modifying-code/SKILL.md +14 -2
  89. package/corpus/core/src/templates/workspace-core/.agents/skills/upgrade-agent-native/SKILL.md +6 -0
  90. package/corpus/core/src/templates/workspace-core/AGENTS.md +4 -0
  91. package/corpus/core/src/templates/workspace-root/AGENTS.md +4 -0
  92. package/corpus/core/src/vite/client.ts +25 -2
  93. package/corpus/templates/analytics/.agents/skills/actions/SKILL.md +32 -12
  94. package/corpus/templates/analytics/.agents/skills/customizing-agent-native/SKILL.md +145 -0
  95. package/corpus/templates/analytics/.agents/skills/self-modifying-code/SKILL.md +14 -2
  96. package/corpus/templates/analytics/.agents/skills/upgrade-agent-native/SKILL.md +6 -0
  97. package/corpus/templates/analytics/actions/delete-staged-dataset.ts +3 -23
  98. package/corpus/templates/analytics/actions/list-staged-datasets.ts +3 -27
  99. package/corpus/templates/analytics/actions/provider-api-catalog.ts +16 -19
  100. package/corpus/templates/analytics/actions/provider-api-docs.ts +3 -5
  101. package/corpus/templates/analytics/actions/provider-api-request.ts +162 -185
  102. package/corpus/templates/analytics/actions/query-staged-dataset.ts +3 -47
  103. package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +52 -161
  104. package/corpus/templates/assets/.agents/skills/actions/SKILL.md +32 -12
  105. package/corpus/templates/assets/.agents/skills/customizing-agent-native/SKILL.md +145 -0
  106. package/corpus/templates/assets/.agents/skills/self-modifying-code/SKILL.md +14 -2
  107. package/corpus/templates/assets/.agents/skills/upgrade-agent-native/SKILL.md +6 -0
  108. package/corpus/templates/assets/app/components/layout/Sidebar.tsx +63 -160
  109. package/corpus/templates/brain/.agents/skills/actions/SKILL.md +32 -12
  110. package/corpus/templates/brain/.agents/skills/customizing-agent-native/SKILL.md +145 -0
  111. package/corpus/templates/brain/.agents/skills/self-modifying-code/SKILL.md +14 -2
  112. package/corpus/templates/brain/.agents/skills/upgrade-agent-native/SKILL.md +6 -0
  113. package/corpus/templates/brain/actions/_schemas.ts +13 -7
  114. package/corpus/templates/brain/actions/delete-staged-dataset.ts +3 -24
  115. package/corpus/templates/brain/actions/list-staged-datasets.ts +3 -28
  116. package/corpus/templates/brain/actions/provider-api-catalog.ts +5 -11
  117. package/corpus/templates/brain/actions/provider-api-docs.ts +3 -5
  118. package/corpus/templates/brain/actions/provider-api-request.ts +3 -37
  119. package/corpus/templates/brain/actions/query-staged-dataset.ts +3 -48
  120. package/corpus/templates/brain/actions/remediate-legacy-capture-audiences.ts +167 -0
  121. package/corpus/templates/brain/actions/update-source.ts +5 -1
  122. package/corpus/templates/brain/app/components/layout/Sidebar.tsx +48 -154
  123. package/corpus/templates/brain/app/lib/brain-chat-readiness.ts +6 -0
  124. package/corpus/templates/brain/app/lib/brain.ts +55 -0
  125. package/corpus/templates/brain/app/lib/ingest-handoff.ts +35 -0
  126. package/corpus/templates/brain/app/routes/_index.tsx +8 -0
  127. package/corpus/templates/brain/app/routes.ts +1 -0
  128. package/corpus/templates/brain/changelog/2026-07-19-ask-starts-immediately-when-builder-s-managed-ai-connection-.md +6 -0
  129. package/corpus/templates/brain/changelog/2026-07-19-slack-and-granola-backfills-now-process-captures-concurrentl.md +6 -0
  130. package/corpus/templates/brain/changelog/2026-07-19-slack-backfills-can-now-join-configured-public-channels-befo.md +6 -0
  131. package/corpus/templates/brain/changelog/2026-07-19-slack-backfills-now-continue-across-the-configured-number-of.md +6 -0
  132. package/corpus/templates/brain/changelog/2026-07-19-slack-backfills-now-start-with-a-safe-four-week-window-and-r.md +6 -0
  133. package/corpus/templates/brain/changelog/2026-07-19-source-review-settings-now-control-knowledge-approval.md +6 -0
  134. package/corpus/templates/brain/changelog/2026-07-19-the-manage-agent-page-now-opens-correctly-from-brain-navigat.md +6 -0
  135. package/corpus/templates/brain/server/db/schema.ts +3 -0
  136. package/corpus/templates/brain/server/lib/brain.ts +41 -2
  137. package/corpus/templates/brain/server/lib/connectors.ts +432 -115
  138. package/corpus/templates/brain/server/lib/meeting-audience.ts +38 -0
  139. package/corpus/templates/brain/server/lib/slack-channel-membership.ts +44 -0
  140. package/corpus/templates/brain/server/plugins/db.ts +10 -0
  141. package/corpus/templates/brain/server/routes/api/_agent-native/brain/ingest.post.ts +6 -4
  142. package/corpus/templates/brain/shared/slack-source-config.ts +60 -0
  143. package/corpus/templates/calendar/.agents/skills/actions/SKILL.md +32 -12
  144. package/corpus/templates/calendar/.agents/skills/customizing-agent-native/SKILL.md +145 -0
  145. package/corpus/templates/calendar/.agents/skills/self-modifying-code/SKILL.md +14 -2
  146. package/corpus/templates/calendar/.agents/skills/upgrade-agent-native/SKILL.md +6 -0
  147. package/corpus/templates/calendar/actions/delete-staged-dataset.ts +3 -24
  148. package/corpus/templates/calendar/actions/list-staged-datasets.ts +3 -28
  149. package/corpus/templates/calendar/actions/provider-api-catalog.ts +5 -11
  150. package/corpus/templates/calendar/actions/provider-api-docs.ts +3 -5
  151. package/corpus/templates/calendar/actions/provider-api-request.ts +3 -37
  152. package/corpus/templates/calendar/actions/query-staged-dataset.ts +3 -48
  153. package/corpus/templates/calendar/server/handlers/gong.ts +6 -61
  154. package/corpus/templates/calendar/server/handlers/google-auth.ts +10 -8
  155. package/corpus/templates/calendar/server/lib/google-calendar.ts +7 -45
  156. package/corpus/templates/chat/.agents/skills/actions/SKILL.md +32 -12
  157. package/corpus/templates/chat/.agents/skills/agent-native-docs/SKILL.md +21 -9
  158. package/corpus/templates/chat/.agents/skills/customizing-agent-native/SKILL.md +145 -0
  159. package/corpus/templates/chat/.agents/skills/self-modifying-code/SKILL.md +14 -2
  160. package/corpus/templates/chat/.agents/skills/upgrade-agent-native/SKILL.md +6 -0
  161. package/corpus/templates/chat/AGENTS.md +6 -2
  162. package/corpus/templates/chat/app/components/layout/Sidebar.tsx +51 -157
  163. package/corpus/templates/clips/.agents/skills/actions/SKILL.md +32 -12
  164. package/corpus/templates/clips/.agents/skills/customizing-agent-native/SKILL.md +145 -0
  165. package/corpus/templates/clips/.agents/skills/self-modifying-code/SKILL.md +14 -2
  166. package/corpus/templates/clips/.agents/skills/upgrade-agent-native/SKILL.md +6 -0
  167. package/corpus/templates/clips/AGENTS.md +11 -0
  168. package/corpus/templates/clips/actions/export-to-brain.ts +505 -171
  169. package/corpus/templates/clips/changelog/2026-07-19-ready-clips-transcripts-can-be-backfilled-to-brain-for-a-bou.md +6 -0
  170. package/corpus/templates/clips/server/lib/calendar-event-meetings.ts +1 -1
  171. package/corpus/templates/clips/server/lib/google-calendar-client.ts +12 -22
  172. package/corpus/templates/clips/server/lib/google-calendar-oauth.ts +9 -6
  173. package/corpus/templates/clips/server/lib/slack-oauth.ts +12 -47
  174. package/corpus/templates/clips/server/routes/_agent-native/google/auth-url.get.ts +2 -6
  175. package/corpus/templates/clips/server/routes/api/auth/google-calendar.get.ts +4 -4
  176. package/corpus/templates/content/.agents/skills/actions/SKILL.md +32 -12
  177. package/corpus/templates/content/.agents/skills/customizing-agent-native/SKILL.md +145 -0
  178. package/corpus/templates/content/.agents/skills/self-modifying-code/SKILL.md +14 -2
  179. package/corpus/templates/content/.agents/skills/upgrade-agent-native/SKILL.md +6 -0
  180. package/corpus/templates/content/actions/delete-staged-dataset.ts +3 -24
  181. package/corpus/templates/content/actions/list-staged-datasets.ts +3 -28
  182. package/corpus/templates/content/actions/provider-api-catalog.ts +5 -11
  183. package/corpus/templates/content/actions/provider-api-docs.ts +3 -5
  184. package/corpus/templates/content/actions/provider-api-request.ts +3 -37
  185. package/corpus/templates/content/actions/query-staged-dataset.ts +3 -48
  186. package/corpus/templates/design/.agents/skills/actions/SKILL.md +32 -12
  187. package/corpus/templates/design/.agents/skills/customizing-agent-native/SKILL.md +145 -0
  188. package/corpus/templates/design/.agents/skills/self-modifying-code/SKILL.md +14 -2
  189. package/corpus/templates/design/.agents/skills/upgrade-agent-native/SKILL.md +6 -0
  190. package/corpus/templates/design/actions/delete-staged-dataset.ts +4 -23
  191. package/corpus/templates/design/actions/list-staged-datasets.ts +4 -27
  192. package/corpus/templates/design/actions/provider-api-catalog.ts +15 -18
  193. package/corpus/templates/design/actions/provider-api-docs.ts +57 -48
  194. package/corpus/templates/design/actions/provider-api-request.ts +140 -164
  195. package/corpus/templates/design/actions/query-staged-dataset.ts +4 -47
  196. package/corpus/templates/dispatch/.agents/skills/actions/SKILL.md +32 -12
  197. package/corpus/templates/dispatch/.agents/skills/customizing-agent-native/SKILL.md +145 -0
  198. package/corpus/templates/dispatch/.agents/skills/self-modifying-code/SKILL.md +14 -2
  199. package/corpus/templates/dispatch/.agents/skills/upgrade-agent-native/SKILL.md +6 -0
  200. package/corpus/templates/dispatch/actions/delete-staged-dataset.ts +4 -23
  201. package/corpus/templates/dispatch/actions/list-staged-datasets.ts +4 -30
  202. package/corpus/templates/dispatch/actions/provider-api-catalog.ts +15 -18
  203. package/corpus/templates/dispatch/actions/provider-api-docs.ts +57 -48
  204. package/corpus/templates/dispatch/actions/provider-api-request.ts +138 -163
  205. package/corpus/templates/dispatch/actions/query-staged-dataset.ts +4 -47
  206. package/corpus/templates/forms/.agents/skills/actions/SKILL.md +32 -12
  207. package/corpus/templates/forms/.agents/skills/customizing-agent-native/SKILL.md +145 -0
  208. package/corpus/templates/forms/.agents/skills/self-modifying-code/SKILL.md +14 -2
  209. package/corpus/templates/forms/.agents/skills/upgrade-agent-native/SKILL.md +6 -0
  210. package/corpus/templates/forms/server/lib/integrations.ts +23 -22
  211. package/corpus/templates/macros/.agents/skills/customizing-agent-native/SKILL.md +145 -0
  212. package/corpus/templates/macros/.agents/skills/upgrade-agent-native/SKILL.md +6 -0
  213. package/corpus/templates/mail/.agents/skills/actions/SKILL.md +32 -12
  214. package/corpus/templates/mail/.agents/skills/customizing-agent-native/SKILL.md +145 -0
  215. package/corpus/templates/mail/.agents/skills/self-modifying-code/SKILL.md +14 -2
  216. package/corpus/templates/mail/.agents/skills/upgrade-agent-native/SKILL.md +6 -0
  217. package/corpus/templates/mail/actions/delete-staged-dataset.ts +4 -23
  218. package/corpus/templates/mail/actions/list-staged-datasets.ts +4 -27
  219. package/corpus/templates/mail/actions/provider-api-catalog.ts +15 -18
  220. package/corpus/templates/mail/actions/provider-api-docs.ts +57 -48
  221. package/corpus/templates/mail/actions/provider-api-request.ts +146 -173
  222. package/corpus/templates/mail/actions/query-staged-dataset.ts +4 -47
  223. package/corpus/templates/mail/server/handlers/gong.ts +6 -61
  224. package/corpus/templates/mail/server/lib/google-auth.ts +10 -13
  225. package/corpus/templates/plan/.agents/skills/actions/SKILL.md +32 -12
  226. package/corpus/templates/plan/.agents/skills/customizing-agent-native/SKILL.md +145 -0
  227. package/corpus/templates/plan/.agents/skills/self-modifying-code/SKILL.md +14 -2
  228. package/corpus/templates/plan/.agents/skills/upgrade-agent-native/SKILL.md +6 -0
  229. package/corpus/templates/plan/app/components/layout/Sidebar.tsx +47 -156
  230. package/corpus/templates/slides/.agents/skills/actions/SKILL.md +32 -12
  231. package/corpus/templates/slides/.agents/skills/customizing-agent-native/SKILL.md +145 -0
  232. package/corpus/templates/slides/.agents/skills/self-modifying-code/SKILL.md +14 -2
  233. package/corpus/templates/slides/.agents/skills/upgrade-agent-native/SKILL.md +6 -0
  234. package/corpus/templates/slides/actions/delete-staged-dataset.ts +4 -23
  235. package/corpus/templates/slides/actions/list-staged-datasets.ts +4 -27
  236. package/corpus/templates/slides/actions/provider-api-catalog.ts +15 -18
  237. package/corpus/templates/slides/actions/provider-api-docs.ts +57 -48
  238. package/corpus/templates/slides/actions/provider-api-request.ts +145 -172
  239. package/corpus/templates/slides/actions/query-staged-dataset.ts +4 -47
  240. package/corpus/templates/slides/server/lib/google-docs-oauth.ts +11 -36
  241. package/corpus/templates/tasks/.agents/skills/actions/SKILL.md +32 -12
  242. package/corpus/templates/tasks/.agents/skills/agent-native-docs/SKILL.md +21 -9
  243. package/corpus/templates/tasks/.agents/skills/customizing-agent-native/SKILL.md +145 -0
  244. package/corpus/templates/tasks/.agents/skills/self-modifying-code/SKILL.md +14 -2
  245. package/corpus/templates/tasks/.agents/skills/upgrade-agent-native/SKILL.md +6 -0
  246. package/corpus/toolkit/CHANGELOG.md +131 -0
  247. package/corpus/toolkit/README.md +60 -0
  248. package/corpus/toolkit/agent-native.eject.json +411 -0
  249. package/corpus/toolkit/export-snapshot.json +35 -0
  250. package/corpus/toolkit/migration-manifest.json +4 -0
  251. package/corpus/toolkit/package.json +284 -0
  252. package/corpus/toolkit/scripts/finalize-build.mjs +55 -0
  253. package/corpus/toolkit/src/app-shell/header-actions.tsx +84 -0
  254. package/corpus/toolkit/src/app-shell/index.ts +1 -0
  255. package/corpus/toolkit/src/chat-history/ChatHistoryList.tsx +469 -0
  256. package/corpus/toolkit/src/chat-history/index.ts +7 -0
  257. package/corpus/toolkit/src/chat-history.css +314 -0
  258. package/corpus/toolkit/src/collab-ui/AgentPresenceChip.tsx +69 -0
  259. package/corpus/toolkit/src/collab-ui/LiveCursorOverlay.tsx +241 -0
  260. package/corpus/toolkit/src/collab-ui/PresenceBar.tsx +346 -0
  261. package/corpus/toolkit/src/collab-ui/RecentEditHighlights.tsx +225 -0
  262. package/corpus/toolkit/src/collab-ui/RemoteSelectionRings.tsx +227 -0
  263. package/corpus/toolkit/src/collab-ui/agent-identity.ts +16 -0
  264. package/corpus/toolkit/src/collab-ui/index.ts +39 -0
  265. package/corpus/toolkit/src/collab-ui/lead-client.ts +32 -0
  266. package/corpus/toolkit/src/collab-ui/types.ts +96 -0
  267. package/corpus/toolkit/src/composer/AgentComposerFrame.tsx +59 -0
  268. package/corpus/toolkit/src/composer/ComposerPlusMenu.tsx +983 -0
  269. package/corpus/toolkit/src/composer/MentionPopover.tsx +412 -0
  270. package/corpus/toolkit/src/composer/PastedTextChip.tsx +150 -0
  271. package/corpus/toolkit/src/composer/PromptComposer.tsx +718 -0
  272. package/corpus/toolkit/src/composer/RealtimeVoiceMode.tsx +856 -0
  273. package/corpus/toolkit/src/composer/TiptapComposer.tsx +2936 -0
  274. package/corpus/toolkit/src/composer/VoiceButton.tsx +255 -0
  275. package/corpus/toolkit/src/composer/asset-picker-url.ts +80 -0
  276. package/corpus/toolkit/src/composer/attachment-accept.ts +71 -0
  277. package/corpus/toolkit/src/composer/draft-key.ts +7 -0
  278. package/corpus/toolkit/src/composer/extensions/FileReference.tsx +55 -0
  279. package/corpus/toolkit/src/composer/extensions/MentionReference.tsx +93 -0
  280. package/corpus/toolkit/src/composer/extensions/SkillReference.tsx +56 -0
  281. package/corpus/toolkit/src/composer/index.ts +79 -0
  282. package/corpus/toolkit/src/composer/pasted-text.ts +160 -0
  283. package/corpus/toolkit/src/composer/prompt-attachments.ts +93 -0
  284. package/corpus/toolkit/src/composer/realtime-voice-audio-level.ts +64 -0
  285. package/corpus/toolkit/src/composer/realtime-voice-transcript.ts +134 -0
  286. package/corpus/toolkit/src/composer/runtime-adapters.tsx +343 -0
  287. package/corpus/toolkit/src/composer/types.ts +66 -0
  288. package/corpus/toolkit/src/composer/use-file-search.ts +64 -0
  289. package/corpus/toolkit/src/composer/use-mention-search.ts +90 -0
  290. package/corpus/toolkit/src/composer/use-skills.ts +45 -0
  291. package/corpus/toolkit/src/composer/useRealtimeVoiceMode.tsx +2117 -0
  292. package/corpus/toolkit/src/composer/useVoiceDictation.ts +1191 -0
  293. package/corpus/toolkit/src/context-ui/ContextMeter.tsx +101 -0
  294. package/corpus/toolkit/src/context-ui/ContextSegmentRow.tsx +184 -0
  295. package/corpus/toolkit/src/context-ui/ContextTreemap.tsx +125 -0
  296. package/corpus/toolkit/src/context-ui/ContextXRayPanel.tsx +377 -0
  297. package/corpus/toolkit/src/context-ui/format.ts +42 -0
  298. package/corpus/toolkit/src/context-ui/index.ts +15 -0
  299. package/corpus/toolkit/src/context-ui/types.ts +43 -0
  300. package/corpus/toolkit/src/design-tweaks/index.ts +1 -0
  301. package/corpus/toolkit/src/design-tweaks/visual-style-controls.tsx +1084 -0
  302. package/corpus/toolkit/src/editor/BubbleToolbar.tsx +253 -0
  303. package/corpus/toolkit/src/editor/CodeBlockNode.tsx +254 -0
  304. package/corpus/toolkit/src/editor/DragHandle.ts +1437 -0
  305. package/corpus/toolkit/src/editor/ImageExtension.ts +306 -0
  306. package/corpus/toolkit/src/editor/RegistryBlockContext.tsx +107 -0
  307. package/corpus/toolkit/src/editor/RegistryBlockNode.tsx +652 -0
  308. package/corpus/toolkit/src/editor/RichMarkdownEditor.tsx +81 -0
  309. package/corpus/toolkit/src/editor/RunId.ts +61 -0
  310. package/corpus/toolkit/src/editor/SharedRichEditor.tsx +321 -0
  311. package/corpus/toolkit/src/editor/SlashCommandMenu.tsx +310 -0
  312. package/corpus/toolkit/src/editor/extensions.ts +402 -0
  313. package/corpus/toolkit/src/editor/gfmDoc.ts +92 -0
  314. package/corpus/toolkit/src/editor/index.ts +93 -0
  315. package/corpus/toolkit/src/editor/registrySlashCommands.ts +131 -0
  316. package/corpus/toolkit/src/editor/surgical-apply.ts +192 -0
  317. package/corpus/toolkit/src/editor/useCollabReconcile.ts +589 -0
  318. package/corpus/toolkit/src/editor.css +510 -0
  319. package/corpus/toolkit/src/hooks/index.ts +2 -0
  320. package/corpus/toolkit/src/hooks/use-mobile.tsx +21 -0
  321. package/corpus/toolkit/src/hooks/use-toast.ts +188 -0
  322. package/corpus/toolkit/src/index.ts +8 -0
  323. package/corpus/toolkit/src/onboarding/index.ts +1 -0
  324. package/corpus/toolkit/src/provider.tsx +47 -0
  325. package/corpus/toolkit/src/sharing/VisibilityBadge.tsx +37 -0
  326. package/corpus/toolkit/src/sharing/index.ts +4 -0
  327. package/corpus/toolkit/src/styles.css +21 -0
  328. package/corpus/toolkit/src/ui/accordion.tsx +56 -0
  329. package/corpus/toolkit/src/ui/alert-dialog.tsx +141 -0
  330. package/corpus/toolkit/src/ui/alert.tsx +59 -0
  331. package/corpus/toolkit/src/ui/aspect-ratio.tsx +5 -0
  332. package/corpus/toolkit/src/ui/avatar.tsx +48 -0
  333. package/corpus/toolkit/src/ui/badge.tsx +37 -0
  334. package/corpus/toolkit/src/ui/breadcrumb.tsx +115 -0
  335. package/corpus/toolkit/src/ui/button.tsx +78 -0
  336. package/corpus/toolkit/src/ui/calendar.tsx +214 -0
  337. package/corpus/toolkit/src/ui/card.tsx +86 -0
  338. package/corpus/toolkit/src/ui/carousel.tsx +260 -0
  339. package/corpus/toolkit/src/ui/chart.tsx +375 -0
  340. package/corpus/toolkit/src/ui/checkbox.tsx +28 -0
  341. package/corpus/toolkit/src/ui/collapsible.tsx +9 -0
  342. package/corpus/toolkit/src/ui/command.tsx +174 -0
  343. package/corpus/toolkit/src/ui/context-menu.tsx +202 -0
  344. package/corpus/toolkit/src/ui/date-picker.tsx +64 -0
  345. package/corpus/toolkit/src/ui/dialog.tsx +146 -0
  346. package/corpus/toolkit/src/ui/drawer.tsx +126 -0
  347. package/corpus/toolkit/src/ui/dropdown-menu.tsx +218 -0
  348. package/corpus/toolkit/src/ui/form.tsx +177 -0
  349. package/corpus/toolkit/src/ui/hover-card.tsx +27 -0
  350. package/corpus/toolkit/src/ui/index.ts +52 -0
  351. package/corpus/toolkit/src/ui/input-otp.tsx +69 -0
  352. package/corpus/toolkit/src/ui/input.tsx +22 -0
  353. package/corpus/toolkit/src/ui/label.tsx +24 -0
  354. package/corpus/toolkit/src/ui/logo.tsx +36 -0
  355. package/corpus/toolkit/src/ui/menubar.tsx +235 -0
  356. package/corpus/toolkit/src/ui/navigation-menu.tsx +128 -0
  357. package/corpus/toolkit/src/ui/pagination.tsx +121 -0
  358. package/corpus/toolkit/src/ui/popover.tsx +44 -0
  359. package/corpus/toolkit/src/ui/progress.tsx +26 -0
  360. package/corpus/toolkit/src/ui/radio-group.tsx +42 -0
  361. package/corpus/toolkit/src/ui/resizable.tsx +43 -0
  362. package/corpus/toolkit/src/ui/scroll-area.tsx +46 -0
  363. package/corpus/toolkit/src/ui/select.tsx +158 -0
  364. package/corpus/toolkit/src/ui/separator.tsx +29 -0
  365. package/corpus/toolkit/src/ui/sheet.tsx +160 -0
  366. package/corpus/toolkit/src/ui/sidebar.tsx +777 -0
  367. package/corpus/toolkit/src/ui/skeleton.tsx +18 -0
  368. package/corpus/toolkit/src/ui/slider.tsx +26 -0
  369. package/corpus/toolkit/src/ui/sonner.tsx +58 -0
  370. package/corpus/toolkit/src/ui/spinner.tsx +17 -0
  371. package/corpus/toolkit/src/ui/switch.tsx +27 -0
  372. package/corpus/toolkit/src/ui/table.tsx +117 -0
  373. package/corpus/toolkit/src/ui/tabs.tsx +53 -0
  374. package/corpus/toolkit/src/ui/textarea.tsx +23 -0
  375. package/corpus/toolkit/src/ui/toast.tsx +127 -0
  376. package/corpus/toolkit/src/ui/toaster.tsx +33 -0
  377. package/corpus/toolkit/src/ui/toggle-group.tsx +59 -0
  378. package/corpus/toolkit/src/ui/toggle.tsx +43 -0
  379. package/corpus/toolkit/src/ui/tooltip.tsx +53 -0
  380. package/corpus/toolkit/src/ui/use-toast.ts +3 -0
  381. package/corpus/toolkit/src/utils.ts +8 -0
  382. package/corpus/toolkit/tsconfig.json +23 -0
  383. package/dist/cli/atomic-json-file.d.ts +30 -0
  384. package/dist/cli/atomic-json-file.d.ts.map +1 -0
  385. package/dist/cli/atomic-json-file.js +240 -0
  386. package/dist/cli/atomic-json-file.js.map +1 -0
  387. package/dist/cli/claude-code-participant.d.ts +77 -0
  388. package/dist/cli/claude-code-participant.d.ts.map +1 -0
  389. package/dist/cli/claude-code-participant.js +355 -0
  390. package/dist/cli/claude-code-participant.js.map +1 -0
  391. package/dist/cli/code-agent-executor.d.ts.map +1 -1
  392. package/dist/cli/code-agent-executor.js +18 -10
  393. package/dist/cli/code-agent-executor.js.map +1 -1
  394. package/dist/cli/code-agent-runs.concurrent-worker.d.ts +2 -0
  395. package/dist/cli/code-agent-runs.concurrent-worker.d.ts.map +1 -0
  396. package/dist/cli/code-agent-runs.concurrent-worker.js +32 -0
  397. package/dist/cli/code-agent-runs.concurrent-worker.js.map +1 -0
  398. package/dist/cli/code-agent-runs.d.ts.map +1 -1
  399. package/dist/cli/code-agent-runs.js +43 -56
  400. package/dist/cli/code-agent-runs.js.map +1 -1
  401. package/dist/cli/codex-cli-participant.d.ts +77 -0
  402. package/dist/cli/codex-cli-participant.d.ts.map +1 -0
  403. package/dist/cli/codex-cli-participant.js +354 -0
  404. package/dist/cli/codex-cli-participant.js.map +1 -0
  405. package/dist/cli/eject.d.ts +21 -0
  406. package/dist/cli/eject.d.ts.map +1 -0
  407. package/dist/cli/eject.js +1145 -0
  408. package/dist/cli/eject.js.map +1 -0
  409. package/dist/cli/index.js +15 -0
  410. package/dist/cli/index.js.map +1 -1
  411. package/dist/cli/multi-frontier-runs.d.ts +115 -0
  412. package/dist/cli/multi-frontier-runs.d.ts.map +1 -1
  413. package/dist/cli/multi-frontier-runs.js +831 -113
  414. package/dist/cli/multi-frontier-runs.js.map +1 -1
  415. package/dist/client/chat/ChatHistoryList.d.ts +1 -87
  416. package/dist/client/chat/ChatHistoryList.d.ts.map +1 -1
  417. package/dist/client/chat/ChatHistoryList.js +1 -82
  418. package/dist/client/chat/ChatHistoryList.js.map +1 -1
  419. package/dist/client/index.d.ts +1 -1
  420. package/dist/client/index.d.ts.map +1 -1
  421. package/dist/client/index.js +1 -1
  422. package/dist/client/index.js.map +1 -1
  423. package/dist/client/resources/McpConnectionSuggestion.d.ts +4 -3
  424. package/dist/client/resources/McpConnectionSuggestion.d.ts.map +1 -1
  425. package/dist/client/resources/McpConnectionSuggestion.js +3 -3
  426. package/dist/client/resources/McpConnectionSuggestion.js.map +1 -1
  427. package/dist/client/resources/McpIntegrationDialog.d.ts +4 -3
  428. package/dist/client/resources/McpIntegrationDialog.d.ts.map +1 -1
  429. package/dist/client/resources/McpIntegrationDialog.js +2 -2
  430. package/dist/client/resources/McpIntegrationDialog.js.map +1 -1
  431. package/dist/client/resources/ResourcesPanel.d.ts +4 -1
  432. package/dist/client/resources/ResourcesPanel.d.ts.map +1 -1
  433. package/dist/client/resources/ResourcesPanel.js +9 -7
  434. package/dist/client/resources/ResourcesPanel.js.map +1 -1
  435. package/dist/client/resources/index.d.ts +3 -0
  436. package/dist/client/resources/index.d.ts.map +1 -1
  437. package/dist/client/resources/index.js +3 -0
  438. package/dist/client/resources/index.js.map +1 -1
  439. package/dist/client/resources/mcp-integration-catalog.d.ts +2 -1
  440. package/dist/client/resources/mcp-integration-catalog.d.ts.map +1 -1
  441. package/dist/client/resources/mcp-integration-catalog.js +6 -2
  442. package/dist/client/resources/mcp-integration-catalog.js.map +1 -1
  443. package/dist/client/resources/runtime.d.ts +2 -0
  444. package/dist/client/resources/runtime.d.ts.map +1 -0
  445. package/dist/client/resources/runtime.js +2 -0
  446. package/dist/client/resources/runtime.js.map +1 -0
  447. package/dist/client/setup-connections/catalog.d.ts +2 -0
  448. package/dist/client/setup-connections/catalog.d.ts.map +1 -0
  449. package/dist/client/setup-connections/catalog.js +7 -0
  450. package/dist/client/setup-connections/catalog.js.map +1 -0
  451. package/dist/client/setup-connections/index.d.ts +1 -0
  452. package/dist/client/setup-connections/index.d.ts.map +1 -1
  453. package/dist/client/setup-connections/index.js +1 -0
  454. package/dist/client/setup-connections/index.js.map +1 -1
  455. package/dist/client/setup-connections/runtime.d.ts +2 -0
  456. package/dist/client/setup-connections/runtime.d.ts.map +1 -0
  457. package/dist/client/setup-connections/runtime.js +2 -0
  458. package/dist/client/setup-connections/runtime.js.map +1 -0
  459. package/dist/collab/awareness.d.ts +2 -2
  460. package/dist/collab/awareness.d.ts.map +1 -1
  461. package/dist/collab/routes.d.ts +1 -1
  462. package/dist/connections/catalog.d.ts +5 -3
  463. package/dist/connections/catalog.d.ts.map +1 -1
  464. package/dist/connections/catalog.js +16 -8
  465. package/dist/connections/catalog.js.map +1 -1
  466. package/dist/connections/index.d.ts +1 -1
  467. package/dist/connections/index.d.ts.map +1 -1
  468. package/dist/connections/index.js +1 -1
  469. package/dist/connections/index.js.map +1 -1
  470. package/dist/connections/runtime.d.ts +2 -0
  471. package/dist/connections/runtime.d.ts.map +1 -0
  472. package/dist/connections/runtime.js +2 -0
  473. package/dist/connections/runtime.js.map +1 -0
  474. package/dist/eject/provider-api-definitions.d.ts +34 -0
  475. package/dist/eject/provider-api-definitions.d.ts.map +1 -0
  476. package/dist/eject/provider-api-definitions.js +88 -0
  477. package/dist/eject/provider-api-definitions.js.map +1 -0
  478. package/dist/eject/remote-mcp-presets.d.ts +17 -0
  479. package/dist/eject/remote-mcp-presets.d.ts.map +1 -0
  480. package/dist/eject/remote-mcp-presets.js +81 -0
  481. package/dist/eject/remote-mcp-presets.js.map +1 -0
  482. package/dist/eject/setup-readiness-ui.d.ts +7 -0
  483. package/dist/eject/setup-readiness-ui.d.ts.map +1 -0
  484. package/dist/eject/setup-readiness-ui.js +13 -0
  485. package/dist/eject/setup-readiness-ui.js.map +1 -0
  486. package/dist/eject/workspace-connections.d.ts +11 -0
  487. package/dist/eject/workspace-connections.d.ts.map +1 -0
  488. package/dist/eject/workspace-connections.js +47 -0
  489. package/dist/eject/workspace-connections.js.map +1 -0
  490. package/dist/index.d.ts +1 -1
  491. package/dist/index.d.ts.map +1 -1
  492. package/dist/index.js +1 -1
  493. package/dist/index.js.map +1 -1
  494. package/dist/integrations/adapter-overrides.d.ts +3 -0
  495. package/dist/integrations/adapter-overrides.d.ts.map +1 -0
  496. package/dist/integrations/adapter-overrides.js +7 -0
  497. package/dist/integrations/adapter-overrides.js.map +1 -0
  498. package/dist/integrations/eject/messaging-adapters.d.ts +12 -0
  499. package/dist/integrations/eject/messaging-adapters.d.ts.map +1 -0
  500. package/dist/integrations/eject/messaging-adapters.js +49 -0
  501. package/dist/integrations/eject/messaging-adapters.js.map +1 -0
  502. package/dist/integrations/index.d.ts +5 -3
  503. package/dist/integrations/index.d.ts.map +1 -1
  504. package/dist/integrations/index.js +4 -2
  505. package/dist/integrations/index.js.map +1 -1
  506. package/dist/integrations/plugin.d.ts +32 -1
  507. package/dist/integrations/plugin.d.ts.map +1 -1
  508. package/dist/integrations/plugin.js +19 -12
  509. package/dist/integrations/plugin.js.map +1 -1
  510. package/dist/integrations/runtime.d.ts +2 -0
  511. package/dist/integrations/runtime.d.ts.map +1 -0
  512. package/dist/integrations/runtime.js +2 -0
  513. package/dist/integrations/runtime.js.map +1 -0
  514. package/dist/integrations/slack-manifest.d.ts +1 -1
  515. package/dist/integrations/slack-oauth.d.ts +1 -1
  516. package/dist/integrations/slack-oauth.d.ts.map +1 -1
  517. package/dist/integrations/slack-oauth.js +1 -0
  518. package/dist/integrations/slack-oauth.js.map +1 -1
  519. package/dist/integrations/types.d.ts +3 -1
  520. package/dist/integrations/types.d.ts.map +1 -1
  521. package/dist/integrations/types.js.map +1 -1
  522. package/dist/integrations/webhook-delivery.d.ts +23 -0
  523. package/dist/integrations/webhook-delivery.d.ts.map +1 -0
  524. package/dist/integrations/webhook-delivery.js +32 -0
  525. package/dist/integrations/webhook-delivery.js.map +1 -0
  526. package/dist/notifications/channels.d.ts.map +1 -1
  527. package/dist/notifications/channels.js +4 -9
  528. package/dist/notifications/channels.js.map +1 -1
  529. package/dist/notifications/routes.d.ts +3 -3
  530. package/dist/package-lifecycle/eject-manifest.d.ts +43 -0
  531. package/dist/package-lifecycle/eject-manifest.d.ts.map +1 -0
  532. package/dist/package-lifecycle/eject-manifest.js +219 -0
  533. package/dist/package-lifecycle/eject-manifest.js.map +1 -0
  534. package/dist/package-lifecycle/index.d.ts +1 -0
  535. package/dist/package-lifecycle/index.d.ts.map +1 -1
  536. package/dist/package-lifecycle/index.js +1 -0
  537. package/dist/package-lifecycle/index.js.map +1 -1
  538. package/dist/progress/routes.d.ts +1 -1
  539. package/dist/provider-api/actions/custom-provider-registration.d.ts +136 -0
  540. package/dist/provider-api/actions/custom-provider-registration.d.ts.map +1 -0
  541. package/dist/provider-api/actions/custom-provider-registration.js +154 -0
  542. package/dist/provider-api/actions/custom-provider-registration.js.map +1 -0
  543. package/dist/provider-api/actions/delete-staged-dataset.d.ts +1 -1
  544. package/dist/provider-api/actions/delete-staged-dataset.d.ts.map +1 -1
  545. package/dist/provider-api/actions/delete-staged-dataset.js +3 -34
  546. package/dist/provider-api/actions/delete-staged-dataset.js.map +1 -1
  547. package/dist/provider-api/actions/list-staged-datasets.d.ts +2 -3
  548. package/dist/provider-api/actions/list-staged-datasets.d.ts.map +1 -1
  549. package/dist/provider-api/actions/list-staged-datasets.js +3 -40
  550. package/dist/provider-api/actions/list-staged-datasets.js.map +1 -1
  551. package/dist/provider-api/actions/provider-api-audit.d.ts +7 -0
  552. package/dist/provider-api/actions/provider-api-audit.d.ts.map +1 -0
  553. package/dist/provider-api/actions/provider-api-audit.js +74 -0
  554. package/dist/provider-api/actions/provider-api-audit.js.map +1 -0
  555. package/dist/provider-api/actions/provider-api.d.ts +370 -0
  556. package/dist/provider-api/actions/provider-api.d.ts.map +1 -0
  557. package/dist/provider-api/actions/provider-api.js +280 -0
  558. package/dist/provider-api/actions/provider-api.js.map +1 -0
  559. package/dist/provider-api/actions/query-staged-dataset.d.ts +1 -1
  560. package/dist/provider-api/actions/query-staged-dataset.d.ts.map +1 -1
  561. package/dist/provider-api/actions/query-staged-dataset.js +3 -116
  562. package/dist/provider-api/actions/query-staged-dataset.js.map +1 -1
  563. package/dist/provider-api/actions/staged-datasets.d.ts +190 -0
  564. package/dist/provider-api/actions/staged-datasets.d.ts.map +1 -0
  565. package/dist/provider-api/actions/staged-datasets.js +210 -0
  566. package/dist/provider-api/actions/staged-datasets.js.map +1 -0
  567. package/dist/provider-api/corpus-jobs.d.ts +2 -2
  568. package/dist/provider-api/gong.d.ts +44 -0
  569. package/dist/provider-api/gong.d.ts.map +1 -0
  570. package/dist/provider-api/gong.js +56 -0
  571. package/dist/provider-api/gong.js.map +1 -0
  572. package/dist/provider-api/index.d.ts +6 -2
  573. package/dist/provider-api/index.d.ts.map +1 -1
  574. package/dist/provider-api/index.js +25 -12
  575. package/dist/provider-api/index.js.map +1 -1
  576. package/dist/provider-api/runtime.d.ts +2 -0
  577. package/dist/provider-api/runtime.d.ts.map +1 -0
  578. package/dist/provider-api/runtime.js +2 -0
  579. package/dist/provider-api/runtime.js.map +1 -0
  580. package/dist/scripts/docs/source-search.d.ts +2 -1
  581. package/dist/scripts/docs/source-search.d.ts.map +1 -1
  582. package/dist/scripts/docs/source-search.js +2 -1
  583. package/dist/scripts/docs/source-search.js.map +1 -1
  584. package/dist/secrets/routes.d.ts +9 -9
  585. package/dist/server/google-oauth-credentials.d.ts +35 -0
  586. package/dist/server/google-oauth-credentials.d.ts.map +1 -1
  587. package/dist/server/google-oauth-credentials.js +48 -2
  588. package/dist/server/google-oauth-credentials.js.map +1 -1
  589. package/dist/server/index.d.ts +1 -1
  590. package/dist/server/index.d.ts.map +1 -1
  591. package/dist/server/index.js +1 -1
  592. package/dist/server/index.js.map +1 -1
  593. package/dist/server/transcribe-voice.d.ts +1 -1
  594. package/dist/setup-connections/index.d.ts +1 -1
  595. package/dist/setup-connections/index.d.ts.map +1 -1
  596. package/dist/setup-connections/index.js +1 -1
  597. package/dist/setup-connections/index.js.map +1 -1
  598. package/dist/shared/merge-by-id.d.ts +5 -0
  599. package/dist/shared/merge-by-id.d.ts.map +1 -0
  600. package/dist/shared/merge-by-id.js +7 -0
  601. package/dist/shared/merge-by-id.js.map +1 -0
  602. package/dist/styles/chat-history-list.css +1 -313
  603. package/dist/templates/chat/.agents/skills/actions/SKILL.md +32 -12
  604. package/dist/templates/chat/.agents/skills/agent-native-docs/SKILL.md +21 -9
  605. package/dist/templates/chat/.agents/skills/customizing-agent-native/SKILL.md +145 -0
  606. package/dist/templates/chat/.agents/skills/self-modifying-code/SKILL.md +14 -2
  607. package/dist/templates/chat/.agents/skills/upgrade-agent-native/SKILL.md +6 -0
  608. package/dist/templates/chat/AGENTS.md +6 -2
  609. package/dist/templates/chat/app/components/layout/Sidebar.tsx +51 -157
  610. package/dist/templates/default/.agents/skills/actions/SKILL.md +32 -12
  611. package/dist/templates/default/.agents/skills/agent-native-docs/SKILL.md +21 -9
  612. package/dist/templates/default/.agents/skills/customizing-agent-native/SKILL.md +145 -0
  613. package/dist/templates/default/.agents/skills/integration-webhooks/SKILL.md +323 -0
  614. package/dist/templates/default/.agents/skills/onboarding/SKILL.md +56 -0
  615. package/dist/templates/default/.agents/skills/secrets/SKILL.md +273 -0
  616. package/dist/templates/default/.agents/skills/self-modifying-code/SKILL.md +14 -2
  617. package/dist/templates/default/.agents/skills/upgrade-agent-native/SKILL.md +6 -0
  618. package/dist/templates/default/AGENTS.md +26 -18
  619. package/dist/templates/headless/.agents/skills/actions/SKILL.md +512 -0
  620. package/dist/templates/headless/.agents/skills/agent-native-docs/SKILL.md +21 -9
  621. package/dist/templates/headless/.agents/skills/customizing-agent-native/SKILL.md +145 -0
  622. package/dist/templates/headless/.agents/skills/integration-webhooks/SKILL.md +323 -0
  623. package/dist/templates/headless/.agents/skills/secrets/SKILL.md +273 -0
  624. package/dist/templates/headless/.agents/skills/upgrade-agent-native/SKILL.md +6 -0
  625. package/dist/templates/headless/AGENTS.md +8 -0
  626. package/dist/templates/workspace-core/.agents/skills/actions/SKILL.md +32 -12
  627. package/dist/templates/workspace-core/.agents/skills/agent-native-docs/SKILL.md +21 -9
  628. package/dist/templates/workspace-core/.agents/skills/agent-native-toolkit/SKILL.md +7 -0
  629. package/dist/templates/workspace-core/.agents/skills/customizing-agent-native/SKILL.md +145 -0
  630. package/dist/templates/workspace-core/.agents/skills/self-modifying-code/SKILL.md +14 -2
  631. package/dist/templates/workspace-core/.agents/skills/upgrade-agent-native/SKILL.md +6 -0
  632. package/dist/templates/workspace-core/AGENTS.md +4 -0
  633. package/dist/templates/workspace-root/AGENTS.md +4 -0
  634. package/dist/vite/client.d.ts.map +1 -1
  635. package/dist/vite/client.js +22 -2
  636. package/dist/vite/client.js.map +1 -1
  637. package/docs/AGENTS.md +7 -0
  638. package/docs/content/agent-native-toolkit.mdx +38 -0
  639. package/docs/content/integrations.mdx +63 -2
  640. package/docs/content/package-lifecycle.mdx +54 -4
  641. package/docs/design/provider-integration-authority.md +117 -0
  642. package/package.json +20 -2
  643. package/src/a2a/agent-card.ts +83 -0
  644. package/src/a2a/artifact-response.ts +1648 -0
  645. package/src/a2a/auth-policy.ts +66 -0
  646. package/src/a2a/caller-auth.ts +102 -0
  647. package/src/a2a/client.ts +876 -0
  648. package/src/a2a/correlation.ts +50 -0
  649. package/src/a2a/handlers.ts +1285 -0
  650. package/src/a2a/index.ts +50 -0
  651. package/src/a2a/invoke.ts +348 -0
  652. package/src/a2a/response-text.ts +53 -0
  653. package/src/a2a/server.ts +586 -0
  654. package/src/a2a/task-store.ts +917 -0
  655. package/src/a2a/types.ts +221 -0
  656. package/src/a2a-claims.ts +52 -0
  657. package/src/action-change-marker.ts +74 -0
  658. package/src/action-ui.ts +38 -0
  659. package/src/action.ts +1406 -0
  660. package/src/adapters/cli/index.ts +6 -0
  661. package/src/adapters/cli/registry.ts +73 -0
  662. package/src/adapters/cli/shell-adapter.ts +92 -0
  663. package/src/adapters/cli/types.ts +27 -0
  664. package/src/agent/action-continuation-guidance.ts +38 -0
  665. package/src/agent/app-model-defaults.ts +201 -0
  666. package/src/agent/context-xray/actions/context-evict.ts +56 -0
  667. package/src/agent/context-xray/actions/context-manifest-get.ts +75 -0
  668. package/src/agent/context-xray/actions/context-pin.ts +56 -0
  669. package/src/agent/context-xray/actions/context-preview-get.ts +134 -0
  670. package/src/agent/context-xray/actions/context-report.ts +75 -0
  671. package/src/agent/context-xray/actions/context-restore.ts +51 -0
  672. package/src/agent/context-xray/actions/errors.ts +40 -0
  673. package/src/agent/context-xray/apply-directives.ts +137 -0
  674. package/src/agent/context-xray/directives-store.ts +178 -0
  675. package/src/agent/context-xray/identity.ts +37 -0
  676. package/src/agent/context-xray/manifest.ts +284 -0
  677. package/src/agent/context-xray/migrations.ts +32 -0
  678. package/src/agent/context-xray/plugin.ts +23 -0
  679. package/src/agent/context-xray/schema.ts +17 -0
  680. package/src/agent/context-xray/segments.ts +194 -0
  681. package/src/agent/context-xray/tokenize.ts +93 -0
  682. package/src/agent/default-model.ts +5 -0
  683. package/src/agent/durable-background.ts +547 -0
  684. package/src/agent/engine/ai-sdk-engine.ts +565 -0
  685. package/src/agent/engine/anthropic-engine.ts +320 -0
  686. package/src/agent/engine/builder-engine.ts +1110 -0
  687. package/src/agent/engine/builder-gateway-headers.ts +44 -0
  688. package/src/agent/engine/builtin.ts +122 -0
  689. package/src/agent/engine/context-directives-transform.ts +73 -0
  690. package/src/agent/engine/continuation-dispatch-retry.ts +168 -0
  691. package/src/agent/engine/credential-errors.ts +69 -0
  692. package/src/agent/engine/index.ts +54 -0
  693. package/src/agent/engine/openai-compatible-endpoint.ts +25 -0
  694. package/src/agent/engine/output-tokens.ts +181 -0
  695. package/src/agent/engine/provider-env-vars.ts +69 -0
  696. package/src/agent/engine/registry.ts +853 -0
  697. package/src/agent/engine/tool-call-journal-seed.ts +85 -0
  698. package/src/agent/engine/translate-ai-sdk.ts +407 -0
  699. package/src/agent/engine/translate-anthropic.ts +611 -0
  700. package/src/agent/engine/types.ts +310 -0
  701. package/src/agent/harness/acp-adapter.ts +893 -0
  702. package/src/agent/harness/acp-builtin.ts +70 -0
  703. package/src/agent/harness/ai-sdk-adapter.ts +509 -0
  704. package/src/agent/harness/background.ts +365 -0
  705. package/src/agent/harness/builtin.ts +50 -0
  706. package/src/agent/harness/index.ts +86 -0
  707. package/src/agent/harness/lifecycle.ts +498 -0
  708. package/src/agent/harness/registry.ts +97 -0
  709. package/src/agent/harness/runner.ts +182 -0
  710. package/src/agent/harness/store.ts +466 -0
  711. package/src/agent/harness/translate.ts +130 -0
  712. package/src/agent/harness/types.ts +129 -0
  713. package/src/agent/index.ts +32 -0
  714. package/src/agent/loop-settings.ts +186 -0
  715. package/src/agent/model-config.ts +363 -0
  716. package/src/agent/observational-memory/compactor.ts +78 -0
  717. package/src/agent/observational-memory/config.ts +78 -0
  718. package/src/agent/observational-memory/index.ts +79 -0
  719. package/src/agent/observational-memory/internal-run.ts +89 -0
  720. package/src/agent/observational-memory/message-text.ts +49 -0
  721. package/src/agent/observational-memory/migrations.ts +44 -0
  722. package/src/agent/observational-memory/observer.ts +128 -0
  723. package/src/agent/observational-memory/plugin.ts +35 -0
  724. package/src/agent/observational-memory/prompts.ts +53 -0
  725. package/src/agent/observational-memory/read.ts +131 -0
  726. package/src/agent/observational-memory/reflector.ts +119 -0
  727. package/src/agent/observational-memory/schema.ts +48 -0
  728. package/src/agent/observational-memory/store.ts +275 -0
  729. package/src/agent/observational-memory/types.ts +65 -0
  730. package/src/agent/processors.ts +209 -0
  731. package/src/agent/production-agent.ts +8254 -0
  732. package/src/agent/run-loop-with-resume.ts +394 -0
  733. package/src/agent/run-manager.ts +1825 -0
  734. package/src/agent/run-ownership.ts +75 -0
  735. package/src/agent/run-store.ts +2601 -0
  736. package/src/agent/runtime-context.ts +169 -0
  737. package/src/agent/thread-data-builder.ts +1584 -0
  738. package/src/agent/tool-call-journal.ts +368 -0
  739. package/src/agent/tool-error-redaction.ts +52 -0
  740. package/src/agent/tool-result-images.ts +178 -0
  741. package/src/agent/tool-search.ts +376 -0
  742. package/src/agent/types.ts +372 -0
  743. package/src/agent-native/index.ts +198 -0
  744. package/src/agent-web/config.ts +253 -0
  745. package/src/agent-web/generator.ts +382 -0
  746. package/src/agent-web/index.ts +36 -0
  747. package/src/appearance/actions/change-appearance.ts +35 -0
  748. package/src/application-state/emitter.ts +81 -0
  749. package/src/application-state/handlers.ts +121 -0
  750. package/src/application-state/index.ts +44 -0
  751. package/src/application-state/script-helpers.ts +155 -0
  752. package/src/application-state/store.ts +274 -0
  753. package/src/assets/branding/agent-native.icon/Assets/background.svg +3 -0
  754. package/src/assets/branding/agent-native.icon/Assets/foreground.svg +12 -0
  755. package/src/assets/branding/agent-native.icon/icon.json +49 -0
  756. package/src/assets/branding/favicon.png +0 -0
  757. package/src/assets/branding/favicon.svg +1 -0
  758. package/src/assets/branding/icon-on-dark.svg +10 -0
  759. package/src/assets/branding/icon-on-light.svg +10 -0
  760. package/src/assets/branding/mac-app-icon.svg +1 -0
  761. package/src/assets/branding/slack-bot/agent-native-1024.png +0 -0
  762. package/src/assets/branding/slack-bot/agent-native-512.png +0 -0
  763. package/src/assets/branding/tray-icon.svg +6 -0
  764. package/src/assets/branding/wordmark-on-dark.svg +21 -0
  765. package/src/assets/branding/wordmark-on-light.svg +21 -0
  766. package/src/assets/fonts/LICENSE_LIBERATION +96 -0
  767. package/src/assets/fonts/LICENSE_NOTO_NASKH_ARABIC +93 -0
  768. package/src/assets/fonts/LiberationSans-Bold.ttf +0 -0
  769. package/src/assets/fonts/LiberationSans-Regular.ttf +0 -0
  770. package/src/assets/fonts/NotoNaskhArabic-Variable.ttf +0 -0
  771. package/src/audit/actions/export-audit-events.ts +162 -0
  772. package/src/audit/actions/get-audit-event.ts +24 -0
  773. package/src/audit/actions/list-audit-events.ts +66 -0
  774. package/src/audit/cleanup-job.ts +100 -0
  775. package/src/audit/config.ts +90 -0
  776. package/src/audit/index.ts +43 -0
  777. package/src/audit/record.ts +180 -0
  778. package/src/audit/redact.ts +109 -0
  779. package/src/audit/store.ts +346 -0
  780. package/src/audit/types.ts +141 -0
  781. package/src/automation/index.ts +802 -0
  782. package/src/brand-kit/brand-signals.ts +124 -0
  783. package/src/brand-kit/fig/index.ts +64 -0
  784. package/src/brand-kit/index.ts +72 -0
  785. package/src/brand-kit/types.ts +113 -0
  786. package/src/browser-sessions/actions.ts +302 -0
  787. package/src/browser-sessions/routes.ts +234 -0
  788. package/src/browser-sessions/store.ts +679 -0
  789. package/src/browser-sessions/types.ts +84 -0
  790. package/src/changelog/parse.ts +328 -0
  791. package/src/chat-threads/emitter.ts +22 -0
  792. package/src/chat-threads/schema.ts +43 -0
  793. package/src/chat-threads/store.ts +1311 -0
  794. package/src/checkpoints/index.ts +15 -0
  795. package/src/checkpoints/service.ts +142 -0
  796. package/src/checkpoints/store.ts +153 -0
  797. package/src/cli/add.ts +425 -0
  798. package/src/cli/agent.ts +424 -0
  799. package/src/cli/agents.ts +122 -0
  800. package/src/cli/app-skill.ts +1455 -0
  801. package/src/cli/atomic-json-file.ts +324 -0
  802. package/src/cli/audit-agent-web.ts +324 -0
  803. package/src/cli/changelog.ts +199 -0
  804. package/src/cli/claude-code-participant.ts +515 -0
  805. package/src/cli/code-agent-commands.ts +270 -0
  806. package/src/cli/code-agent-connector.ts +1109 -0
  807. package/src/cli/code-agent-executor.ts +1970 -0
  808. package/src/cli/code-agent-output-smoother.ts +140 -0
  809. package/src/cli/code-agent-runs.concurrent-worker.ts +33 -0
  810. package/src/cli/code-agent-runs.ts +548 -0
  811. package/src/cli/code.ts +1805 -0
  812. package/src/cli/codex-cli-participant.ts +496 -0
  813. package/src/cli/connect.ts +2714 -0
  814. package/src/cli/content-local.ts +442 -0
  815. package/src/cli/context-xray-local.ts +2193 -0
  816. package/src/cli/create-workspace.ts +30 -0
  817. package/src/cli/create.ts +2247 -0
  818. package/src/cli/deploy-build.ts +50 -0
  819. package/src/cli/design-connect.ts +3187 -0
  820. package/src/cli/doctor.ts +472 -0
  821. package/src/cli/eject.ts +1594 -0
  822. package/src/cli/eval.ts +134 -0
  823. package/src/cli/gateway-helpers.ts +70 -0
  824. package/src/cli/index.ts +1217 -0
  825. package/src/cli/info.ts +105 -0
  826. package/src/cli/invoke.ts +288 -0
  827. package/src/cli/mcp-config-writers.ts +857 -0
  828. package/src/cli/mcp.ts +594 -0
  829. package/src/cli/migrate.ts +1813 -0
  830. package/src/cli/migration-codemod.ts +646 -0
  831. package/src/cli/multi-frontier-runs.ts +1952 -0
  832. package/src/cli/package-lifecycle.ts +823 -0
  833. package/src/cli/plan-blocks.ts +143 -0
  834. package/src/cli/plan-local.ts +3189 -0
  835. package/src/cli/plan-publish-store.ts +138 -0
  836. package/src/cli/pr-visual-recap-workflow.ts +2 -0
  837. package/src/cli/recap.ts +5 -0
  838. package/src/cli/setup-agents.ts +120 -0
  839. package/src/cli/skills-content/assets-skill.ts +83 -0
  840. package/src/cli/skills-content/canvas.ts +153 -0
  841. package/src/cli/skills-content/connection.ts +52 -0
  842. package/src/cli/skills-content/content-skill.ts +120 -0
  843. package/src/cli/skills-content/design-exploration-skill.ts +118 -0
  844. package/src/cli/skills-content/design-visual-edit-skill.ts +228 -0
  845. package/src/cli/skills-content/document-quality.ts +196 -0
  846. package/src/cli/skills-content/exemplar.ts +69 -0
  847. package/src/cli/skills-content/help.ts +77 -0
  848. package/src/cli/skills-content/index.ts +22 -0
  849. package/src/cli/skills-content/local-files.ts +100 -0
  850. package/src/cli/skills-content/plan-setup-auth.ts +80 -0
  851. package/src/cli/skills-content/visual-plan-skill.ts +493 -0
  852. package/src/cli/skills-content/visual-recap-skill.ts +553 -0
  853. package/src/cli/skills-content/visualize-repo-skill.ts +93 -0
  854. package/src/cli/skills-content/wireframe.ts +349 -0
  855. package/src/cli/skills.ts +4340 -0
  856. package/src/cli/sync-builder-starter-manifest.ts +631 -0
  857. package/src/cli/telemetry.ts +136 -0
  858. package/src/cli/templates-meta.ts +269 -0
  859. package/src/cli/upgrade.ts +956 -0
  860. package/src/cli/visualize-repo.ts +715 -0
  861. package/src/cli/workspace-dev.ts +1486 -0
  862. package/src/cli/workspacify.ts +258 -0
  863. package/src/client/AgentAskPopover.tsx +89 -0
  864. package/src/client/AgentChatHome.tsx +66 -0
  865. package/src/client/AgentNative.tsx +161 -0
  866. package/src/client/AgentNativeEmbedded.tsx +288 -0
  867. package/src/client/AgentNativeFrame.tsx +151 -0
  868. package/src/client/AgentPanel.tsx +3437 -0
  869. package/src/client/AgentTaskCard.tsx +273 -0
  870. package/src/client/AppearancePicker.tsx +79 -0
  871. package/src/client/AssistantChat.tsx +5793 -0
  872. package/src/client/ClientOnly.tsx +22 -0
  873. package/src/client/CommandMenu.tsx +726 -0
  874. package/src/client/ConnectBuilderCard.tsx +390 -0
  875. package/src/client/DefaultSpinner.tsx +47 -0
  876. package/src/client/ErrorBoundary.tsx +359 -0
  877. package/src/client/ErrorReportActions.tsx +69 -0
  878. package/src/client/FeedbackButton.tsx +553 -0
  879. package/src/client/HighlightedCodeBlock.tsx +173 -0
  880. package/src/client/IframeEmbed.tsx +151 -0
  881. package/src/client/KeepTabOpenNotice.tsx +181 -0
  882. package/src/client/MultiTabAssistantChat.tsx +2576 -0
  883. package/src/client/NewWorkspaceAppFlow.tsx +525 -0
  884. package/src/client/PoweredByBadge.tsx +284 -0
  885. package/src/client/RunStuckBanner.tsx +431 -0
  886. package/src/client/StarfieldBackground.tsx +466 -0
  887. package/src/client/Turnstile.tsx +125 -0
  888. package/src/client/active-run-state.ts +139 -0
  889. package/src/client/agent-chat/index.ts +279 -0
  890. package/src/client/agent-chat-adapter.ts +3692 -0
  891. package/src/client/agent-chat.ts +1233 -0
  892. package/src/client/agent-engine-key.ts +122 -0
  893. package/src/client/agent-page/AgentContextTab.tsx +487 -0
  894. package/src/client/agent-page/AgentEmptyState.tsx +44 -0
  895. package/src/client/agent-page/AgentJobsTab.tsx +441 -0
  896. package/src/client/agent-page/AgentTabFrame.tsx +39 -0
  897. package/src/client/agent-page/AgentTabsPage.tsx +1096 -0
  898. package/src/client/agent-page/types.ts +18 -0
  899. package/src/client/agent-page/use-jobs.ts +150 -0
  900. package/src/client/agent-sidebar-state.ts +166 -0
  901. package/src/client/analytics/index.ts +40 -0
  902. package/src/client/analytics-session.ts +70 -0
  903. package/src/client/analytics.ts +1757 -0
  904. package/src/client/api-path.ts +124 -0
  905. package/src/client/app-providers.tsx +230 -0
  906. package/src/client/appearance.ts +130 -0
  907. package/src/client/application-state.ts +154 -0
  908. package/src/client/assistant-ui-recovery.tsx +205 -0
  909. package/src/client/automation/index.ts +4 -0
  910. package/src/client/automation.ts +22 -0
  911. package/src/client/blocks/AiEditableField.tsx +30 -0
  912. package/src/client/blocks/BlockView.tsx +145 -0
  913. package/src/client/blocks/RegistryBlockDataProvider.tsx +121 -0
  914. package/src/client/blocks/SchemaBlockEditor.tsx +457 -0
  915. package/src/client/blocks/agent.ts +95 -0
  916. package/src/client/blocks/code-block-direction.ts +21 -0
  917. package/src/client/blocks/index.ts +308 -0
  918. package/src/client/blocks/library/AnnotatedCodeBlock.tsx +710 -0
  919. package/src/client/blocks/library/ApiEndpointBlock.tsx +1120 -0
  920. package/src/client/blocks/library/DataModelBlock.tsx +775 -0
  921. package/src/client/blocks/library/DiffBlock.tsx +1854 -0
  922. package/src/client/blocks/library/FileTreeBlock.tsx +868 -0
  923. package/src/client/blocks/library/HighlightedCode.tsx +260 -0
  924. package/src/client/blocks/library/JsonExplorerBlock.tsx +608 -0
  925. package/src/client/blocks/library/MermaidBlock.tsx +362 -0
  926. package/src/client/blocks/library/OpenApiSpecBlock.tsx +998 -0
  927. package/src/client/blocks/library/annotated-code.config.ts +101 -0
  928. package/src/client/blocks/library/annotation-rail.tsx +1020 -0
  929. package/src/client/blocks/library/api-endpoint.config.ts +207 -0
  930. package/src/client/blocks/library/block-copy.ts +399 -0
  931. package/src/client/blocks/library/callout.config.ts +57 -0
  932. package/src/client/blocks/library/callout.tsx +149 -0
  933. package/src/client/blocks/library/checklist.config.ts +56 -0
  934. package/src/client/blocks/library/checklist.tsx +208 -0
  935. package/src/client/blocks/library/code-filename-label.tsx +59 -0
  936. package/src/client/blocks/library/code-highlight.tsx +178 -0
  937. package/src/client/blocks/library/code-tabs.config.ts +70 -0
  938. package/src/client/blocks/library/code-tabs.tsx +606 -0
  939. package/src/client/blocks/library/code.config.ts +69 -0
  940. package/src/client/blocks/library/code.tsx +440 -0
  941. package/src/client/blocks/library/columns.config.ts +85 -0
  942. package/src/client/blocks/library/columns.tsx +334 -0
  943. package/src/client/blocks/library/data-model.config.ts +152 -0
  944. package/src/client/blocks/library/dev-doc-ui.tsx +191 -0
  945. package/src/client/blocks/library/diagram.config.ts +222 -0
  946. package/src/client/blocks/library/diagram.tsx +958 -0
  947. package/src/client/blocks/library/diff.config.ts +115 -0
  948. package/src/client/blocks/library/file-tree.config.ts +92 -0
  949. package/src/client/blocks/library/html.config.ts +79 -0
  950. package/src/client/blocks/library/html.tsx +258 -0
  951. package/src/client/blocks/library/json-explorer.config.ts +74 -0
  952. package/src/client/blocks/library/mermaid.config.ts +49 -0
  953. package/src/client/blocks/library/narrow-container.tsx +37 -0
  954. package/src/client/blocks/library/openapi-spec.config.ts +66 -0
  955. package/src/client/blocks/library/question-form.config.ts +127 -0
  956. package/src/client/blocks/library/question-form.tsx +944 -0
  957. package/src/client/blocks/library/sanitize-html.ts +343 -0
  958. package/src/client/blocks/library/server-specs.ts +338 -0
  959. package/src/client/blocks/library/specs.tsx +308 -0
  960. package/src/client/blocks/library/table.config.ts +61 -0
  961. package/src/client/blocks/library/table.tsx +449 -0
  962. package/src/client/blocks/library/tabs.config.ts +96 -0
  963. package/src/client/blocks/library/tabs.tsx +665 -0
  964. package/src/client/blocks/library/wireframe-icons.ts +210 -0
  965. package/src/client/blocks/library/wireframe-kit.tsx +1850 -0
  966. package/src/client/blocks/library/wireframe.config.ts +539 -0
  967. package/src/client/blocks/library/wireframe.tsx +535 -0
  968. package/src/client/blocks/mdx.ts +364 -0
  969. package/src/client/blocks/provider.tsx +51 -0
  970. package/src/client/blocks/registry.ts +83 -0
  971. package/src/client/blocks/schema-form/introspect.ts +201 -0
  972. package/src/client/blocks/server.ts +170 -0
  973. package/src/client/blocks/types.ts +415 -0
  974. package/src/client/browser-session-bridge.ts +548 -0
  975. package/src/client/browser-tab-id.ts +36 -0
  976. package/src/client/builder-frame.ts +194 -0
  977. package/src/client/builder-mark.tsx +21 -0
  978. package/src/client/changelog/Changelog.tsx +333 -0
  979. package/src/client/changelog/index.ts +1 -0
  980. package/src/client/chat/ChatHistoryList.tsx +7 -0
  981. package/src/client/chat/attachment-adapters.ts +426 -0
  982. package/src/client/chat/connectors.ts +1579 -0
  983. package/src/client/chat/index.ts +160 -0
  984. package/src/client/chat/markdown-renderer.tsx +693 -0
  985. package/src/client/chat/message-components.tsx +1326 -0
  986. package/src/client/chat/repo-helpers.ts +281 -0
  987. package/src/client/chat/run-recovery.tsx +994 -0
  988. package/src/client/chat/runtime.ts +1810 -0
  989. package/src/client/chat/tool-call-display.tsx +1270 -0
  990. package/src/client/chat/tool-render-registry.tsx +144 -0
  991. package/src/client/chat/use-agent-chat-lifecycle-tracking.ts +74 -0
  992. package/src/client/chat/use-reconnect-reader-owner.ts +28 -0
  993. package/src/client/chat/widgets/DataChartRenderer.tsx +242 -0
  994. package/src/client/chat/widgets/DataChartWidget.tsx +51 -0
  995. package/src/client/chat/widgets/DataInsightsWidget.tsx +59 -0
  996. package/src/client/chat/widgets/DataTableWidget.tsx +240 -0
  997. package/src/client/chat/widgets/InlineExtensionWidget.tsx +60 -0
  998. package/src/client/chat/widgets/builtin-tool-renderers.tsx +213 -0
  999. package/src/client/chat/widgets/data-widget-types.ts +1 -0
  1000. package/src/client/chat/widgets/inline-extension-result.ts +86 -0
  1001. package/src/client/chat-model-groups.ts +171 -0
  1002. package/src/client/chat-thread-url.ts +11 -0
  1003. package/src/client/chat-view-transition.ts +213 -0
  1004. package/src/client/client-action.ts +21 -0
  1005. package/src/client/client-bootstrap.ts +7 -0
  1006. package/src/client/client-surface.ts +41 -0
  1007. package/src/client/clipboard.ts +89 -0
  1008. package/src/client/code-agent-chat-adapter.ts +537 -0
  1009. package/src/client/collab/index.ts +60 -0
  1010. package/src/client/command-navigation/index.ts +15 -0
  1011. package/src/client/comments-review/index.ts +1 -0
  1012. package/src/client/components/AgentPresenceChip.tsx +4 -0
  1013. package/src/client/components/ApiKeySettings.tsx +309 -0
  1014. package/src/client/components/CodeAgentIndicator.tsx +59 -0
  1015. package/src/client/components/CodeRequiredDialog.tsx +470 -0
  1016. package/src/client/components/LiveCursorOverlay.tsx +5 -0
  1017. package/src/client/components/MissingKeyCard.tsx +61 -0
  1018. package/src/client/components/PresenceBar.tsx +4 -0
  1019. package/src/client/components/RecentEditHighlights.tsx +4 -0
  1020. package/src/client/components/RemoteSelectionRings.tsx +5 -0
  1021. package/src/client/components/icons/AgentNativeIcon.tsx +46 -0
  1022. package/src/client/components/ui/dialog.tsx +1 -0
  1023. package/src/client/components/ui/dropdown-menu.tsx +1 -0
  1024. package/src/client/components/ui/hover-card.tsx +1 -0
  1025. package/src/client/components/ui/message-scroller.tsx +131 -0
  1026. package/src/client/components/ui/popover.tsx +1 -0
  1027. package/src/client/components/ui/sheet.tsx +1 -0
  1028. package/src/client/components/ui/tooltip.tsx +1 -0
  1029. package/src/client/composer/index.ts +11 -0
  1030. package/src/client/composer/runtime-adapters.tsx +123 -0
  1031. package/src/client/composer/use-mention-search.ts +7 -0
  1032. package/src/client/composer/wired-components.tsx +53 -0
  1033. package/src/client/context-xray/ContextMeter.tsx +124 -0
  1034. package/src/client/context-xray/ContextSegmentRow.tsx +27 -0
  1035. package/src/client/context-xray/ContextTreemap.tsx +24 -0
  1036. package/src/client/context-xray/ContextXRayPanel.tsx +59 -0
  1037. package/src/client/context-xray/SegmentProvenancePopover.tsx +18 -0
  1038. package/src/client/context-xray/format.ts +27 -0
  1039. package/src/client/conversation/AgentConversation.tsx +555 -0
  1040. package/src/client/conversation/code-agent-transcript.ts +283 -0
  1041. package/src/client/conversation/index.ts +22 -0
  1042. package/src/client/conversation/types.ts +85 -0
  1043. package/src/client/conversation/use-near-bottom-autoscroll.ts +278 -0
  1044. package/src/client/create-query-client.ts +86 -0
  1045. package/src/client/db-admin/DataGrid.tsx +551 -0
  1046. package/src/client/db-admin/DbAdminPage.tsx +218 -0
  1047. package/src/client/db-admin/DevDatabaseLink.tsx +16 -0
  1048. package/src/client/db-admin/EditableCell.tsx +451 -0
  1049. package/src/client/db-admin/FilterBar.tsx +203 -0
  1050. package/src/client/db-admin/ResultsGrid.tsx +114 -0
  1051. package/src/client/db-admin/RowSidePanel.tsx +337 -0
  1052. package/src/client/db-admin/SqlEditor.tsx +840 -0
  1053. package/src/client/db-admin/TableBrowser.tsx +212 -0
  1054. package/src/client/db-admin/TableEditor.tsx +760 -0
  1055. package/src/client/db-admin/cell-format.ts +246 -0
  1056. package/src/client/db-admin/changeset.ts +296 -0
  1057. package/src/client/db-admin/export-utils.ts +78 -0
  1058. package/src/client/db-admin/index.ts +33 -0
  1059. package/src/client/db-admin/sql-storage.ts +134 -0
  1060. package/src/client/db-admin/storage.ts +68 -0
  1061. package/src/client/db-admin/useAgentSync.ts +226 -0
  1062. package/src/client/db-admin/useDbAdmin.ts +294 -0
  1063. package/src/client/dev-overlay/DevOverlay.tsx +576 -0
  1064. package/src/client/dev-overlay/builtins.ts +40 -0
  1065. package/src/client/dev-overlay/index.ts +23 -0
  1066. package/src/client/dev-overlay/registry.ts +67 -0
  1067. package/src/client/dev-overlay/types.ts +64 -0
  1068. package/src/client/dev-overlay/use-dev-option.ts +78 -0
  1069. package/src/client/dev-overlay/use-dev-overlay-shortcut.ts +31 -0
  1070. package/src/client/dynamic-suggestions.ts +455 -0
  1071. package/src/client/embed-auth.ts +544 -0
  1072. package/src/client/embed.ts +54 -0
  1073. package/src/client/error-capture.ts +690 -0
  1074. package/src/client/error-format.ts +211 -0
  1075. package/src/client/error-reporting.ts +100 -0
  1076. package/src/client/extensions/AgentNativeExtensionFrame.e2e-host.tsx +136 -0
  1077. package/src/client/extensions/AgentNativeExtensionFrame.tsx +708 -0
  1078. package/src/client/extensions/EmbeddedExtension.tsx +604 -0
  1079. package/src/client/extensions/ExtensionEditor.tsx +450 -0
  1080. package/src/client/extensions/ExtensionQueryErrorState.tsx +47 -0
  1081. package/src/client/extensions/ExtensionSlot.tsx +345 -0
  1082. package/src/client/extensions/ExtensionViewer.tsx +1502 -0
  1083. package/src/client/extensions/ExtensionViewerPage.tsx +32 -0
  1084. package/src/client/extensions/ExtensionsListPage.tsx +432 -0
  1085. package/src/client/extensions/ExtensionsSidebarSection.tsx +1259 -0
  1086. package/src/client/extensions/InlineExtensionFrame.tsx +660 -0
  1087. package/src/client/extensions/agent-native-extension-runtime.ts +495 -0
  1088. package/src/client/extensions/delete-extension.ts +76 -0
  1089. package/src/client/extensions/extension-load-error.ts +26 -0
  1090. package/src/client/extensions/extension-order.ts +49 -0
  1091. package/src/client/extensions/extension-popularity.ts +61 -0
  1092. package/src/client/extensions/iframe-bridge.ts +377 -0
  1093. package/src/client/extensions/index.ts +84 -0
  1094. package/src/client/extensions/portable-extension.ts +712 -0
  1095. package/src/client/feature-flags/FeatureFlagsPanel.tsx +519 -0
  1096. package/src/client/feature-flags/helpers.ts +77 -0
  1097. package/src/client/feature-flags/index.ts +13 -0
  1098. package/src/client/feature-flags/types.ts +29 -0
  1099. package/src/client/feature-flags/use-feature-flag.ts +26 -0
  1100. package/src/client/feedback-context.ts +90 -0
  1101. package/src/client/frame-protocol.ts +168 -0
  1102. package/src/client/frame.ts +329 -0
  1103. package/src/client/guided-questions.tsx +1152 -0
  1104. package/src/client/history/VersionHistoryPanel.tsx +175 -0
  1105. package/src/client/history/index.ts +21 -0
  1106. package/src/client/history/use-history.ts +114 -0
  1107. package/src/client/hooks/index.ts +46 -0
  1108. package/src/client/host/index.ts +170 -0
  1109. package/src/client/host-bridge.ts +1272 -0
  1110. package/src/client/host-tools.ts +190 -0
  1111. package/src/client/i18n.tsx +798 -0
  1112. package/src/client/index.ts +370 -0
  1113. package/src/client/integrations/IntegrationCard.tsx +186 -0
  1114. package/src/client/integrations/IntegrationsPanel.tsx +633 -0
  1115. package/src/client/integrations/api.ts +295 -0
  1116. package/src/client/integrations/index.ts +29 -0
  1117. package/src/client/integrations/useIntegrationStatus.ts +52 -0
  1118. package/src/client/mcp-app-host.ts +720 -0
  1119. package/src/client/mcp-apps/McpAppRenderer.tsx +760 -0
  1120. package/src/client/navigation/index.ts +54 -0
  1121. package/src/client/notifications/NotificationsBell.tsx +383 -0
  1122. package/src/client/notifications/index.ts +1 -0
  1123. package/src/client/observability/ObservabilityDashboard.tsx +890 -0
  1124. package/src/client/observability/ThumbsFeedback.tsx +160 -0
  1125. package/src/client/observability/index.ts +20 -0
  1126. package/src/client/observability/useObservability.ts +266 -0
  1127. package/src/client/onboarding/OnboardingBanner.tsx +73 -0
  1128. package/src/client/onboarding/OnboardingPanel.tsx +1036 -0
  1129. package/src/client/onboarding/SetupButton.tsx +64 -0
  1130. package/src/client/onboarding/index.ts +25 -0
  1131. package/src/client/onboarding/use-onboarding.ts +164 -0
  1132. package/src/client/onboarding/use-preview-mode.ts +40 -0
  1133. package/src/client/org/InvitationBanner.tsx +148 -0
  1134. package/src/client/org/OrgSwitcher.tsx +754 -0
  1135. package/src/client/org/RequireActiveOrg.tsx +337 -0
  1136. package/src/client/org/TeamPage.tsx +1432 -0
  1137. package/src/client/org/hooks.ts +359 -0
  1138. package/src/client/org/index.ts +70 -0
  1139. package/src/client/org/workspace-app-links.ts +367 -0
  1140. package/src/client/org-team/index.ts +1 -0
  1141. package/src/client/progress/RunsTray.tsx +680 -0
  1142. package/src/client/progress/index.ts +1 -0
  1143. package/src/client/require-session.tsx +142 -0
  1144. package/src/client/resources/BuiltinCapabilityDetail.tsx +258 -0
  1145. package/src/client/resources/McpConnectionSuggestion.tsx +276 -0
  1146. package/src/client/resources/McpIntegrationDialog.tsx +808 -0
  1147. package/src/client/resources/McpServerDetail.tsx +230 -0
  1148. package/src/client/resources/ResourceEditor.tsx +872 -0
  1149. package/src/client/resources/ResourceTree.tsx +860 -0
  1150. package/src/client/resources/ResourcesPanel.tsx +1960 -0
  1151. package/src/client/resources/index.ts +25 -0
  1152. package/src/client/resources/mcp-integration-catalog.ts +771 -0
  1153. package/src/client/resources/mcp-integration-logos.ts +108 -0
  1154. package/src/client/resources/runtime.ts +1 -0
  1155. package/src/client/resources/use-builtin-capabilities.ts +113 -0
  1156. package/src/client/resources/use-mcp-servers.ts +217 -0
  1157. package/src/client/resources/use-resources.ts +402 -0
  1158. package/src/client/review/ReviewCommentComposer.tsx +123 -0
  1159. package/src/client/review/ReviewStatusBadge.tsx +39 -0
  1160. package/src/client/review/ReviewThreadPanel.tsx +625 -0
  1161. package/src/client/review/index.ts +38 -0
  1162. package/src/client/review/use-review.ts +186 -0
  1163. package/src/client/route-chunk-recovery/index.ts +1 -0
  1164. package/src/client/route-chunk-recovery.ts +331 -0
  1165. package/src/client/route-state.ts +455 -0
  1166. package/src/client/route-warmup.tsx +543 -0
  1167. package/src/client/session-replay-iframe.e2e-host.tsx +100 -0
  1168. package/src/client/session-replay.ts +3417 -0
  1169. package/src/client/settings/AgentsSection.tsx +441 -0
  1170. package/src/client/settings/AutomationsSection.tsx +516 -0
  1171. package/src/client/settings/BackgroundAgentSection.tsx +189 -0
  1172. package/src/client/settings/BrowserSection.tsx +110 -0
  1173. package/src/client/settings/DemoModeSection.tsx +48 -0
  1174. package/src/client/settings/SecretsSection.tsx +875 -0
  1175. package/src/client/settings/SettingsPanel.tsx +3162 -0
  1176. package/src/client/settings/SettingsSection.tsx +283 -0
  1177. package/src/client/settings/SettingsTabsPage.tsx +592 -0
  1178. package/src/client/settings/UsageSection.tsx +401 -0
  1179. package/src/client/settings/VoiceTranscriptionSection.tsx +960 -0
  1180. package/src/client/settings/agent-settings-search.ts +220 -0
  1181. package/src/client/settings/index.ts +27 -0
  1182. package/src/client/settings/useBuilderStatus.ts +1055 -0
  1183. package/src/client/setup-connections/BuilderConnectCard.tsx +89 -0
  1184. package/src/client/setup-connections/ProviderReadinessBadge.tsx +73 -0
  1185. package/src/client/setup-connections/SetupConnectionsPage.tsx +94 -0
  1186. package/src/client/setup-connections/catalog.ts +6 -0
  1187. package/src/client/setup-connections/index.ts +47 -0
  1188. package/src/client/setup-connections/runtime.ts +1 -0
  1189. package/src/client/sharing/ShareButton.tsx +1748 -0
  1190. package/src/client/sharing/ShareDialog.tsx +846 -0
  1191. package/src/client/sharing/VisibilityBadge.tsx +4 -0
  1192. package/src/client/sharing/index.ts +2 -0
  1193. package/src/client/sse-event-processor.ts +2002 -0
  1194. package/src/client/terminal/AgentTerminal.tsx +488 -0
  1195. package/src/client/terminal/index.ts +7 -0
  1196. package/src/client/theme.ts +27 -0
  1197. package/src/client/tombstone/agent-presence-chip.ts +17 -0
  1198. package/src/client/tombstone/editor.ts +265 -0
  1199. package/src/client/tombstone/live-cursor-overlay.ts +21 -0
  1200. package/src/client/tombstone/presence-bar.ts +17 -0
  1201. package/src/client/tombstone/recent-edit-highlights.ts +17 -0
  1202. package/src/client/tombstone/remote-selection-rings.ts +21 -0
  1203. package/src/client/tombstone/rich-markdown-editor.ts +265 -0
  1204. package/src/client/tombstone/ui-dialog.ts +49 -0
  1205. package/src/client/tombstone/ui-dropdown-menu.ts +69 -0
  1206. package/src/client/tombstone/ui-hover-card.ts +21 -0
  1207. package/src/client/tombstone/ui-popover.ts +25 -0
  1208. package/src/client/tombstone/ui-sheet.ts +49 -0
  1209. package/src/client/tombstone/ui-tooltip.ts +29 -0
  1210. package/src/client/tombstone/visual-style-controls.ts +61 -0
  1211. package/src/client/tool-cells/BashCell.tsx +164 -0
  1212. package/src/client/tool-cells/EditCell.tsx +303 -0
  1213. package/src/client/tool-cells/FilesChangedSummary.tsx +208 -0
  1214. package/src/client/tool-cells/WriteCell.tsx +145 -0
  1215. package/src/client/tool-cells/index.ts +7 -0
  1216. package/src/client/tool-display.ts +41 -0
  1217. package/src/client/track.ts +57 -0
  1218. package/src/client/transcription/BuilderTranscriptionCta.tsx +120 -0
  1219. package/src/client/transcription/use-live-transcription.ts +292 -0
  1220. package/src/client/ui/index.ts +55 -0
  1221. package/src/client/uploads/index.ts +6 -0
  1222. package/src/client/uploads/upload-editor-image.ts +79 -0
  1223. package/src/client/uploads/use-upload-resource.ts +24 -0
  1224. package/src/client/url-scrub.ts +51 -0
  1225. package/src/client/use-action.ts +766 -0
  1226. package/src/client/use-agent-chat-context.ts +63 -0
  1227. package/src/client/use-agent-chat-home-handoff.ts +207 -0
  1228. package/src/client/use-agent-chat.ts +53 -0
  1229. package/src/client/use-agent-engine-configured.ts +211 -0
  1230. package/src/client/use-avatar.ts +127 -0
  1231. package/src/client/use-change-version.ts +150 -0
  1232. package/src/client/use-chat-models.ts +252 -0
  1233. package/src/client/use-chat-threads.ts +1262 -0
  1234. package/src/client/use-db-sync.ts +1112 -0
  1235. package/src/client/use-demo-mode-status.ts +30 -0
  1236. package/src/client/use-dev-mode.ts +177 -0
  1237. package/src/client/use-external-value.ts +40 -0
  1238. package/src/client/use-pausing-interval.ts +65 -0
  1239. package/src/client/use-pinch-zoom.ts +202 -0
  1240. package/src/client/use-run-stuck-detection.ts +427 -0
  1241. package/src/client/use-send-to-agent-chat.ts +85 -0
  1242. package/src/client/use-session.ts +114 -0
  1243. package/src/client/utils.ts +7 -0
  1244. package/src/client/visual-style-controls.tsx +1 -0
  1245. package/src/client/vite-dev-recovery-script.ts +226 -0
  1246. package/src/client/voice-provider-status.ts +44 -0
  1247. package/src/client/widgets/index.ts +41 -0
  1248. package/src/code-agents/background-controller.ts +398 -0
  1249. package/src/code-agents/background-run.ts +156 -0
  1250. package/src/code-agents/index.ts +95 -0
  1251. package/src/code-agents/prompt-attachments.ts +39 -0
  1252. package/src/code-agents/transcript-normalizer.ts +750 -0
  1253. package/src/code-agents/transcript-order.ts +73 -0
  1254. package/src/coding-tools/index.ts +742 -0
  1255. package/src/coding-tools/run-code.ts +1662 -0
  1256. package/src/coding-tools/sandbox/adapter.ts +82 -0
  1257. package/src/coding-tools/sandbox/background.ts +406 -0
  1258. package/src/coding-tools/sandbox/executions-store.ts +517 -0
  1259. package/src/coding-tools/sandbox/index.ts +132 -0
  1260. package/src/coding-tools/sandbox/local-child-process-adapter.ts +217 -0
  1261. package/src/collab/agent-identity.ts +5 -0
  1262. package/src/collab/agent-presence.ts +341 -0
  1263. package/src/collab/awareness-store.ts +196 -0
  1264. package/src/collab/awareness.ts +317 -0
  1265. package/src/collab/client-struct.ts +366 -0
  1266. package/src/collab/client.ts +1205 -0
  1267. package/src/collab/emitter.ts +31 -0
  1268. package/src/collab/follow-mode.ts +107 -0
  1269. package/src/collab/index.ts +151 -0
  1270. package/src/collab/json-to-yjs.ts +504 -0
  1271. package/src/collab/presence.ts +207 -0
  1272. package/src/collab/recent-edits.ts +215 -0
  1273. package/src/collab/routes.ts +191 -0
  1274. package/src/collab/storage.ts +228 -0
  1275. package/src/collab/struct-routes.ts +133 -0
  1276. package/src/collab/text-to-yjs.ts +79 -0
  1277. package/src/collab/undo.ts +432 -0
  1278. package/src/collab/xml-ops.ts +68 -0
  1279. package/src/collab/ydoc-manager.ts +544 -0
  1280. package/src/command-navigation/actions.ts +100 -0
  1281. package/src/command-navigation/index.ts +12 -0
  1282. package/src/comments-review/index.ts +1 -0
  1283. package/src/connections/catalog.ts +451 -0
  1284. package/src/connections/index.ts +48 -0
  1285. package/src/connections/reader.ts +911 -0
  1286. package/src/connections/runtime.ts +1 -0
  1287. package/src/credentials/index.ts +187 -0
  1288. package/src/data-programs/actions.ts +335 -0
  1289. package/src/data-programs/contract.ts +284 -0
  1290. package/src/data-programs/execute.ts +693 -0
  1291. package/src/data-programs/index.ts +72 -0
  1292. package/src/data-programs/schema.ts +148 -0
  1293. package/src/data-programs/store.ts +755 -0
  1294. package/src/data-widgets/index.ts +376 -0
  1295. package/src/db/client.ts +1627 -0
  1296. package/src/db/create-get-db.ts +579 -0
  1297. package/src/db/ddl-guard.ts +302 -0
  1298. package/src/db/drizzle-config.ts +190 -0
  1299. package/src/db/ensure-additive-columns.ts +430 -0
  1300. package/src/db/index.ts +57 -0
  1301. package/src/db/migrations.ts +691 -0
  1302. package/src/db/request-telemetry.ts +154 -0
  1303. package/src/db/runtime-diagnostics.ts +331 -0
  1304. package/src/db/schema.ts +121 -0
  1305. package/src/db/widen-columns.ts +75 -0
  1306. package/src/db-admin/agent-tools.ts +202 -0
  1307. package/src/db-admin/index.ts +26 -0
  1308. package/src/db-admin/operations.ts +803 -0
  1309. package/src/db-admin/routes.ts +174 -0
  1310. package/src/db-admin/types.ts +110 -0
  1311. package/src/demo/browser-state.ts +47 -0
  1312. package/src/demo/fetch-interceptor.ts +175 -0
  1313. package/src/demo/redact.ts +575 -0
  1314. package/src/deploy/build.ts +3935 -0
  1315. package/src/deploy/immutable-assets.ts +65 -0
  1316. package/src/deploy/route-discovery.ts +458 -0
  1317. package/src/deploy/workspace-core.ts +282 -0
  1318. package/src/deploy/workspace-deploy.ts +1488 -0
  1319. package/src/eject/provider-api-definitions.ts +193 -0
  1320. package/src/eject/remote-mcp-presets.ts +137 -0
  1321. package/src/eject/setup-readiness-ui.tsx +29 -0
  1322. package/src/eject/workspace-connections.ts +92 -0
  1323. package/src/embedding/agent.ts +159 -0
  1324. package/src/embedding/bridge.ts +297 -0
  1325. package/src/embedding/index.ts +43 -0
  1326. package/src/embedding/protocol.ts +185 -0
  1327. package/src/embedding/react.tsx +319 -0
  1328. package/src/embeddings/index.ts +233 -0
  1329. package/src/eval/agent-runner.ts +210 -0
  1330. package/src/eval/define-eval.ts +55 -0
  1331. package/src/eval/index.ts +49 -0
  1332. package/src/eval/report.ts +75 -0
  1333. package/src/eval/runner.ts +369 -0
  1334. package/src/eval/scorer.ts +244 -0
  1335. package/src/eval/types.ts +188 -0
  1336. package/src/event-bus/bus.ts +140 -0
  1337. package/src/event-bus/index.ts +3 -0
  1338. package/src/event-bus/registry.ts +79 -0
  1339. package/src/event-bus/types.ts +29 -0
  1340. package/src/extensions/actions.ts +1636 -0
  1341. package/src/extensions/change-marker.ts +54 -0
  1342. package/src/extensions/content-patch.ts +468 -0
  1343. package/src/extensions/fetch-tool.ts +461 -0
  1344. package/src/extensions/html-shell.ts +803 -0
  1345. package/src/extensions/local.ts +462 -0
  1346. package/src/extensions/path.ts +40 -0
  1347. package/src/extensions/proxy-security.ts +171 -0
  1348. package/src/extensions/routes.ts +1080 -0
  1349. package/src/extensions/schema.ts +269 -0
  1350. package/src/extensions/session-replay-iframe.ts +131 -0
  1351. package/src/extensions/slots/routes.ts +126 -0
  1352. package/src/extensions/slots/schema.ts +87 -0
  1353. package/src/extensions/slots/store.ts +450 -0
  1354. package/src/extensions/store.ts +1347 -0
  1355. package/src/extensions/theme.ts +114 -0
  1356. package/src/extensions/url-safety.ts +316 -0
  1357. package/src/extensions/web-content.ts +663 -0
  1358. package/src/extensions/web-search-tool.ts +437 -0
  1359. package/src/feature-flags/a2a-action-route.ts +56 -0
  1360. package/src/feature-flags/actions/get-feature-flags.ts +24 -0
  1361. package/src/feature-flags/actions/list-feature-flags.ts +69 -0
  1362. package/src/feature-flags/actions/set-feature-flag.ts +89 -0
  1363. package/src/feature-flags/index.ts +21 -0
  1364. package/src/feature-flags/permissions.ts +53 -0
  1365. package/src/feature-flags/plugin.ts +44 -0
  1366. package/src/feature-flags/registry.ts +96 -0
  1367. package/src/feature-flags/store.ts +176 -0
  1368. package/src/file-upload/actions/upload-image.ts +213 -0
  1369. package/src/file-upload/builder.ts +431 -0
  1370. package/src/file-upload/index.ts +24 -0
  1371. package/src/file-upload/pre-upload-attachments.ts +305 -0
  1372. package/src/file-upload/registry.ts +125 -0
  1373. package/src/file-upload/types.ts +89 -0
  1374. package/src/guards/db-tool-scoping.ts +129 -0
  1375. package/src/guards/index.ts +23 -0
  1376. package/src/guards/no-drizzle-push.ts +116 -0
  1377. package/src/guards/no-env-credentials.ts +229 -0
  1378. package/src/guards/no-env-mutation.ts +114 -0
  1379. package/src/guards/no-localhost-fallback.ts +124 -0
  1380. package/src/guards/no-unscoped-credentials.ts +227 -0
  1381. package/src/guards/no-unscoped-queries.ts +834 -0
  1382. package/src/guards/scan-utils.ts +105 -0
  1383. package/src/guards/types.ts +30 -0
  1384. package/src/history/actions/create-resource-version.ts +92 -0
  1385. package/src/history/actions/get-resource-version.ts +60 -0
  1386. package/src/history/actions/list-resource-history.ts +53 -0
  1387. package/src/history/actions/list-resource-versions.ts +43 -0
  1388. package/src/history/actions/restore-resource-version.ts +96 -0
  1389. package/src/history/index.ts +26 -0
  1390. package/src/history/registry.ts +111 -0
  1391. package/src/history/store.ts +379 -0
  1392. package/src/history/types.ts +69 -0
  1393. package/src/index.browser.ts +155 -0
  1394. package/src/index.ts +408 -0
  1395. package/src/ingestion/docx.ts +158 -0
  1396. package/src/ingestion/figma-node-to-html.ts +1860 -0
  1397. package/src/ingestion/figma.ts +548 -0
  1398. package/src/ingestion/index.ts +107 -0
  1399. package/src/ingestion/media.ts +264 -0
  1400. package/src/ingestion/notion.ts +121 -0
  1401. package/src/ingestion/office.ts +213 -0
  1402. package/src/ingestion/orchestration.ts +160 -0
  1403. package/src/ingestion/pptx.ts +331 -0
  1404. package/src/ingestion/selection.ts +81 -0
  1405. package/src/ingestion/website.ts +151 -0
  1406. package/src/integrations/a2a-continuation-marker.ts +2 -0
  1407. package/src/integrations/a2a-continuation-processor.ts +888 -0
  1408. package/src/integrations/a2a-continuations-store.ts +643 -0
  1409. package/src/integrations/adapter-overrides.ts +12 -0
  1410. package/src/integrations/adapters/discord.ts +364 -0
  1411. package/src/integrations/adapters/email.ts +1164 -0
  1412. package/src/integrations/adapters/google-docs.ts +371 -0
  1413. package/src/integrations/adapters/index.ts +29 -0
  1414. package/src/integrations/adapters/microsoft-teams.ts +413 -0
  1415. package/src/integrations/adapters/slack.ts +1914 -0
  1416. package/src/integrations/adapters/telegram.ts +386 -0
  1417. package/src/integrations/adapters/whatsapp.ts +358 -0
  1418. package/src/integrations/awaiting-input-store.ts +130 -0
  1419. package/src/integrations/catalog.ts +571 -0
  1420. package/src/integrations/computer-supervision-store.ts +423 -0
  1421. package/src/integrations/computer-supervision.ts +213 -0
  1422. package/src/integrations/config-store.ts +131 -0
  1423. package/src/integrations/controls-store.ts +187 -0
  1424. package/src/integrations/eject/messaging-adapters.ts +85 -0
  1425. package/src/integrations/google-docs-poller.ts +671 -0
  1426. package/src/integrations/identity-links-store.ts +210 -0
  1427. package/src/integrations/identity.ts +196 -0
  1428. package/src/integrations/index.ts +220 -0
  1429. package/src/integrations/installations-store.ts +677 -0
  1430. package/src/integrations/integration-memory.ts +187 -0
  1431. package/src/integrations/internal-token.ts +106 -0
  1432. package/src/integrations/pending-tasks-retry-job.ts +286 -0
  1433. package/src/integrations/pending-tasks-store.ts +468 -0
  1434. package/src/integrations/plugin.ts +3048 -0
  1435. package/src/integrations/remote-commands-store.ts +690 -0
  1436. package/src/integrations/remote-devices-store.ts +492 -0
  1437. package/src/integrations/remote-json-safety.ts +127 -0
  1438. package/src/integrations/remote-push-delivery-job.ts +48 -0
  1439. package/src/integrations/remote-push-delivery.ts +370 -0
  1440. package/src/integrations/remote-push-store.ts +664 -0
  1441. package/src/integrations/remote-retry-job.ts +55 -0
  1442. package/src/integrations/remote-run-events-store.ts +222 -0
  1443. package/src/integrations/remote-types.ts +186 -0
  1444. package/src/integrations/runtime.ts +1 -0
  1445. package/src/integrations/scope-store.ts +498 -0
  1446. package/src/integrations/slack-manifest.ts +78 -0
  1447. package/src/integrations/slack-oauth.ts +344 -0
  1448. package/src/integrations/task-queue-stats.ts +144 -0
  1449. package/src/integrations/thread-mapping-store.ts +134 -0
  1450. package/src/integrations/types.ts +485 -0
  1451. package/src/integrations/usage-budget-store.ts +906 -0
  1452. package/src/integrations/webhook-delivery.ts +55 -0
  1453. package/src/integrations/webhook-handler.ts +1939 -0
  1454. package/src/jobs/actions/list-recurring-jobs.ts +105 -0
  1455. package/src/jobs/actions/manage-recurring-job.ts +85 -0
  1456. package/src/jobs/cron.ts +126 -0
  1457. package/src/jobs/index.ts +9 -0
  1458. package/src/jobs/scheduler.ts +703 -0
  1459. package/src/jobs/tools.ts +367 -0
  1460. package/src/local-artifacts/index.ts +1372 -0
  1461. package/src/localization/actions/get-localization-preference.ts +24 -0
  1462. package/src/localization/actions/set-localization-preference.ts +32 -0
  1463. package/src/localization/default-messages.ts +1009 -0
  1464. package/src/localization/index.ts +2 -0
  1465. package/src/localization/server.ts +131 -0
  1466. package/src/localization/shared.ts +208 -0
  1467. package/src/mcp/actions/call-mcp-tool.ts +19 -0
  1468. package/src/mcp/actions/create-org-service-token.ts +87 -0
  1469. package/src/mcp/actions/list-mcp-tools.ts +18 -0
  1470. package/src/mcp/actions/list-org-service-tokens.ts +44 -0
  1471. package/src/mcp/actions/revoke-org-service-token.ts +30 -0
  1472. package/src/mcp/actions/service-token-access.ts +121 -0
  1473. package/src/mcp/ask-app-inline-tasks.ts +125 -0
  1474. package/src/mcp/build-server.ts +2356 -0
  1475. package/src/mcp/builtin-tools.ts +1506 -0
  1476. package/src/mcp/connect-route.ts +1460 -0
  1477. package/src/mcp/connect-store.ts +680 -0
  1478. package/src/mcp/embed-app.ts +2051 -0
  1479. package/src/mcp/embed-route.ts +84 -0
  1480. package/src/mcp/external-agent-policy.ts +18 -0
  1481. package/src/mcp/index.ts +47 -0
  1482. package/src/mcp/oauth-route.ts +1016 -0
  1483. package/src/mcp/oauth-store.ts +581 -0
  1484. package/src/mcp/oauth-token.ts +227 -0
  1485. package/src/mcp/org-directory.ts +343 -0
  1486. package/src/mcp/route-paths.ts +34 -0
  1487. package/src/mcp/screen-memory-stdio.ts +290 -0
  1488. package/src/mcp/server.ts +507 -0
  1489. package/src/mcp/stdio.ts +328 -0
  1490. package/src/mcp/workspace-resolve.ts +261 -0
  1491. package/src/mcp-client/app-api.ts +136 -0
  1492. package/src/mcp-client/app-result.ts +64 -0
  1493. package/src/mcp-client/builtin-capabilities.ts +146 -0
  1494. package/src/mcp-client/builtin-store.ts +93 -0
  1495. package/src/mcp-client/config.ts +281 -0
  1496. package/src/mcp-client/errors.ts +54 -0
  1497. package/src/mcp-client/hub-client.ts +172 -0
  1498. package/src/mcp-client/hub-routes.ts +198 -0
  1499. package/src/mcp-client/index.ts +504 -0
  1500. package/src/mcp-client/manager.ts +968 -0
  1501. package/src/mcp-client/oauth-client.ts +462 -0
  1502. package/src/mcp-client/oauth-routes.ts +307 -0
  1503. package/src/mcp-client/remote-store.ts +674 -0
  1504. package/src/mcp-client/remote-url.ts +97 -0
  1505. package/src/mcp-client/routes.ts +1093 -0
  1506. package/src/mcp-client/screen-memory-local.ts +461 -0
  1507. package/src/mcp-client/tool-policy.ts +182 -0
  1508. package/src/mcp-client/visibility.ts +56 -0
  1509. package/src/mcp-client/workspace-servers.ts +379 -0
  1510. package/src/navigation/index.ts +170 -0
  1511. package/src/notifications/actions.ts +151 -0
  1512. package/src/notifications/channels.ts +410 -0
  1513. package/src/notifications/index.ts +22 -0
  1514. package/src/notifications/registry.ts +216 -0
  1515. package/src/notifications/routes.ts +106 -0
  1516. package/src/notifications/store.ts +236 -0
  1517. package/src/notifications/types.ts +52 -0
  1518. package/src/oauth-tokens/google-refresh.ts +175 -0
  1519. package/src/oauth-tokens/index.ts +15 -0
  1520. package/src/oauth-tokens/store.ts +384 -0
  1521. package/src/observability/cleanup-job.ts +124 -0
  1522. package/src/observability/evals.ts +507 -0
  1523. package/src/observability/experiments.ts +359 -0
  1524. package/src/observability/feedback.ts +332 -0
  1525. package/src/observability/hosted-model-experiment.ts +118 -0
  1526. package/src/observability/index.ts +62 -0
  1527. package/src/observability/plugin.ts +31 -0
  1528. package/src/observability/routes.ts +431 -0
  1529. package/src/observability/sentiment.ts +261 -0
  1530. package/src/observability/store.ts +1347 -0
  1531. package/src/observability/traces.ts +789 -0
  1532. package/src/observability/tracing.ts +157 -0
  1533. package/src/observability/tracking-identity.ts +55 -0
  1534. package/src/observability/types.ts +211 -0
  1535. package/src/onboarding/default-steps.ts +428 -0
  1536. package/src/onboarding/index.ts +22 -0
  1537. package/src/onboarding/plugin.ts +262 -0
  1538. package/src/onboarding/registry.ts +47 -0
  1539. package/src/onboarding/types.ts +96 -0
  1540. package/src/org/accept-pending.ts +98 -0
  1541. package/src/org/auto-join-domain.ts +113 -0
  1542. package/src/org/context.ts +614 -0
  1543. package/src/org/free-email-providers.ts +124 -0
  1544. package/src/org/handlers.ts +1153 -0
  1545. package/src/org/index.ts +63 -0
  1546. package/src/org/migrations.ts +105 -0
  1547. package/src/org/permissions.ts +30 -0
  1548. package/src/org/plugin.ts +255 -0
  1549. package/src/org/schema.ts +28 -0
  1550. package/src/org/types.ts +57 -0
  1551. package/src/org-team/index.ts +1 -0
  1552. package/src/package-lifecycle/deprecated-imports.ts +179 -0
  1553. package/src/package-lifecycle/eject-manifest.ts +345 -0
  1554. package/src/package-lifecycle/index.ts +7 -0
  1555. package/src/package-lifecycle/manifest.ts +120 -0
  1556. package/src/package-lifecycle/migration-manifest.ts +159 -0
  1557. package/src/package-lifecycle/migration-message.ts +6 -0
  1558. package/src/package-lifecycle/tombstone.ts +58 -0
  1559. package/src/package-lifecycle/upgrade-error.ts +37 -0
  1560. package/src/private-blob/index.ts +18 -0
  1561. package/src/private-blob/registry.ts +242 -0
  1562. package/src/private-blob/types.ts +55 -0
  1563. package/src/progress/actions.ts +179 -0
  1564. package/src/progress/index.ts +16 -0
  1565. package/src/progress/registry.ts +127 -0
  1566. package/src/progress/routes.ts +89 -0
  1567. package/src/progress/store.ts +353 -0
  1568. package/src/progress/types.ts +59 -0
  1569. package/src/provider-api/actions/custom-provider-registration.ts +197 -0
  1570. package/src/provider-api/actions/delete-staged-dataset.ts +5 -0
  1571. package/src/provider-api/actions/github-repo-files.ts +266 -0
  1572. package/src/provider-api/actions/list-staged-datasets.ts +5 -0
  1573. package/src/provider-api/actions/provider-api-audit.ts +88 -0
  1574. package/src/provider-api/actions/provider-api.ts +460 -0
  1575. package/src/provider-api/actions/query-staged-dataset.ts +5 -0
  1576. package/src/provider-api/actions/staged-datasets.ts +359 -0
  1577. package/src/provider-api/corpus-jobs-store.ts +522 -0
  1578. package/src/provider-api/corpus-jobs.ts +1817 -0
  1579. package/src/provider-api/custom-registry.ts +456 -0
  1580. package/src/provider-api/github-repo.ts +675 -0
  1581. package/src/provider-api/gong.ts +108 -0
  1582. package/src/provider-api/index.ts +5444 -0
  1583. package/src/provider-api/quota-governor.ts +562 -0
  1584. package/src/provider-api/runtime.ts +1 -0
  1585. package/src/provider-api/staged-datasets-aggregate.ts +304 -0
  1586. package/src/provider-api/staged-datasets-store.ts +441 -0
  1587. package/src/provider-api/staging.ts +483 -0
  1588. package/src/resources/agents.ts +65 -0
  1589. package/src/resources/emitter.ts +54 -0
  1590. package/src/resources/handlers.ts +728 -0
  1591. package/src/resources/index.ts +4 -0
  1592. package/src/resources/metadata.ts +252 -0
  1593. package/src/resources/script-helpers.ts +160 -0
  1594. package/src/resources/store.ts +1618 -0
  1595. package/src/review/actions/consume-review-feedback.ts +48 -0
  1596. package/src/review/actions/create-review-comment.ts +108 -0
  1597. package/src/review/actions/delete-review-comment.ts +67 -0
  1598. package/src/review/actions/get-review-feedback.ts +49 -0
  1599. package/src/review/actions/list-review-comments.ts +87 -0
  1600. package/src/review/actions/reply-review-comment.ts +118 -0
  1601. package/src/review/actions/resolve-review-thread.ts +94 -0
  1602. package/src/review/actions/send-review-thread-to-agent.ts +62 -0
  1603. package/src/review/actions/set-review-status.ts +58 -0
  1604. package/src/review/identity.ts +101 -0
  1605. package/src/review/index.ts +45 -0
  1606. package/src/review/mentions.ts +44 -0
  1607. package/src/review/registry.ts +111 -0
  1608. package/src/review/store.ts +997 -0
  1609. package/src/review/types.ts +101 -0
  1610. package/src/router/index.ts +24 -0
  1611. package/src/scripts/agent-engines/list-agent-engines.ts +130 -0
  1612. package/src/scripts/agent-engines/manage-agent-engine.ts +197 -0
  1613. package/src/scripts/agent-engines/set-agent-engine.ts +84 -0
  1614. package/src/scripts/agent-engines/test-agent-engine.ts +174 -0
  1615. package/src/scripts/call-agent.ts +792 -0
  1616. package/src/scripts/chat/index.ts +8 -0
  1617. package/src/scripts/chat/open-chat.ts +56 -0
  1618. package/src/scripts/chat/search-chats.ts +121 -0
  1619. package/src/scripts/core-scripts.ts +22 -0
  1620. package/src/scripts/db/check-scoping.ts +212 -0
  1621. package/src/scripts/db/exec.ts +791 -0
  1622. package/src/scripts/db/index.ts +19 -0
  1623. package/src/scripts/db/migrate-encrypt-credentials.ts +223 -0
  1624. package/src/scripts/db/migrate-encrypt-oauth-tokens.ts +213 -0
  1625. package/src/scripts/db/migrate-user-api-keys.ts +257 -0
  1626. package/src/scripts/db/patch.ts +820 -0
  1627. package/src/scripts/db/query.ts +299 -0
  1628. package/src/scripts/db/reset-dev-owner.ts +285 -0
  1629. package/src/scripts/db/safety.ts +286 -0
  1630. package/src/scripts/db/schema.ts +364 -0
  1631. package/src/scripts/db/scoping.ts +341 -0
  1632. package/src/scripts/db/sqlite-client.ts +78 -0
  1633. package/src/scripts/db/tool-mode.ts +23 -0
  1634. package/src/scripts/db/tool-schemas.ts +31 -0
  1635. package/src/scripts/db/wipe-leaked-builder-keys.ts +201 -0
  1636. package/src/scripts/dev/index.ts +296 -0
  1637. package/src/scripts/dev/list-files.ts +119 -0
  1638. package/src/scripts/dev/read-file.ts +77 -0
  1639. package/src/scripts/dev/search-files.ts +151 -0
  1640. package/src/scripts/dev/shell.ts +111 -0
  1641. package/src/scripts/dev/write-file.ts +56 -0
  1642. package/src/scripts/dev-session.ts +96 -0
  1643. package/src/scripts/docs/index.ts +8 -0
  1644. package/src/scripts/docs/search.ts +274 -0
  1645. package/src/scripts/docs/source-search.ts +363 -0
  1646. package/src/scripts/index.ts +15 -0
  1647. package/src/scripts/manage-agent-loop-settings.ts +84 -0
  1648. package/src/scripts/parse-args.ts +46 -0
  1649. package/src/scripts/resources/delete-memory.ts +67 -0
  1650. package/src/scripts/resources/delete.ts +69 -0
  1651. package/src/scripts/resources/effective.ts +71 -0
  1652. package/src/scripts/resources/index.ts +18 -0
  1653. package/src/scripts/resources/list.ts +103 -0
  1654. package/src/scripts/resources/migrate-learnings.ts +40 -0
  1655. package/src/scripts/resources/read.ts +107 -0
  1656. package/src/scripts/resources/save-memory.ts +99 -0
  1657. package/src/scripts/resources/write.ts +158 -0
  1658. package/src/scripts/runner.ts +339 -0
  1659. package/src/scripts/utils.ts +130 -0
  1660. package/src/search/index.ts +413 -0
  1661. package/src/search-utils/index.ts +112 -0
  1662. package/src/secrets/crypto.ts +228 -0
  1663. package/src/secrets/index.ts +65 -0
  1664. package/src/secrets/onboarding.ts +101 -0
  1665. package/src/secrets/register-framework-secrets.ts +228 -0
  1666. package/src/secrets/register.ts +129 -0
  1667. package/src/secrets/routes.ts +697 -0
  1668. package/src/secrets/schema.ts +52 -0
  1669. package/src/secrets/storage.ts +561 -0
  1670. package/src/secrets/substitution.ts +305 -0
  1671. package/src/server/__snapshots__/agent-chat-plugin.surface.spec.ts.snap +150 -0
  1672. package/src/server/action-change.ts +66 -0
  1673. package/src/server/action-discovery.ts +774 -0
  1674. package/src/server/action-routes.ts +608 -0
  1675. package/src/server/agent-access.ts +72 -0
  1676. package/src/server/agent-chat/action-filters-a2a.ts +339 -0
  1677. package/src/server/agent-chat/browser-team-tools.ts +510 -0
  1678. package/src/server/agent-chat/context-tools.ts +599 -0
  1679. package/src/server/agent-chat/framework-prompts.ts +467 -0
  1680. package/src/server/agent-chat/lazy-fs.ts +11 -0
  1681. package/src/server/agent-chat/mcp-glue.ts +91 -0
  1682. package/src/server/agent-chat/plugin-options.ts +379 -0
  1683. package/src/server/agent-chat/process-run-failure.ts +62 -0
  1684. package/src/server/agent-chat/prompt-resources.ts +1004 -0
  1685. package/src/server/agent-chat/recurring-jobs-runtime.ts +80 -0
  1686. package/src/server/agent-chat/request-surface.ts +71 -0
  1687. package/src/server/agent-chat/run-code-tools.ts +67 -0
  1688. package/src/server/agent-chat/script-entries.ts +796 -0
  1689. package/src/server/agent-chat/shared-thread.ts +301 -0
  1690. package/src/server/agent-chat/skill-frontmatter.ts +41 -0
  1691. package/src/server/agent-chat-plugin.ts +5930 -0
  1692. package/src/server/agent-discovery.ts +706 -0
  1693. package/src/server/agent-engine-api-key-route.ts +236 -0
  1694. package/src/server/agent-run-context.ts +204 -0
  1695. package/src/server/agent-teams-run-queue.ts +344 -0
  1696. package/src/server/agent-teams.ts +2257 -0
  1697. package/src/server/agents-bundle.ts +464 -0
  1698. package/src/server/analytics.ts +105 -0
  1699. package/src/server/app-base-path.ts +79 -0
  1700. package/src/server/app-name.ts +53 -0
  1701. package/src/server/app-url.ts +184 -0
  1702. package/src/server/attachment-actions.ts +276 -0
  1703. package/src/server/attribution.ts +214 -0
  1704. package/src/server/auth-marketing.ts +260 -0
  1705. package/src/server/auth-plugin.ts +27 -0
  1706. package/src/server/auth.ts +3803 -0
  1707. package/src/server/better-auth-instance.ts +1197 -0
  1708. package/src/server/builder-browser.ts +1701 -0
  1709. package/src/server/builder-design-systems.ts +668 -0
  1710. package/src/server/builder-space.ts +176 -0
  1711. package/src/server/captcha.ts +63 -0
  1712. package/src/server/capture-error.ts +64 -0
  1713. package/src/server/cli-capture.ts +141 -0
  1714. package/src/server/collab-plugin.ts +391 -0
  1715. package/src/server/complete-text.ts +231 -0
  1716. package/src/server/cookie-namespace.ts +159 -0
  1717. package/src/server/core-routes-plugin.ts +4122 -0
  1718. package/src/server/cors-origins.ts +60 -0
  1719. package/src/server/create-server.ts +268 -0
  1720. package/src/server/credential-provider.ts +1202 -0
  1721. package/src/server/csrf.ts +229 -0
  1722. package/src/server/date-utils.ts +42 -0
  1723. package/src/server/deep-link.ts +119 -0
  1724. package/src/server/derived-secret.ts +32 -0
  1725. package/src/server/design-token-utils.ts +1032 -0
  1726. package/src/server/desktop-sso.ts +83 -0
  1727. package/src/server/edge.ts +69 -0
  1728. package/src/server/email-actions.ts +218 -0
  1729. package/src/server/email-template.ts +192 -0
  1730. package/src/server/email-templates.ts +148 -0
  1731. package/src/server/email.ts +219 -0
  1732. package/src/server/embed-route.ts +283 -0
  1733. package/src/server/embed-session.ts +805 -0
  1734. package/src/server/embedded.ts +252 -0
  1735. package/src/server/entry-server.tsx +154 -0
  1736. package/src/server/framework-request-handler.ts +848 -0
  1737. package/src/server/fusion-app.ts +447 -0
  1738. package/src/server/google-auth-mode.ts +34 -0
  1739. package/src/server/google-auth-plugin.ts +496 -0
  1740. package/src/server/google-oauth-credentials.ts +128 -0
  1741. package/src/server/google-oauth.ts +972 -0
  1742. package/src/server/google-realtime-session.ts +182 -0
  1743. package/src/server/h3-helpers.ts +174 -0
  1744. package/src/server/http-response-telemetry.ts +396 -0
  1745. package/src/server/identity-sso-store.ts +304 -0
  1746. package/src/server/identity-sso.ts +514 -0
  1747. package/src/server/index.ts +593 -0
  1748. package/src/server/missing-key.ts +36 -0
  1749. package/src/server/oauth-helpers.ts +44 -0
  1750. package/src/server/oauth-public-origin.ts +44 -0
  1751. package/src/server/oauth-return-url.ts +120 -0
  1752. package/src/server/og-fonts-data.ts +15 -0
  1753. package/src/server/og-fonts.ts +75 -0
  1754. package/src/server/onboarding-html.ts +4040 -0
  1755. package/src/server/open-route.ts +311 -0
  1756. package/src/server/org-admin.ts +28 -0
  1757. package/src/server/poll-events.ts +88 -0
  1758. package/src/server/poll.ts +1224 -0
  1759. package/src/server/prompts/framework-core-compact.ts +107 -0
  1760. package/src/server/prompts/framework-core.ts +143 -0
  1761. package/src/server/prompts/index.ts +16 -0
  1762. package/src/server/prompts/model-overlays.ts +54 -0
  1763. package/src/server/prompts/shared-rules.ts +104 -0
  1764. package/src/server/realtime-voice.ts +967 -0
  1765. package/src/server/recap-image-route.ts +242 -0
  1766. package/src/server/recap-image-store.ts +185 -0
  1767. package/src/server/request-context.ts +416 -0
  1768. package/src/server/request-origin.ts +67 -0
  1769. package/src/server/resources-plugin.ts +119 -0
  1770. package/src/server/schema-prompt.ts +429 -0
  1771. package/src/server/scoped-key-storage.ts +223 -0
  1772. package/src/server/security-headers.ts +170 -0
  1773. package/src/server/self-dispatch.ts +224 -0
  1774. package/src/server/sentry-config.ts +73 -0
  1775. package/src/server/sentry-plugin.ts +138 -0
  1776. package/src/server/sentry.ts +444 -0
  1777. package/src/server/short-lived-token.ts +170 -0
  1778. package/src/server/social-og-image.ts +454 -0
  1779. package/src/server/sse.ts +102 -0
  1780. package/src/server/ssr-handler.ts +466 -0
  1781. package/src/server/transcribe-voice.ts +1076 -0
  1782. package/src/server/voice-providers-status.ts +118 -0
  1783. package/src/server/workspace-oauth.ts +31 -0
  1784. package/src/server/workspace-provider-oauth.ts +970 -0
  1785. package/src/session-replay-iframe-protocol.ts +58 -0
  1786. package/src/settings/handlers.ts +44 -0
  1787. package/src/settings/index.ts +34 -0
  1788. package/src/settings/org-settings.ts +83 -0
  1789. package/src/settings/script-helpers.ts +24 -0
  1790. package/src/settings/store.ts +247 -0
  1791. package/src/settings/user-settings.ts +47 -0
  1792. package/src/setup-connections/index.ts +90 -0
  1793. package/src/setup-connections/onboarding.ts +47 -0
  1794. package/src/shared/agent-access.ts +112 -0
  1795. package/src/shared/agent-chat.ts +124 -0
  1796. package/src/shared/agent-env.ts +46 -0
  1797. package/src/shared/agent-readable-resource.ts +111 -0
  1798. package/src/shared/agent-sidebar-url.ts +39 -0
  1799. package/src/shared/cache-control.ts +25 -0
  1800. package/src/shared/cloudflare-globals.d.ts +34 -0
  1801. package/src/shared/context-xray.ts +172 -0
  1802. package/src/shared/embed-auth.ts +6 -0
  1803. package/src/shared/index.ts +83 -0
  1804. package/src/shared/llm-connection.ts +42 -0
  1805. package/src/shared/markdown-block-split.ts +129 -0
  1806. package/src/shared/mcp-connect-content.ts +130 -0
  1807. package/src/shared/mcp-embed-headers.ts +175 -0
  1808. package/src/shared/mcp-integration-config.ts +101 -0
  1809. package/src/shared/merge-by-id.ts +14 -0
  1810. package/src/shared/oauth-state.ts +39 -0
  1811. package/src/shared/reasoning-effort.ts +228 -0
  1812. package/src/shared/route-warmup-config.ts +128 -0
  1813. package/src/shared/runtime.ts +31 -0
  1814. package/src/shared/social-meta.ts +82 -0
  1815. package/src/shared/streaming-text-smoothing.ts +184 -0
  1816. package/src/shared/truncate.ts +13 -0
  1817. package/src/shared/workspace-app-audience.ts +177 -0
  1818. package/src/shared/workspace-app-id.ts +54 -0
  1819. package/src/sharing/access.ts +585 -0
  1820. package/src/sharing/actions/create-agent-resource-link.ts +91 -0
  1821. package/src/sharing/actions/extension-change.ts +22 -0
  1822. package/src/sharing/actions/list-resource-shares.ts +93 -0
  1823. package/src/sharing/actions/set-resource-visibility.ts +91 -0
  1824. package/src/sharing/actions/share-resource.ts +322 -0
  1825. package/src/sharing/actions/unshare-resource.ts +72 -0
  1826. package/src/sharing/index.ts +35 -0
  1827. package/src/sharing/registry.ts +201 -0
  1828. package/src/sharing/schema.ts +99 -0
  1829. package/src/styles/agent-conversation.css +766 -0
  1830. package/src/styles/agent-native.css +938 -0
  1831. package/src/styles/blocks.css +1717 -0
  1832. package/src/styles/chat-history-list.css +1 -0
  1833. package/src/styles/rich-markdown-editor.css +1 -0
  1834. package/src/tailwind.preset.ts +140 -0
  1835. package/src/templates/chat/.agents/skills/actions/SKILL.md +32 -12
  1836. package/src/templates/chat/.agents/skills/agent-native-docs/SKILL.md +21 -9
  1837. package/src/templates/chat/.agents/skills/customizing-agent-native/SKILL.md +145 -0
  1838. package/src/templates/chat/.agents/skills/self-modifying-code/SKILL.md +14 -2
  1839. package/src/templates/chat/.agents/skills/upgrade-agent-native/SKILL.md +6 -0
  1840. package/src/templates/chat/AGENTS.md +6 -2
  1841. package/src/templates/chat/app/components/layout/Sidebar.tsx +51 -157
  1842. package/src/templates/default/.agents/skills/actions/SKILL.md +32 -12
  1843. package/src/templates/default/.agents/skills/agent-native-docs/SKILL.md +21 -9
  1844. package/src/templates/default/.agents/skills/customizing-agent-native/SKILL.md +145 -0
  1845. package/src/templates/default/.agents/skills/integration-webhooks/SKILL.md +323 -0
  1846. package/src/templates/default/.agents/skills/onboarding/SKILL.md +56 -0
  1847. package/src/templates/default/.agents/skills/secrets/SKILL.md +273 -0
  1848. package/src/templates/default/.agents/skills/self-modifying-code/SKILL.md +14 -2
  1849. package/src/templates/default/.agents/skills/upgrade-agent-native/SKILL.md +6 -0
  1850. package/src/templates/default/AGENTS.md +26 -18
  1851. package/src/templates/headless/.agents/skills/actions/SKILL.md +512 -0
  1852. package/src/templates/headless/.agents/skills/agent-native-docs/SKILL.md +21 -9
  1853. package/src/templates/headless/.agents/skills/customizing-agent-native/SKILL.md +145 -0
  1854. package/src/templates/headless/.agents/skills/integration-webhooks/SKILL.md +323 -0
  1855. package/src/templates/headless/.agents/skills/secrets/SKILL.md +273 -0
  1856. package/src/templates/headless/.agents/skills/upgrade-agent-native/SKILL.md +6 -0
  1857. package/src/templates/headless/AGENTS.md +8 -0
  1858. package/src/templates/workspace-core/.agents/skills/actions/SKILL.md +32 -12
  1859. package/src/templates/workspace-core/.agents/skills/agent-native-docs/SKILL.md +21 -9
  1860. package/src/templates/workspace-core/.agents/skills/agent-native-toolkit/SKILL.md +7 -0
  1861. package/src/templates/workspace-core/.agents/skills/customizing-agent-native/SKILL.md +145 -0
  1862. package/src/templates/workspace-core/.agents/skills/self-modifying-code/SKILL.md +14 -2
  1863. package/src/templates/workspace-core/.agents/skills/upgrade-agent-native/SKILL.md +6 -0
  1864. package/src/templates/workspace-core/AGENTS.md +4 -0
  1865. package/src/templates/workspace-root/AGENTS.md +4 -0
  1866. package/src/terminal/cli-registry.ts +57 -0
  1867. package/src/terminal/index.ts +22 -0
  1868. package/src/terminal/pty-server.ts +389 -0
  1869. package/src/terminal/terminal-plugin.ts +265 -0
  1870. package/src/testing.ts +23 -0
  1871. package/src/tracking/index.ts +10 -0
  1872. package/src/tracking/providers.ts +422 -0
  1873. package/src/tracking/registry.ts +102 -0
  1874. package/src/tracking/route.ts +108 -0
  1875. package/src/tracking/types.ts +16 -0
  1876. package/src/transcription/builder-transcription.ts +118 -0
  1877. package/src/triggers/actions/list-automations.ts +99 -0
  1878. package/src/triggers/actions/manage-automation.ts +78 -0
  1879. package/src/triggers/actions.ts +333 -0
  1880. package/src/triggers/condition-evaluator.ts +163 -0
  1881. package/src/triggers/dispatcher.ts +536 -0
  1882. package/src/triggers/index.ts +13 -0
  1883. package/src/triggers/routes.ts +322 -0
  1884. package/src/triggers/types.ts +42 -0
  1885. package/src/types/pglite.d.ts +26 -0
  1886. package/src/usage/store.ts +698 -0
  1887. package/src/vite/action-types-plugin.ts +481 -0
  1888. package/src/vite/agent-web-plugin.ts +78 -0
  1889. package/src/vite/agents-bundle-plugin.ts +185 -0
  1890. package/src/vite/client.ts +3039 -0
  1891. package/src/vite/index.ts +21 -0
  1892. package/src/voice/index.ts +18 -0
  1893. package/src/voice/voice-cleanup-prompt.ts +38 -0
  1894. package/src/voice/voice-context.ts +217 -0
  1895. package/src/voice/voice-replacements.ts +75 -0
  1896. package/src/workspace-connections/credentials.ts +603 -0
  1897. package/src/workspace-connections/index.ts +72 -0
  1898. package/src/workspace-connections/lifecycle.ts +43 -0
  1899. package/src/workspace-connections/store.ts +1943 -0
  1900. package/src/workspace-files/index.ts +18 -0
  1901. package/src/workspace-files/store.ts +339 -0
  1902. package/src/workspace-files/tool.ts +266 -0
@@ -0,0 +1,2714 @@
1
+ /**
2
+ * `agent-native connect <url>` — wire your local MCP-capable coding agent
3
+ * to a DEPLOYED agent-native app. OAuth-capable clients receive a standard
4
+ * remote MCP URL entry and authenticate in the host. Fallback clients use the
5
+ * browser device-code flow: open the verification URL, approve in the browser,
6
+ * and the minted HTTP MCP server entry is written idempotently.
7
+ *
8
+ * agent-native connect <url> [--client all|claude-code|
9
+ * codex|cowork|cursor|opencode|github-copilot]
10
+ * [--scope user|project]
11
+ * [--name <serverName>]
12
+ * agent-native reconnect [<url>] [--client ...] [--name <serverName>]
13
+ * agent-native connect <url> --token <token> (no-browser fallback)
14
+ * agent-native connect [--client ...] (pick first-party apps)
15
+ * agent-native connect --all [--client ...] (separate first-party app MCP resources)
16
+ *
17
+ * Server contract (implemented by another agent on `<url>`):
18
+ * POST <url>/mcp/connect/device/start (no auth)
19
+ * body { client?, app? }
20
+ * → { device_code, user_code, verification_uri,
21
+ * verification_uri_complete, interval, expires_in }
22
+ * POST <url>/mcp/connect/device/poll (no auth)
23
+ * body { device_code }
24
+ * → { status: "pending" }
25
+ * | { status: "approved", token, mcpUrl, serverName, mcpServerEntry }
26
+ * | { status: "expired" }
27
+ * | { status: "consumed" }
28
+ * | { status: "error" | "not_found", message? }
29
+ *
30
+ * Node-only CLI module. Uses Node built-ins, @clack/prompts, and global fetch.
31
+ */
32
+
33
+ import { spawn } from "node:child_process";
34
+ import fs from "node:fs";
35
+ import os from "node:os";
36
+ import path from "node:path";
37
+
38
+ import {
39
+ MCP_LEGACY_ROUTE_PREFIX,
40
+ MCP_PUBLIC_ROUTE_PREFIX,
41
+ } from "../mcp/route-paths.js";
42
+ import { findWorkspaceRoot } from "../mcp/workspace-resolve.js";
43
+ import {
44
+ CLIENTS,
45
+ ClientId,
46
+ configPathFor,
47
+ jsonMcpConfigKeyForClient,
48
+ removeSameUrlDuplicatesForClient,
49
+ writeCodexBlock,
50
+ writeHttpEntryForClient,
51
+ writeJsonMcpEntryForClient,
52
+ } from "./mcp-config-writers.js";
53
+ import {
54
+ isFirstPartyPlanHost,
55
+ writePlanPublishAuth,
56
+ } from "./plan-publish-store.js";
57
+ import { TEMPLATES, visibleTemplates } from "./templates-meta.js";
58
+
59
+ const DEVICE_START_PATH = `${MCP_PUBLIC_ROUTE_PREFIX}/connect/device/start`;
60
+ const DEVICE_POLL_PATH = `${MCP_PUBLIC_ROUTE_PREFIX}/connect/device/poll`;
61
+ const MCP_PATH = MCP_PUBLIC_ROUTE_PREFIX;
62
+ const LEGACY_MCP_PATH = MCP_LEGACY_ROUTE_PREFIX;
63
+ const SERVER_NAME_PREFIX = "agent-native";
64
+ const CONNECT_PREFERENCES_VERSION = 1;
65
+
66
+ /**
67
+ * Maps a normalised hosted MCP URL to the canonical server name for that
68
+ * first-party app. Kept in sync with BUILT_IN_APP_SKILLS in skills.ts (we
69
+ * cannot import from there — it imports connect.ts, which would be circular).
70
+ */
71
+ const CANONICAL_SERVER_NAME_BY_MCP_URL: Readonly<Record<string, string>> = {
72
+ "https://plan.agent-native.com/mcp": "plan",
73
+ "https://assets.agent-native.com/mcp": "agent-native-assets",
74
+ "https://design.agent-native.com/mcp": "agent-native-design",
75
+ "https://context-xray.agent-native.com/mcp": "agent-native-context-xray",
76
+ };
77
+ const LEGACY_SERVER_NAMES_BY_MCP_URL: Readonly<
78
+ Record<string, readonly string[]>
79
+ > = {
80
+ "https://plan.agent-native.com/mcp": [
81
+ "agent-native-plan",
82
+ "agent-native-plans",
83
+ "agent-native-visual-plans",
84
+ ],
85
+ };
86
+ const CONNECT_PROFILES_VERSION = 1;
87
+ const DEFAULT_DEV_GATEWAY = "http://127.0.0.1:8080";
88
+
89
+ const CLIENT_LABELS: Record<ClientId, string> = {
90
+ "claude-code": "Claude Code",
91
+ "claude-code-cli": "Claude Code CLI",
92
+ codex: "Codex",
93
+ cowork: "Claude Cowork",
94
+ cursor: "Cursor",
95
+ opencode: "OpenCode",
96
+ "github-copilot": "GitHub Copilot / VS Code",
97
+ };
98
+
99
+ const CLIENT_HINTS: Record<ClientId, string> = {
100
+ "claude-code": ".mcp.json or ~/.claude.json",
101
+ "claude-code-cli": ".mcp.json or ~/.claude.json",
102
+ codex: "$CODEX_HOME/config.toml or ~/.codex/config.toml",
103
+ cowork: "~/.cowork/mcp.json",
104
+ cursor: ".cursor/mcp.json or ~/.cursor/mcp.json",
105
+ opencode: "opencode.json or ~/.config/opencode/opencode.json",
106
+ "github-copilot": ".vscode/mcp.json or VS Code user mcp.json",
107
+ };
108
+
109
+ const REMOTE_MCP_OAUTH_CLIENTS = new Set<ClientId>([
110
+ "claude-code",
111
+ "claude-code-cli",
112
+ "cursor",
113
+ "opencode",
114
+ "github-copilot",
115
+ ]);
116
+
117
+ let logOutImpl = (msg: string) => process.stdout.write(`${msg}\n`);
118
+ let logErrImpl = (msg: string) => process.stderr.write(`${msg}\n`);
119
+
120
+ function logOut(msg: string): void {
121
+ logOutImpl(msg);
122
+ }
123
+ function logErr(msg: string): void {
124
+ logErrImpl(msg);
125
+ }
126
+
127
+ // ---------------------------------------------------------------------------
128
+ // Arg parsing
129
+ // ---------------------------------------------------------------------------
130
+
131
+ export interface ParsedConnectArgs {
132
+ /** Developer profile switch: local dev gateway or saved production config. */
133
+ mode?: "dev" | "prod" | "reauth" | "reconnect";
134
+ /** Positional URL (the deployed app origin). Undefined for `--all`. */
135
+ url?: string;
136
+ /** all | claude-code | codex | cowork | cursor | opencode | github-copilot (default "all"). claude-code-cli is accepted as a legacy alias for claude-code. */
137
+ client: string;
138
+ /** True when the user passed --client explicitly, so we skip the picker. */
139
+ clientExplicit: boolean;
140
+ /** user | project (default "user"). */
141
+ scope: string;
142
+ /** Override the minted MCP server name. */
143
+ name?: string;
144
+ /** No-browser fallback: skip device flow, use this token directly. */
145
+ token?: string;
146
+ /**
147
+ * Mint an ORG SERVICE token with this service name (e.g. "ci") instead of
148
+ * writing local MCP configs. Authenticates the human via the device flow,
149
+ * then calls the app's `create-org-service-token` action and prints the
150
+ * token once — for CI secrets like PLAN_RECAP_TOKEN.
151
+ */
152
+ serviceToken?: string;
153
+ /** Optional token TTL in days (1–365) for --service-token. */
154
+ ttlDays?: number;
155
+ /** Connect every first-party hosted app. */
156
+ all: boolean;
157
+ /** Comma-separated app names for profile switching. */
158
+ apps?: string;
159
+ /** Local dev-lazy gateway URL for `connect dev`. */
160
+ gateway?: string;
161
+ /** Shorthand for a local dev-lazy gateway port. */
162
+ port?: number;
163
+ /** Local owner email override for dev entries. */
164
+ ownerEmail?: string;
165
+ /**
166
+ * Embed `catalog_scope: "full"` in the minted token so the connected client
167
+ * bypasses the connector-catalog tier and sees the complete action surface.
168
+ * Matches the `fullCatalog` body param on the app's token-mint route.
169
+ */
170
+ fullCatalog?: boolean;
171
+ }
172
+
173
+ export function parseConnectArgs(argv: string[]): ParsedConnectArgs {
174
+ const out: ParsedConnectArgs = {
175
+ client: "all",
176
+ clientExplicit: false,
177
+ scope: "user",
178
+ all: false,
179
+ };
180
+ for (let i = 0; i < argv.length; i++) {
181
+ const a = argv[i];
182
+ const eat = (flag: string): string | undefined => {
183
+ if (a === flag) return argv[++i];
184
+ if (a.startsWith(`${flag}=`)) return a.slice(flag.length + 1);
185
+ return undefined;
186
+ };
187
+ let v: string | undefined;
188
+ if (a === "--all") out.all = true;
189
+ else if ((v = eat("--apps")) !== undefined) out.apps = v;
190
+ else if ((v = eat("--gateway")) !== undefined) out.gateway = v;
191
+ else if ((v = eat("--gateway-url")) !== undefined) out.gateway = v;
192
+ else if ((v = eat("--port")) !== undefined) out.port = Number(v);
193
+ else if ((v = eat("--owner-email")) !== undefined) out.ownerEmail = v;
194
+ else if ((v = eat("--client")) !== undefined) {
195
+ out.client = v;
196
+ out.clientExplicit = true;
197
+ } else if ((v = eat("--scope")) !== undefined) out.scope = v;
198
+ else if ((v = eat("--name")) !== undefined) out.name = v;
199
+ else if ((v = eat("--service-token")) !== undefined) out.serviceToken = v;
200
+ else if ((v = eat("--ttl-days")) !== undefined) out.ttlDays = Number(v);
201
+ else if ((v = eat("--token")) !== undefined) out.token = v;
202
+ else if (a === "--full-catalog") out.fullCatalog = true;
203
+ else if (!a.startsWith("-") && !out.url) {
204
+ if (
205
+ !out.mode &&
206
+ (a === "dev" || a === "prod" || a === "reauth" || a === "reconnect")
207
+ ) {
208
+ out.mode = a;
209
+ } else out.url = a;
210
+ }
211
+ }
212
+ return out;
213
+ }
214
+
215
+ /**
216
+ * Normalize a user-supplied app URL: trim, require http/https, strip the
217
+ * trailing slash. Throws a friendly Error otherwise.
218
+ */
219
+ export function normalizeUrl(raw: string): string {
220
+ const trimmed = (raw ?? "").trim();
221
+ if (!trimmed) {
222
+ throw new Error(
223
+ "Missing app URL. Usage: npx @agent-native/core@latest connect <url>",
224
+ );
225
+ }
226
+ let parsed: URL;
227
+ try {
228
+ parsed = new URL(trimmed);
229
+ } catch {
230
+ throw new Error(
231
+ `Not a valid URL: "${raw}". Pass a full origin, e.g. ` +
232
+ `npx @agent-native/core@latest connect https://mail.agent-native.com`,
233
+ );
234
+ }
235
+ if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
236
+ throw new Error(
237
+ `Unsupported URL scheme "${parsed.protocol}". Use http:// or https://`,
238
+ );
239
+ }
240
+ const host = parsed.hostname.toLowerCase();
241
+ const isLoopback =
242
+ host === "localhost" ||
243
+ host === "127.0.0.1" ||
244
+ host === "::1" ||
245
+ host === "[::1]" ||
246
+ host.startsWith("127.");
247
+ if (parsed.protocol === "http:" && !isLoopback) {
248
+ throw new Error(
249
+ `Refusing plaintext HTTP for non-loopback host "${parsed.hostname}". ` +
250
+ `Use https:// so bearer tokens are not sent in cleartext.`,
251
+ );
252
+ }
253
+ // origin + pathname, trailing slash stripped (origin keeps no path).
254
+ const base = `${parsed.origin}${parsed.pathname}`.replace(/\/+$/, "");
255
+ return base;
256
+ }
257
+
258
+ // Clients offered in the interactive picker and expanded by "all". Excludes
259
+ // the `claude-code-cli` alias so users only ever see a single "Claude Code"
260
+ // option (it still works if passed explicitly via --client).
261
+ const SELECTABLE_CLIENTS: ClientId[] = CLIENTS.filter(
262
+ (c) => c !== "claude-code-cli",
263
+ );
264
+
265
+ /** Resolve the requested clients list. "all" → every supported client. */
266
+ export function resolveClients(client: string): ClientId[] {
267
+ const c = normalizeClientAlias(client ?? "all");
268
+ if (c === "all" || c === "") return [...SELECTABLE_CLIENTS];
269
+ if (c.includes(",")) {
270
+ const clients = normalizeClientIds(c.split(",").map((part) => part.trim()));
271
+ if (clients.length > 0) return clients;
272
+ }
273
+ if ((CLIENTS as string[]).includes(c)) return [c as ClientId];
274
+ throw new Error(
275
+ `Unknown --client "${client}". Use: all, ${CLIENTS.join(", ")}`,
276
+ );
277
+ }
278
+
279
+ function normalizeClientAlias(value: string): string {
280
+ const id = value.trim().toLowerCase();
281
+ // The Claude Code CLI and desktop share ~/.claude.json, so they are one
282
+ // client. `claude-code-cli` stays accepted for back-compat but collapses to
283
+ // the single "Claude Code" option everywhere it surfaces.
284
+ if (
285
+ id === "claude" ||
286
+ id === "claude-code-desktop" ||
287
+ id === "claude-code-cli"
288
+ )
289
+ return "claude-code";
290
+ if (id === "copilot" || id === "vscode" || id === "vs-code") {
291
+ return "github-copilot";
292
+ }
293
+ return id;
294
+ }
295
+
296
+ export function connectPreferencesPath(): string {
297
+ return path.join(os.homedir(), ".agent-native", "connect.json");
298
+ }
299
+
300
+ function normalizeClientIds(values: unknown): ClientId[] {
301
+ if (!Array.isArray(values)) return [];
302
+ const seen = new Set<ClientId>();
303
+ const out: ClientId[] = [];
304
+ for (const value of values) {
305
+ if (typeof value !== "string") continue;
306
+ const id = normalizeClientAlias(value);
307
+ if (!(CLIENTS as string[]).includes(id)) continue;
308
+ const client = id as ClientId;
309
+ if (seen.has(client)) continue;
310
+ seen.add(client);
311
+ out.push(client);
312
+ }
313
+ return out;
314
+ }
315
+
316
+ export function readConnectClientPreferences(
317
+ file: string = connectPreferencesPath(),
318
+ ): ClientId[] | null {
319
+ try {
320
+ const parsed = JSON.parse(fs.readFileSync(file, "utf-8"));
321
+ const clients = normalizeClientIds(
322
+ parsed?.defaultClients ?? parsed?.clients,
323
+ );
324
+ return clients.length > 0 ? clients : null;
325
+ } catch {
326
+ return null;
327
+ }
328
+ }
329
+
330
+ export function writeConnectClientPreferences(
331
+ clients: ClientId[],
332
+ file: string = connectPreferencesPath(),
333
+ ): void {
334
+ const normalized = normalizeClientIds(clients);
335
+ if (normalized.length === 0) return;
336
+ fs.mkdirSync(path.dirname(file), { recursive: true });
337
+ fs.writeFileSync(
338
+ file,
339
+ JSON.stringify(
340
+ {
341
+ version: CONNECT_PREFERENCES_VERSION,
342
+ defaultClients: normalized,
343
+ updatedAt: new Date().toISOString(),
344
+ },
345
+ null,
346
+ 2,
347
+ ) + "\n",
348
+ "utf-8",
349
+ );
350
+ }
351
+
352
+ export interface ConnectClientPromptContext {
353
+ initialClients: ClientId[];
354
+ options: { value: ClientId; label: string; hint: string }[];
355
+ preferencesFile: string;
356
+ }
357
+
358
+ export interface HostedApp {
359
+ name: string;
360
+ label: string;
361
+ url: string;
362
+ }
363
+
364
+ export interface ConnectHostedAppsPromptContext {
365
+ apps: HostedApp[];
366
+ initialApps: string[];
367
+ }
368
+
369
+ function clientPromptOptions(): ConnectClientPromptContext["options"] {
370
+ return SELECTABLE_CLIENTS.map((client) => ({
371
+ value: client,
372
+ label: CLIENT_LABELS[client],
373
+ hint: CLIENT_HINTS[client],
374
+ }));
375
+ }
376
+
377
+ function shouldPrompt(deps: ConnectDeps): boolean {
378
+ if (deps.isInteractive) return deps.isInteractive();
379
+ if (process.env.AGENT_NATIVE_NO_PROMPT === "1") return false;
380
+ if (process.env.CI === "true") return false;
381
+ return !!process.stdin.isTTY && !!process.stdout.isTTY;
382
+ }
383
+
384
+ function shouldPromptForClients(deps: ConnectDeps): boolean {
385
+ return shouldPrompt(deps);
386
+ }
387
+
388
+ async function promptForClients(
389
+ context: ConnectClientPromptContext,
390
+ ): Promise<ClientId[] | null> {
391
+ const clack = await import("@clack/prompts");
392
+ const result = await clack.multiselect({
393
+ message:
394
+ "Write MCP config for which local agents?\n" +
395
+ " (space toggles, enter confirms; saved for next time)",
396
+ options: context.options,
397
+ initialValues: context.initialClients,
398
+ required: true,
399
+ });
400
+ if (clack.isCancel(result)) {
401
+ clack.cancel("Cancelled.");
402
+ return null;
403
+ }
404
+ return normalizeClientIds(result);
405
+ }
406
+
407
+ function normalizeHostedAppNames(values: unknown, apps: HostedApp[]): string[] {
408
+ if (!Array.isArray(values)) return [];
409
+ const byName = new Map(apps.map((app) => [app.name, app]));
410
+ const seen = new Set<string>();
411
+ const out: string[] = [];
412
+ for (const value of values) {
413
+ if (typeof value !== "string") continue;
414
+ const app = byName.get(value);
415
+ if (!app || seen.has(app.name)) continue;
416
+ seen.add(app.name);
417
+ out.push(app.name);
418
+ }
419
+ return out;
420
+ }
421
+
422
+ async function promptForHostedApps(
423
+ context: ConnectHostedAppsPromptContext,
424
+ ): Promise<string[] | null> {
425
+ const clack = await import("@clack/prompts");
426
+ const result = await clack.multiselect({
427
+ message:
428
+ "Which Agent Native apps do you want to connect?\n" +
429
+ " (all are selected by default; space toggles, enter confirms)",
430
+ options: context.apps.map((app) => ({
431
+ value: app.name,
432
+ label: app.label,
433
+ hint: app.url,
434
+ })),
435
+ initialValues: context.initialApps,
436
+ required: true,
437
+ });
438
+ if (clack.isCancel(result)) {
439
+ clack.cancel("Cancelled.");
440
+ return null;
441
+ }
442
+ return normalizeHostedAppNames(result, context.apps);
443
+ }
444
+
445
+ async function resolveConnectClients(
446
+ parsed: ParsedConnectArgs,
447
+ deps: ConnectDeps,
448
+ ): Promise<ClientId[] | null> {
449
+ if (parsed.clientExplicit) return resolveClients(parsed.client);
450
+
451
+ const defaultClients = resolveClients(parsed.client);
452
+ if (!shouldPromptForClients(deps)) return defaultClients;
453
+
454
+ const preferencesFile = deps.preferencesFile ?? connectPreferencesPath();
455
+ const initialClients =
456
+ readConnectClientPreferences(preferencesFile) ?? defaultClients;
457
+ const prompt = deps.promptClients ?? promptForClients;
458
+ const selected = normalizeClientIds(
459
+ await prompt({
460
+ initialClients,
461
+ options: clientPromptOptions(),
462
+ preferencesFile,
463
+ }),
464
+ );
465
+ if (selected.length === 0) return null;
466
+
467
+ try {
468
+ writeConnectClientPreferences(selected, preferencesFile);
469
+ } catch (err: any) {
470
+ logErr(
471
+ ` Could not save connect client preference (${err?.message ?? err}).`,
472
+ );
473
+ }
474
+ return selected;
475
+ }
476
+
477
+ async function resolveHostedAppsFromPrompt(
478
+ deps: ConnectDeps,
479
+ ): Promise<HostedApp[] | null> {
480
+ const apps = hostedApps();
481
+ if (apps.length === 0) {
482
+ logErr(" No hosted first-party apps found in the template registry.");
483
+ return null;
484
+ }
485
+ if (!shouldPrompt(deps)) return null;
486
+
487
+ const prompt = deps.promptHostedApps ?? promptForHostedApps;
488
+ const selectedNames = normalizeHostedAppNames(
489
+ await prompt({
490
+ apps,
491
+ initialApps: apps.map((app) => app.name),
492
+ }),
493
+ apps,
494
+ );
495
+ if (selectedNames.length === 0) return [];
496
+
497
+ const selected = new Set(selectedNames);
498
+ return apps.filter((app) => selected.has(app.name));
499
+ }
500
+
501
+ function clientArgForDeviceFlow(clients: ClientId[]): string {
502
+ return clients.length === 1 ? clients[0] : "all";
503
+ }
504
+
505
+ export function supportsRemoteMcpOAuth(client: ClientId): boolean {
506
+ return REMOTE_MCP_OAUTH_CLIENTS.has(client);
507
+ }
508
+
509
+ function clientLabelList(clients: ClientId[]): string {
510
+ return clients.map((client) => CLIENT_LABELS[client]).join(", ");
511
+ }
512
+
513
+ function sentenceClientLabelList(clients: ClientId[]): string {
514
+ const labels = clients.map((client) => CLIENT_LABELS[client]);
515
+ if (labels.length <= 1) return labels[0] ?? "";
516
+ if (labels.length === 2) return `${labels[0]} and ${labels[1]}`;
517
+ return `${labels.slice(0, -1).join(", ")}, and ${labels[labels.length - 1]}`;
518
+ }
519
+
520
+ function oauthNextStepsForClients(
521
+ clients: ClientId[],
522
+ serverName?: string,
523
+ ): string[] {
524
+ const lines: string[] = [];
525
+ if (clients.includes("claude-code") || clients.includes("claude-code-cli")) {
526
+ lines.push(
527
+ "Claude Code: restart Claude Code, run /mcp, and choose Authenticate.",
528
+ );
529
+ }
530
+ if (clients.includes("cursor")) {
531
+ lines.push(
532
+ "Cursor: restart or reload Cursor, then authenticate the MCP server from Cursor MCP settings if prompted.",
533
+ );
534
+ }
535
+ if (clients.includes("opencode")) {
536
+ lines.push(
537
+ `OpenCode: run opencode mcp auth ${serverName ?? "<server-name>"} or authenticate on first use.`,
538
+ );
539
+ }
540
+ if (clients.includes("github-copilot")) {
541
+ lines.push(
542
+ "GitHub Copilot / VS Code: reload VS Code, open the MCP config, and use the Auth action above the server if prompted.",
543
+ );
544
+ }
545
+ return lines;
546
+ }
547
+
548
+ function clientsNotIn(
549
+ requestedClients: ClientId[],
550
+ effectiveClients: ClientId[],
551
+ ): ClientId[] {
552
+ const effective = new Set(effectiveClients);
553
+ return requestedClients.filter((client) => !effective.has(client));
554
+ }
555
+
556
+ function displayMcpServerName(serverName: string | undefined): string {
557
+ if (!serverName) return "Agent Native MCP";
558
+ if (serverName === "plan") return "Plan MCP";
559
+ return `"${serverName}" MCP`;
560
+ }
561
+
562
+ async function showReconnectSuccessOutro({
563
+ serverName,
564
+ clients,
565
+ }: {
566
+ serverName: string | undefined;
567
+ clients: ClientId[];
568
+ }): Promise<void> {
569
+ const lines = [`✅ Reconnected ${displayMcpServerName(serverName)}.`];
570
+ if (clients.includes("codex")) {
571
+ lines.push(
572
+ "Codex: start a new Codex session now; the MCP tools should be available there.",
573
+ );
574
+ }
575
+ const oauthClients = clients.filter((client) =>
576
+ supportsRemoteMcpOAuth(client),
577
+ );
578
+ if (oauthClients.length > 0) {
579
+ lines.push(...oauthNextStepsForClients(oauthClients, serverName));
580
+ }
581
+ if (!clients.includes("codex") && oauthClients.length === 0) {
582
+ lines.push(
583
+ `Restart or reload ${sentenceClientLabelList(
584
+ clients,
585
+ )} before using the MCP tools.`,
586
+ );
587
+ }
588
+
589
+ const message = lines.join("\n");
590
+ try {
591
+ const clack = await import("@clack/prompts");
592
+ clack.outro(message);
593
+ } catch {
594
+ logOut("");
595
+ for (const line of lines) logOut(` ${line}`);
596
+ }
597
+ }
598
+
599
+ /** Derive an app slug from a deployed origin, e.g. mail.agent-native.com → mail. */
600
+ function appSlugFromUrl(url: string): string {
601
+ try {
602
+ const host = new URL(url).hostname;
603
+ const first = host.split(".")[0];
604
+ return first && first !== "www" ? first : "app";
605
+ } catch {
606
+ return "app";
607
+ }
608
+ }
609
+
610
+ function defaultServerName(url: string): string {
611
+ const canonical = canonicalServerNameForMcpUrl(mcpUrlForBaseUrl(url));
612
+ if (canonical) return canonical;
613
+ return `${SERVER_NAME_PREFIX}-${appSlugFromUrl(url)}`;
614
+ }
615
+
616
+ function canonicalServerNameForMcpUrl(
617
+ mcpUrl: string | undefined,
618
+ ): string | undefined {
619
+ const key = canonicalMcpUrl(mcpUrl);
620
+ return key ? CANONICAL_SERVER_NAME_BY_MCP_URL[key] : undefined;
621
+ }
622
+
623
+ function reconnectServerNameForMcpUrl(
624
+ mcpUrl: string | undefined,
625
+ serverName: string | undefined,
626
+ ): string | undefined {
627
+ const key = canonicalMcpUrl(mcpUrl);
628
+ if (!key || !serverName) return serverName;
629
+ const canonical = CANONICAL_SERVER_NAME_BY_MCP_URL[key];
630
+ if (!canonical || serverName === canonical) return serverName;
631
+ const legacyNames = LEGACY_SERVER_NAMES_BY_MCP_URL[key] ?? [];
632
+ return legacyNames.includes(serverName) ? canonical : serverName;
633
+ }
634
+
635
+ // ---------------------------------------------------------------------------
636
+ // Browser open (mirrors workspace-dev.ts openBrowser)
637
+ // ---------------------------------------------------------------------------
638
+
639
+ function openInBrowser(url: string): void {
640
+ if (process.env.AGENT_NATIVE_NO_OPEN === "1") return;
641
+ try {
642
+ const command =
643
+ process.platform === "darwin"
644
+ ? "open"
645
+ : process.platform === "win32"
646
+ ? "cmd"
647
+ : "xdg-open";
648
+ const openArgs =
649
+ process.platform === "win32" ? ["/c", "start", "", url] : [url];
650
+ const child = spawn(command, openArgs, {
651
+ stdio: "ignore",
652
+ detached: true,
653
+ });
654
+ child.unref();
655
+ } catch {
656
+ // Non-fatal: the user can open the URL manually (we already printed it).
657
+ }
658
+ }
659
+
660
+ // ---------------------------------------------------------------------------
661
+ // Device-code flow
662
+ // ---------------------------------------------------------------------------
663
+
664
+ interface DeviceStartResponse {
665
+ device_code: string;
666
+ user_code: string;
667
+ verification_uri: string;
668
+ verification_uri_complete: string;
669
+ interval?: number;
670
+ expires_in?: number;
671
+ }
672
+
673
+ interface DevicePollResponse {
674
+ status:
675
+ | "pending"
676
+ | "approved"
677
+ | "expired"
678
+ | "consumed"
679
+ | "error"
680
+ | "not_found";
681
+ token?: string;
682
+ mcpUrl?: string;
683
+ serverName?: string;
684
+ mcpServerEntry?: Record<string, unknown>;
685
+ message?: string;
686
+ error?: string;
687
+ }
688
+
689
+ /** Injectable hooks so the poll state machine is unit-testable. */
690
+ export interface ConnectDeps {
691
+ /** Defaults to global fetch. */
692
+ fetchImpl?: typeof fetch;
693
+ /** Sleep between polls (ms). Defaults to real setTimeout. */
694
+ sleep?: (ms: number) => Promise<void>;
695
+ /** Open the verification URL. Defaults to the platform browser opener. */
696
+ openBrowser?: (url: string) => void | Promise<void>;
697
+ /** Optional wrapper for showing progress while the browser opener runs. */
698
+ withBrowserOpenSpinner?: (
699
+ message: string,
700
+ openBrowser: () => void | Promise<void>,
701
+ ) => void | Promise<void>;
702
+ /** Override "now" for the expiry cap (ms epoch). Defaults to Date.now. */
703
+ now?: () => number;
704
+ /** Tests/embedders can force or suppress the interactive client picker. */
705
+ isInteractive?: () => boolean;
706
+ /** Injectable client picker. Defaults to @clack/prompts multiselect. */
707
+ promptClients?: (
708
+ context: ConnectClientPromptContext,
709
+ ) => Promise<ClientId[] | null>;
710
+ /** Injectable hosted app picker. Defaults to @clack/prompts multiselect. */
711
+ promptHostedApps?: (
712
+ context: ConnectHostedAppsPromptContext,
713
+ ) => Promise<string[] | null>;
714
+ /** Override the persisted connect preferences file. */
715
+ preferencesFile?: string;
716
+ /** Override the saved dev/prod profile file. */
717
+ profilesFile?: string;
718
+ /** Optional output hooks used when another clack-based command embeds connect. */
719
+ logOut?: (message: string) => void;
720
+ logErr?: (message: string) => void;
721
+ }
722
+
723
+ function realSleep(ms: number): Promise<void> {
724
+ return new Promise((resolve) => setTimeout(resolve, ms));
725
+ }
726
+
727
+ async function postJson(
728
+ fetchImpl: typeof fetch,
729
+ url: string,
730
+ body: unknown,
731
+ ): Promise<{ status: number; json: any }> {
732
+ const controller = new AbortController();
733
+ const timeout = setTimeout(() => controller.abort(), 30_000);
734
+ try {
735
+ const response = await fetchImpl(url, {
736
+ method: "POST",
737
+ headers: { "content-type": "application/json" },
738
+ body: JSON.stringify(body ?? {}),
739
+ signal: controller.signal,
740
+ });
741
+ let json: any = null;
742
+ try {
743
+ json = await response.json();
744
+ } catch {
745
+ json = null;
746
+ }
747
+ return { status: response.status, json };
748
+ } finally {
749
+ clearTimeout(timeout);
750
+ }
751
+ }
752
+
753
+ function responseMessage(json: any, fallback: string): string {
754
+ const message =
755
+ typeof json?.message === "string"
756
+ ? json.message
757
+ : typeof json?.error === "string"
758
+ ? json.error
759
+ : "";
760
+ return message.trim() || fallback;
761
+ }
762
+
763
+ function stripMcpPath(baseUrl: string): string {
764
+ const parsed = new URL(baseUrl);
765
+ const pathname = parsed.pathname.replace(/\/+$/, "");
766
+ const suffix = mcpPathSuffix(pathname);
767
+ if (suffix) {
768
+ parsed.pathname = pathname.slice(0, -suffix.length) || "/";
769
+ parsed.search = "";
770
+ parsed.hash = "";
771
+ return `${parsed.origin}${parsed.pathname}`.replace(/\/+$/, "");
772
+ }
773
+ return baseUrl;
774
+ }
775
+
776
+ function mcpUrlForBaseUrl(baseUrl: string): string {
777
+ const parsed = new URL(baseUrl);
778
+ const pathname = parsed.pathname.replace(/\/+$/, "");
779
+ const suffix = mcpPathSuffix(pathname);
780
+ if (suffix) {
781
+ parsed.pathname = `${pathname.slice(0, -suffix.length)}${MCP_PATH}`;
782
+ parsed.search = "";
783
+ parsed.hash = "";
784
+ return `${parsed.origin}${parsed.pathname}`;
785
+ }
786
+ return `${baseUrl.replace(/\/+$/, "")}${MCP_PATH}`;
787
+ }
788
+
789
+ async function validateOAuthMcpServer(
790
+ baseUrl: string,
791
+ mcpUrl: string,
792
+ deps: ConnectDeps,
793
+ ): Promise<boolean> {
794
+ const fetchImpl = deps.fetchImpl ?? fetch;
795
+ const sleep = deps.sleep ?? realSleep;
796
+ const metadataUrl = `${baseUrl}/.well-known/oauth-protected-resource`;
797
+ let lastFailure = "";
798
+
799
+ for (let attempt = 0; attempt < 2; attempt++) {
800
+ const controller = new AbortController();
801
+ const timeout = setTimeout(() => controller.abort(), 15_000);
802
+ try {
803
+ const response = await fetchImpl(metadataUrl, {
804
+ method: "GET",
805
+ headers: { accept: "application/json" },
806
+ signal: controller.signal,
807
+ });
808
+ if (!response.ok) {
809
+ lastFailure = `HTTP ${response.status}`;
810
+ } else {
811
+ const metadata = (await response.json().catch(() => null)) as {
812
+ resource?: unknown;
813
+ } | null;
814
+ if (
815
+ canonicalMcpUrl(String(metadata?.resource ?? "")) !==
816
+ canonicalMcpUrl(mcpUrl)
817
+ ) {
818
+ logErr(
819
+ ` ${metadataUrl} did not advertise the expected MCP resource ` +
820
+ `${mcpUrl}.`,
821
+ );
822
+ return false;
823
+ }
824
+ return true;
825
+ }
826
+ } catch (err: any) {
827
+ lastFailure = err?.message ?? String(err);
828
+ } finally {
829
+ clearTimeout(timeout);
830
+ }
831
+
832
+ if (attempt === 0) await sleep(500);
833
+ }
834
+
835
+ logErr(
836
+ ` Could not validate OAuth MCP support at ${metadataUrl}` +
837
+ (lastFailure ? ` (${lastFailure}).` : "."),
838
+ );
839
+ return false;
840
+ }
841
+
842
+ const SPINNER = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"];
843
+
844
+ /**
845
+ * Run the device-code flow against `baseUrl` and return the approved grant.
846
+ * Resolves with `null` (and prints a clear message) on expired/consumed or
847
+ * other terminal failure — the caller maps that to a non-zero exit.
848
+ */
849
+ export async function runDeviceFlow(
850
+ baseUrl: string,
851
+ appSlug: string,
852
+ clientArg: string,
853
+ deps: ConnectDeps = {},
854
+ options: { fullCatalog?: boolean } = {},
855
+ ): Promise<{
856
+ token?: string;
857
+ mcpUrl: string;
858
+ serverName: string;
859
+ headers?: Record<string, string>;
860
+ } | null> {
861
+ const fetchImpl = deps.fetchImpl ?? fetch;
862
+ const sleep = deps.sleep ?? realSleep;
863
+ const open = deps.openBrowser ?? openInBrowser;
864
+ const now = deps.now ?? (() => Date.now());
865
+
866
+ let start: DeviceStartResponse | null = null;
867
+ // A cold/propagating Plan instance can briefly 404/5xx before its connect
868
+ // route is registered (async plugin init). Retry a few times so a recoverable
869
+ // blip doesn't kill the connect before polling even begins.
870
+ const START_ATTEMPTS = 4;
871
+ for (let attempt = 0; attempt < START_ATTEMPTS; attempt++) {
872
+ try {
873
+ const { status, json } = await postJson(
874
+ fetchImpl,
875
+ `${baseUrl}${DEVICE_START_PATH}`,
876
+ {
877
+ client: clientArg,
878
+ app: appSlug,
879
+ ...(options.fullCatalog ? { fullCatalog: true } : {}),
880
+ },
881
+ );
882
+ if (status >= 200 && status < 300 && json?.device_code) {
883
+ start = json as DeviceStartResponse;
884
+ break;
885
+ }
886
+ if ((status === 404 || status >= 500) && attempt < START_ATTEMPTS - 1) {
887
+ await sleep(1000 * (attempt + 1));
888
+ continue;
889
+ }
890
+ logErr(
891
+ ` Could not start the connect flow on ${baseUrl} ` +
892
+ `(HTTP ${status}). Is this an agent-native app, and is it ` +
893
+ `deployed with the connect endpoint enabled?`,
894
+ );
895
+ return null;
896
+ } catch (err: any) {
897
+ if (attempt < START_ATTEMPTS - 1) {
898
+ await sleep(1000 * (attempt + 1));
899
+ continue;
900
+ }
901
+ logErr(
902
+ ` Could not reach ${baseUrl} (${err?.message ?? err}). ` +
903
+ `Check the URL and your network.`,
904
+ );
905
+ return null;
906
+ }
907
+ }
908
+ if (!start) return null;
909
+
910
+ const interval = Math.max(1, Number(start.interval) || 5);
911
+ const expiresIn = Math.max(interval, Number(start.expires_in) || 600);
912
+ const deadline = now() + expiresIn * 1000;
913
+
914
+ logOut("");
915
+ logOut(` Connecting to ${baseUrl}`);
916
+ logOut("");
917
+ logOut(` Your code: ${start.user_code}`);
918
+ logOut(` Open: ${start.verification_uri_complete}`);
919
+ logOut("");
920
+ logOut(" Approve in the browser to finish. Opening it now…");
921
+ const openVerificationUrl = () => open(start.verification_uri_complete);
922
+ if (deps.withBrowserOpenSpinner) {
923
+ await deps.withBrowserOpenSpinner(
924
+ "Opening browser for approval",
925
+ openVerificationUrl,
926
+ );
927
+ } else {
928
+ await openVerificationUrl();
929
+ }
930
+
931
+ let spin = 0;
932
+ let transientStreak = 0;
933
+ // Ride out brief cold-instance blips, but don't poll a persistently-dead
934
+ // endpoint forever: give up after this many consecutive transient (404/5xx
935
+ // or network-error) polls. Reset as soon as one poll responds normally.
936
+ const MAX_TRANSIENT_POLLS = 20;
937
+ const isTTY = !!process.stdout.isTTY;
938
+ while (now() < deadline) {
939
+ let poll: DevicePollResponse;
940
+ let transient = false;
941
+ try {
942
+ const { status, json } = await postJson(
943
+ fetchImpl,
944
+ `${baseUrl}${DEVICE_POLL_PATH}`,
945
+ { device_code: start.device_code },
946
+ );
947
+ if (status < 200 || status >= 300) {
948
+ if (isTerminalPollBody(json)) {
949
+ poll = json as DevicePollResponse;
950
+ } else if (status === 404 || status >= 500) {
951
+ // Transient: a cold/propagating Plan instance can briefly serve a
952
+ // bare 404 (the MCP route isn't registered until async plugin init
953
+ // settles) or a 5xx before it's healthy. The next poll usually lands
954
+ // on a warm instance, so keep polling until the deadline instead of
955
+ // hard-failing the whole connect on a recoverable blip. (This is the
956
+ // recurring "Cannot find any route matching [POST] .../mcp" case.)
957
+ poll = { status: "pending" };
958
+ transient = true;
959
+ } else {
960
+ if (isTTY) process.stdout.write("\r\x1b[K");
961
+ logErr(
962
+ ` Connect polling failed (HTTP ${status}): ` +
963
+ responseMessage(json, "server returned an error."),
964
+ );
965
+ return null;
966
+ }
967
+ } else {
968
+ poll = (json ?? { status: "pending" }) as DevicePollResponse;
969
+ }
970
+ } catch {
971
+ // Transient network error — keep polling.
972
+ poll = { status: "pending" };
973
+ transient = true;
974
+ }
975
+
976
+ if (transient) {
977
+ if (++transientStreak > MAX_TRANSIENT_POLLS) {
978
+ if (isTTY) process.stdout.write("\r\x1b[K");
979
+ logErr(
980
+ " Connect endpoint is not responding (repeated 404/5xx). It may be " +
981
+ "mid-deploy — wait a minute and run the command again.",
982
+ );
983
+ return null;
984
+ }
985
+ } else {
986
+ transientStreak = 0;
987
+ }
988
+
989
+ if (poll.status === "approved") {
990
+ if (isTTY) process.stdout.write("\r\x1b[K");
991
+ const token = poll.token ?? "";
992
+ const mcpUrl = mcpUrlForBaseUrl(poll.mcpUrl ?? baseUrl);
993
+ const serverName = poll.serverName ?? `${SERVER_NAME_PREFIX}-${appSlug}`;
994
+ const headers =
995
+ poll.mcpServerEntry &&
996
+ typeof poll.mcpServerEntry === "object" &&
997
+ poll.mcpServerEntry.headers &&
998
+ typeof poll.mcpServerEntry.headers === "object"
999
+ ? (poll.mcpServerEntry.headers as Record<string, string>)
1000
+ : undefined;
1001
+ logOut(" Approved.");
1002
+ return {
1003
+ token: token || undefined,
1004
+ mcpUrl,
1005
+ serverName,
1006
+ ...(headers ? { headers } : {}),
1007
+ };
1008
+ }
1009
+ if (poll.status === "expired") {
1010
+ if (isTTY) process.stdout.write("\r\x1b[K");
1011
+ logErr(" The connect request expired before it was approved.");
1012
+ logErr(" Run the command again to retry.");
1013
+ return null;
1014
+ }
1015
+ if (poll.status === "consumed") {
1016
+ if (isTTY) process.stdout.write("\r\x1b[K");
1017
+ logErr(" This connect code was already used. Run the command again.");
1018
+ return null;
1019
+ }
1020
+ if (poll.status === "error" || poll.status === "not_found") {
1021
+ if (isTTY) process.stdout.write("\r\x1b[K");
1022
+ logErr(
1023
+ ` Connect polling failed: ${responseMessage(
1024
+ poll,
1025
+ poll.status === "not_found"
1026
+ ? "device code was not found."
1027
+ : "server returned an error.",
1028
+ )}`,
1029
+ );
1030
+ return null;
1031
+ }
1032
+
1033
+ if (isTTY) {
1034
+ process.stdout.write(
1035
+ `\r ${SPINNER[spin++ % SPINNER.length]} Waiting for approval…`,
1036
+ );
1037
+ }
1038
+ await sleep(interval * 1000);
1039
+ }
1040
+
1041
+ if (isTTY) process.stdout.write("\r\x1b[K");
1042
+ logErr(" Timed out waiting for approval. Run the command again to retry.");
1043
+ return null;
1044
+ }
1045
+
1046
+ function isTerminalPollBody(json: any): boolean {
1047
+ return (
1048
+ json?.status === "not_found" ||
1049
+ json?.status === "error" ||
1050
+ json?.status === "expired" ||
1051
+ json?.status === "consumed"
1052
+ );
1053
+ }
1054
+
1055
+ // ---------------------------------------------------------------------------
1056
+ // Writing config(s)
1057
+ // ---------------------------------------------------------------------------
1058
+
1059
+ function projectBaseDir(): string {
1060
+ const cwd = process.cwd();
1061
+ return findWorkspaceRoot(cwd) ?? path.resolve(cwd);
1062
+ }
1063
+
1064
+ /**
1065
+ * Write the HTTP MCP entry into every requested client config idempotently.
1066
+ * Returns the list of files written so the caller can print them.
1067
+ */
1068
+ export function writeConfigs(
1069
+ clients: ClientId[],
1070
+ serverName: string,
1071
+ mcpUrl: string,
1072
+ token: string | undefined,
1073
+ scope: string,
1074
+ baseDir: string = projectBaseDir(),
1075
+ headers?: Record<string, string>,
1076
+ ): { client: ClientId; file: string }[] {
1077
+ const written: { client: ClientId; file: string }[] = [];
1078
+ for (const client of clients) {
1079
+ const file = writeHttpEntryForClient(
1080
+ client,
1081
+ serverName,
1082
+ mcpUrl,
1083
+ token,
1084
+ baseDir,
1085
+ scope,
1086
+ headers,
1087
+ );
1088
+ written.push({ client, file });
1089
+ }
1090
+ return written;
1091
+ }
1092
+
1093
+ // ---------------------------------------------------------------------------
1094
+ // Developer profile switcher (`connect dev` / `connect prod`)
1095
+ // ---------------------------------------------------------------------------
1096
+
1097
+ type SavedMcpEntry =
1098
+ | {
1099
+ kind: "json";
1100
+ entry: Record<string, unknown>;
1101
+ savedAt: string;
1102
+ }
1103
+ | {
1104
+ kind: "codex";
1105
+ block: string;
1106
+ savedAt: string;
1107
+ };
1108
+
1109
+ interface ConnectProfiles {
1110
+ version: number;
1111
+ updatedAt?: string;
1112
+ prodEntries?: Record<string, Record<string, Record<string, SavedMcpEntry>>>;
1113
+ }
1114
+
1115
+ interface CurrentMcpEntry {
1116
+ file: string;
1117
+ saved?: SavedMcpEntry;
1118
+ }
1119
+
1120
+ interface ConnectableApp extends HostedApp {
1121
+ core: boolean;
1122
+ }
1123
+
1124
+ export function connectProfilesPath(): string {
1125
+ return path.join(os.homedir(), ".agent-native", "connect-profiles.json");
1126
+ }
1127
+
1128
+ function readConnectProfiles(file: string): ConnectProfiles {
1129
+ try {
1130
+ const parsed = JSON.parse(fs.readFileSync(file, "utf-8"));
1131
+ if (parsed && typeof parsed === "object") {
1132
+ return {
1133
+ version: Number(parsed.version) || CONNECT_PROFILES_VERSION,
1134
+ updatedAt:
1135
+ typeof parsed.updatedAt === "string" ? parsed.updatedAt : undefined,
1136
+ prodEntries:
1137
+ parsed.prodEntries && typeof parsed.prodEntries === "object"
1138
+ ? parsed.prodEntries
1139
+ : {},
1140
+ };
1141
+ }
1142
+ } catch {
1143
+ // no saved profiles yet
1144
+ }
1145
+ return { version: CONNECT_PROFILES_VERSION, prodEntries: {} };
1146
+ }
1147
+
1148
+ function writeConnectProfiles(file: string, profiles: ConnectProfiles): void {
1149
+ profiles.version = CONNECT_PROFILES_VERSION;
1150
+ profiles.updatedAt = new Date().toISOString();
1151
+ fs.mkdirSync(path.dirname(file), { recursive: true });
1152
+ fs.writeFileSync(file, JSON.stringify(profiles, null, 2) + "\n", "utf-8");
1153
+ }
1154
+
1155
+ function savedProfileEntry(
1156
+ profiles: ConnectProfiles,
1157
+ serverName: string,
1158
+ client: ClientId,
1159
+ file: string,
1160
+ ): SavedMcpEntry | undefined {
1161
+ return profiles.prodEntries?.[serverName]?.[client]?.[file];
1162
+ }
1163
+
1164
+ function setSavedProfileEntry(
1165
+ profiles: ConnectProfiles,
1166
+ serverName: string,
1167
+ client: ClientId,
1168
+ file: string,
1169
+ entry: SavedMcpEntry,
1170
+ ): void {
1171
+ profiles.prodEntries ??= {};
1172
+ profiles.prodEntries[serverName] ??= {};
1173
+ profiles.prodEntries[serverName][client] ??= {};
1174
+ profiles.prodEntries[serverName][client][file] = entry;
1175
+ }
1176
+
1177
+ function readJsonMcpServerEntry(
1178
+ client: ClientId,
1179
+ file: string,
1180
+ serverName: string,
1181
+ ): Record<string, unknown> | undefined {
1182
+ try {
1183
+ const parsed = JSON.parse(fs.readFileSync(file, "utf-8"));
1184
+ const entry = parsed?.[jsonMcpConfigKeyForClient(client)]?.[serverName];
1185
+ return entry && typeof entry === "object" ? entry : undefined;
1186
+ } catch {
1187
+ return undefined;
1188
+ }
1189
+ }
1190
+
1191
+ function tomlQuoteForRead(s: string): string {
1192
+ return `"${s.replace(/\\/g, "\\\\").replace(/"/g, '\\"')}"`;
1193
+ }
1194
+
1195
+ function codexHeadersForRead(name: string): string[] {
1196
+ const headers = [`[mcp_servers.${tomlQuoteForRead(name)}]`];
1197
+ if (/^[A-Za-z0-9_-]+$/.test(name)) headers.push(`[mcp_servers.${name}]`);
1198
+ return headers;
1199
+ }
1200
+
1201
+ function readCodexMcpBlock(
1202
+ file: string,
1203
+ serverName: string,
1204
+ ): string | undefined {
1205
+ let content = "";
1206
+ try {
1207
+ content = fs.readFileSync(file, "utf-8");
1208
+ } catch {
1209
+ return undefined;
1210
+ }
1211
+ const headers = new Set(codexHeadersForRead(serverName));
1212
+ const lines = content.split(/\r?\n/);
1213
+ for (let i = 0; i < lines.length; i++) {
1214
+ if (!headers.has(lines[i].trim())) continue;
1215
+ const block: string[] = [lines[i]];
1216
+ i++;
1217
+ while (i < lines.length && !/^\s*\[/.test(lines[i])) {
1218
+ block.push(lines[i]);
1219
+ i++;
1220
+ }
1221
+ return block.join("\n").replace(/\n*$/, "") + "\n";
1222
+ }
1223
+ return undefined;
1224
+ }
1225
+
1226
+ function readCurrentMcpEntry(
1227
+ client: ClientId,
1228
+ serverName: string,
1229
+ baseDir: string,
1230
+ scope: string,
1231
+ ): CurrentMcpEntry {
1232
+ const file = configPathFor(client, baseDir, scope);
1233
+ if (client === "codex") {
1234
+ const block = readCodexMcpBlock(file, serverName);
1235
+ return {
1236
+ file,
1237
+ saved: block
1238
+ ? { kind: "codex", block, savedAt: new Date().toISOString() }
1239
+ : undefined,
1240
+ };
1241
+ }
1242
+ const entry = readJsonMcpServerEntry(client, file, serverName);
1243
+ return {
1244
+ file,
1245
+ saved: entry
1246
+ ? { kind: "json", entry, savedAt: new Date().toISOString() }
1247
+ : undefined,
1248
+ };
1249
+ }
1250
+
1251
+ function writeSavedMcpEntry(
1252
+ client: ClientId,
1253
+ file: string,
1254
+ serverName: string,
1255
+ saved: SavedMcpEntry,
1256
+ ): void {
1257
+ if (client === "codex") {
1258
+ if (saved.kind !== "codex") return;
1259
+ writeCodexBlock(file, serverName, saved.block);
1260
+ return;
1261
+ }
1262
+ if (saved.kind !== "json") return;
1263
+ writeJsonMcpEntryForClient(client, file, serverName, saved.entry);
1264
+ }
1265
+
1266
+ function unescapeTomlString(value: string): string {
1267
+ return value.replace(/\\"/g, '"').replace(/\\\\/g, "\\");
1268
+ }
1269
+
1270
+ function parseCodexHeaders(block: string): Record<string, string> {
1271
+ const line = block
1272
+ .split(/\r?\n/)
1273
+ .find((candidate) => /^\s*http_headers\s*=/.test(candidate));
1274
+ if (!line) return {};
1275
+ const match = line.match(/\{(.*)\}/);
1276
+ if (!match) return {};
1277
+ const headers: Record<string, string> = {};
1278
+ const pairRe = /"((?:\\.|[^"])*)"\s*=\s*"((?:\\.|[^"])*)"/g;
1279
+ let pair: RegExpExecArray | null;
1280
+ while ((pair = pairRe.exec(match[1]))) {
1281
+ headers[unescapeTomlString(pair[1])] = unescapeTomlString(pair[2]);
1282
+ }
1283
+ return headers;
1284
+ }
1285
+
1286
+ function savedEntryUrl(saved: SavedMcpEntry | undefined): string | undefined {
1287
+ if (!saved) return undefined;
1288
+ if (saved.kind === "json") {
1289
+ return typeof saved.entry.url === "string" ? saved.entry.url : undefined;
1290
+ }
1291
+ const match = saved.block.match(/^\s*url\s*=\s*"((?:\\.|[^"])*)"/m);
1292
+ return match ? unescapeTomlString(match[1]) : undefined;
1293
+ }
1294
+
1295
+ interface ExistingMcpEntry {
1296
+ client: ClientId;
1297
+ serverName: string;
1298
+ file: string;
1299
+ saved: SavedMcpEntry;
1300
+ url: string;
1301
+ }
1302
+
1303
+ function readJsonMcpServerEntries(
1304
+ client: ClientId,
1305
+ file: string,
1306
+ ): { serverName: string; saved: SavedMcpEntry }[] {
1307
+ try {
1308
+ const parsed = JSON.parse(fs.readFileSync(file, "utf-8"));
1309
+ const servers = parsed?.[jsonMcpConfigKeyForClient(client)];
1310
+ if (!servers || typeof servers !== "object" || Array.isArray(servers)) {
1311
+ return [];
1312
+ }
1313
+ return Object.entries(servers).flatMap(([serverName, entry]) => {
1314
+ if (!entry || typeof entry !== "object" || Array.isArray(entry)) {
1315
+ return [];
1316
+ }
1317
+ return [
1318
+ {
1319
+ serverName,
1320
+ saved: {
1321
+ kind: "json" as const,
1322
+ entry: entry as Record<string, unknown>,
1323
+ savedAt: new Date().toISOString(),
1324
+ },
1325
+ },
1326
+ ];
1327
+ });
1328
+ } catch {
1329
+ return [];
1330
+ }
1331
+ }
1332
+
1333
+ function parseCodexMcpServerName(line: string): string | undefined {
1334
+ const trimmed = line.trim();
1335
+ const quoted = trimmed.match(/^\[mcp_servers\."((?:\\.|[^"])*)"\]$/);
1336
+ if (quoted) return unescapeTomlString(quoted[1]);
1337
+ const bare = trimmed.match(/^\[mcp_servers\.([A-Za-z0-9_-]+)\]$/);
1338
+ return bare?.[1];
1339
+ }
1340
+
1341
+ function readCodexMcpServerEntries(
1342
+ file: string,
1343
+ ): { serverName: string; saved: SavedMcpEntry }[] {
1344
+ let content = "";
1345
+ try {
1346
+ content = fs.readFileSync(file, "utf-8");
1347
+ } catch {
1348
+ return [];
1349
+ }
1350
+ const lines = content.split(/\r?\n/);
1351
+ const entries: { serverName: string; saved: SavedMcpEntry }[] = [];
1352
+ for (let i = 0; i < lines.length; i++) {
1353
+ const serverName = parseCodexMcpServerName(lines[i]);
1354
+ if (!serverName) continue;
1355
+ const block: string[] = [lines[i]];
1356
+ i++;
1357
+ while (i < lines.length && !/^\s*\[/.test(lines[i])) {
1358
+ block.push(lines[i]);
1359
+ i++;
1360
+ }
1361
+ i--;
1362
+ entries.push({
1363
+ serverName,
1364
+ saved: {
1365
+ kind: "codex",
1366
+ block: block.join("\n").replace(/\n*$/, "") + "\n",
1367
+ savedAt: new Date().toISOString(),
1368
+ },
1369
+ });
1370
+ }
1371
+ return entries;
1372
+ }
1373
+
1374
+ function readExistingMcpEntries(
1375
+ clients: ClientId[],
1376
+ baseDir: string,
1377
+ scope: string,
1378
+ ): ExistingMcpEntry[] {
1379
+ const entries: ExistingMcpEntry[] = [];
1380
+ for (const client of clients) {
1381
+ const file = configPathFor(client, baseDir, scope);
1382
+ const rawEntries =
1383
+ client === "codex"
1384
+ ? readCodexMcpServerEntries(file)
1385
+ : readJsonMcpServerEntries(client, file);
1386
+ for (const { serverName, saved } of rawEntries) {
1387
+ const url = savedEntryUrl(saved);
1388
+ if (!url) continue;
1389
+ entries.push({ client, serverName, file, saved, url });
1390
+ }
1391
+ }
1392
+ return entries;
1393
+ }
1394
+
1395
+ function canonicalMcpUrl(value: string | undefined): string | undefined {
1396
+ if (!value) return undefined;
1397
+ try {
1398
+ const url = new URL(value);
1399
+ url.hash = "";
1400
+ const pathname = url.pathname.replace(/\/+$/, "");
1401
+ if (pathname === LEGACY_MCP_PATH || pathname.endsWith(LEGACY_MCP_PATH)) {
1402
+ url.pathname = `${pathname.slice(0, -LEGACY_MCP_PATH.length)}${MCP_PATH}`;
1403
+ }
1404
+ return url.toString().replace(/\/+$/, "");
1405
+ } catch {
1406
+ return undefined;
1407
+ }
1408
+ }
1409
+
1410
+ function mcpPathSuffix(pathname: string): string | undefined {
1411
+ const normalized = pathname.replace(/\/+$/, "");
1412
+ if (normalized === LEGACY_MCP_PATH || normalized.endsWith(LEGACY_MCP_PATH)) {
1413
+ return LEGACY_MCP_PATH;
1414
+ }
1415
+ if (normalized === MCP_PATH || normalized.endsWith(MCP_PATH)) return MCP_PATH;
1416
+ return undefined;
1417
+ }
1418
+
1419
+ function sameMcpUrl(a: string | undefined, b: string | undefined): boolean {
1420
+ const left = canonicalMcpUrl(a);
1421
+ const right = canonicalMcpUrl(b);
1422
+ return !!left && !!right && left === right;
1423
+ }
1424
+
1425
+ function savedEntryHeaders(
1426
+ saved: SavedMcpEntry | undefined,
1427
+ ): Record<string, string> {
1428
+ if (!saved) return {};
1429
+ if (saved.kind === "json") {
1430
+ const headers =
1431
+ saved.entry.headers ??
1432
+ (saved.entry.requestInit &&
1433
+ typeof saved.entry.requestInit === "object" &&
1434
+ !Array.isArray(saved.entry.requestInit)
1435
+ ? (saved.entry.requestInit as Record<string, unknown>).headers
1436
+ : undefined);
1437
+ return headers && typeof headers === "object"
1438
+ ? Object.fromEntries(
1439
+ Object.entries(headers as Record<string, unknown>)
1440
+ .filter((entry): entry is [string, string] => {
1441
+ return typeof entry[1] === "string";
1442
+ })
1443
+ .map(([key, value]) => [key, value]),
1444
+ )
1445
+ : {};
1446
+ }
1447
+ return parseCodexHeaders(saved.block);
1448
+ }
1449
+
1450
+ function isLoopbackMcpUrl(value: string | undefined): boolean {
1451
+ if (!value) return false;
1452
+ try {
1453
+ const url = new URL(value);
1454
+ return (
1455
+ url.hostname === "localhost" ||
1456
+ url.hostname === "127.0.0.1" ||
1457
+ url.hostname === "::1" ||
1458
+ url.hostname.startsWith("127.")
1459
+ );
1460
+ } catch {
1461
+ return false;
1462
+ }
1463
+ }
1464
+
1465
+ function decodeJwtSub(authHeader: string | undefined): string | undefined {
1466
+ if (!authHeader?.startsWith("Bearer ")) return undefined;
1467
+ const token = authHeader.slice("Bearer ".length);
1468
+ const [, payload] = token.split(".");
1469
+ if (!payload) return undefined;
1470
+ try {
1471
+ const normalized = payload.replace(/-/g, "+").replace(/_/g, "/");
1472
+ const padded = normalized.padEnd(
1473
+ normalized.length + ((4 - (normalized.length % 4)) % 4),
1474
+ "=",
1475
+ );
1476
+ const parsed = JSON.parse(Buffer.from(padded, "base64").toString("utf8"));
1477
+ return typeof parsed.sub === "string" && parsed.sub.includes("@")
1478
+ ? parsed.sub
1479
+ : undefined;
1480
+ } catch {
1481
+ return undefined;
1482
+ }
1483
+ }
1484
+
1485
+ function ownerEmailFromEntry(
1486
+ saved: SavedMcpEntry | undefined,
1487
+ ): string | undefined {
1488
+ const headers = savedEntryHeaders(saved);
1489
+ return (
1490
+ headers["X-Agent-Native-Owner-Email"] || decodeJwtSub(headers.Authorization)
1491
+ );
1492
+ }
1493
+
1494
+ function readEnvFile(file: string): string {
1495
+ try {
1496
+ return fs.readFileSync(file, "utf-8");
1497
+ } catch {
1498
+ return "";
1499
+ }
1500
+ }
1501
+
1502
+ function readEnvValue(content: string, key: string): string | undefined {
1503
+ let found: string | undefined;
1504
+ for (const line of content.split(/\r?\n/)) {
1505
+ const match = line.match(/^\s*([A-Z0-9_]+)\s*=\s*(.*)\s*$/i);
1506
+ if (match?.[1] === key) {
1507
+ found = match[2].replace(/^["']|["']$/g, "");
1508
+ }
1509
+ }
1510
+ return found;
1511
+ }
1512
+
1513
+ function workspaceEnvContent(baseDir: string): string {
1514
+ return (
1515
+ readEnvFile(path.join(baseDir, ".env.local")) +
1516
+ "\n" +
1517
+ readEnvFile(path.join(baseDir, ".env"))
1518
+ );
1519
+ }
1520
+
1521
+ function localAccessToken(baseDir: string): string | undefined {
1522
+ const content = workspaceEnvContent(baseDir);
1523
+ const single = readEnvValue(content, "ACCESS_TOKEN");
1524
+ if (single) return single;
1525
+ const multi = readEnvValue(content, "ACCESS_TOKENS");
1526
+ return multi
1527
+ ?.split(",")
1528
+ .map((token) => token.trim())
1529
+ .find(Boolean);
1530
+ }
1531
+
1532
+ function localA2ASecret(baseDir: string): string | undefined {
1533
+ return (
1534
+ process.env.A2A_SECRET ||
1535
+ readEnvValue(workspaceEnvContent(baseDir), "A2A_SECRET")
1536
+ );
1537
+ }
1538
+
1539
+ async function mintLocalA2AToken(
1540
+ ownerEmail: string | undefined,
1541
+ baseDir: string,
1542
+ ): Promise<string | undefined> {
1543
+ const secret = ownerEmail ? localA2ASecret(baseDir) : undefined;
1544
+ if (!secret) return undefined;
1545
+ const jose = await import("jose");
1546
+ return new jose.SignJWT({ sub: ownerEmail })
1547
+ .setProtectedHeader({ alg: "HS256" })
1548
+ .setIssuer("agent-native-connect-dev")
1549
+ .setIssuedAt()
1550
+ .setExpirationTime("30d")
1551
+ .sign(new TextEncoder().encode(secret));
1552
+ }
1553
+
1554
+ async function devHeadersForApp(params: {
1555
+ ownerEmail?: string;
1556
+ sourceEntry?: SavedMcpEntry;
1557
+ baseDir: string;
1558
+ }): Promise<Record<string, string> | undefined> {
1559
+ const ownerEmail =
1560
+ params.ownerEmail ||
1561
+ process.env.AGENT_NATIVE_OWNER_EMAIL ||
1562
+ ownerEmailFromEntry(params.sourceEntry);
1563
+ const headers: Record<string, string> = {};
1564
+ const accessToken = localAccessToken(params.baseDir);
1565
+ const a2aToken = accessToken
1566
+ ? undefined
1567
+ : await mintLocalA2AToken(ownerEmail, params.baseDir);
1568
+ if (accessToken || a2aToken) {
1569
+ headers.Authorization = `Bearer ${accessToken || a2aToken}`;
1570
+ }
1571
+ if (ownerEmail) {
1572
+ headers["X-Agent-Native-Owner-Email"] = ownerEmail;
1573
+ }
1574
+ // Local dev defaults to the compact/connector catalog + tool-search, same as
1575
+ // every other client. The local server still honors AGENT_NATIVE_MCP_FULL_CATALOG=1
1576
+ // for an explicit full-catalog opt-in, so we don't force the header here.
1577
+ return Object.keys(headers).length ? headers : undefined;
1578
+ }
1579
+
1580
+ function connectableApps(includeHidden = false): ConnectableApp[] {
1581
+ const source = includeHidden ? TEMPLATES : visibleTemplates();
1582
+ return source
1583
+ .filter((template) => typeof template.prodUrl === "string")
1584
+ .map((template) => ({
1585
+ name: template.name,
1586
+ label: template.label,
1587
+ url: template.prodUrl as string,
1588
+ core: !!template.core,
1589
+ }));
1590
+ }
1591
+
1592
+ function profileDefaultApps(): ConnectableApp[] {
1593
+ const core = connectableApps(false).filter((app) => app.core);
1594
+ return core.length ? core : connectableApps(false);
1595
+ }
1596
+
1597
+ function parseAppsList(value: string | undefined): string[] {
1598
+ return (value ?? "")
1599
+ .split(",")
1600
+ .map((app) => app.trim())
1601
+ .filter(Boolean);
1602
+ }
1603
+
1604
+ async function resolveProfileApps(
1605
+ parsed: ParsedConnectArgs,
1606
+ deps: ConnectDeps,
1607
+ ): Promise<ConnectableApp[] | null> {
1608
+ const allVisible = connectableApps(false);
1609
+ const allIncludingHidden = connectableApps(true);
1610
+
1611
+ if (parsed.apps) {
1612
+ const requested = parseAppsList(parsed.apps);
1613
+ if (requested.includes("all")) return allVisible;
1614
+ const byName = new Map(allIncludingHidden.map((app) => [app.name, app]));
1615
+ const unknown = requested.filter((name) => !byName.has(name));
1616
+ if (unknown.length) {
1617
+ throw new Error(
1618
+ `Unknown app(s): ${unknown.join(", ")}. Known apps: ${allIncludingHidden
1619
+ .map((app) => app.name)
1620
+ .join(", ")}`,
1621
+ );
1622
+ }
1623
+ return requested.map((name) => byName.get(name)!);
1624
+ }
1625
+
1626
+ if (parsed.all) return allVisible;
1627
+
1628
+ if (shouldPrompt(deps)) {
1629
+ const prompt = deps.promptHostedApps ?? promptForHostedApps;
1630
+ const initialApps = profileDefaultApps().map((app) => app.name);
1631
+ const selectedNames = normalizeHostedAppNames(
1632
+ await prompt({ apps: allVisible, initialApps }),
1633
+ allVisible,
1634
+ );
1635
+ if (selectedNames.length === 0) return [];
1636
+ const selected = new Set(selectedNames);
1637
+ return allVisible.filter((app) => selected.has(app.name));
1638
+ }
1639
+
1640
+ return profileDefaultApps();
1641
+ }
1642
+
1643
+ function defaultDevGateway(): string {
1644
+ if (process.env.WORKSPACE_GATEWAY_URL)
1645
+ return process.env.WORKSPACE_GATEWAY_URL;
1646
+ const port = process.env.WORKSPACE_PORT || process.env.PORT;
1647
+ return port ? `http://127.0.0.1:${port}` : DEFAULT_DEV_GATEWAY;
1648
+ }
1649
+
1650
+ function normalizeDevGateway(parsed: ParsedConnectArgs): string {
1651
+ const raw =
1652
+ parsed.gateway ||
1653
+ (Number.isFinite(parsed.port) && parsed.port
1654
+ ? `http://127.0.0.1:${parsed.port}`
1655
+ : defaultDevGateway());
1656
+ const normalized = normalizeUrl(raw);
1657
+ return normalized.replace(/\/+$/, "");
1658
+ }
1659
+
1660
+ async function gatewayAppUrls(
1661
+ gatewayUrl: string,
1662
+ deps: ConnectDeps,
1663
+ ): Promise<Map<string, string>> {
1664
+ const out = new Map<string, string>();
1665
+ const fetchImpl = deps.fetchImpl ?? fetch;
1666
+ try {
1667
+ const response = await fetchImpl(`${gatewayUrl}/_workspace/apps`, {
1668
+ signal: AbortSignal.timeout(1200),
1669
+ });
1670
+ if (!response.ok) return out;
1671
+ const apps = (await response.json()) as unknown;
1672
+ if (!Array.isArray(apps)) return out;
1673
+ for (const app of apps) {
1674
+ if (!app || typeof app !== "object") continue;
1675
+ const id = (app as { id?: unknown }).id;
1676
+ const url = (app as { url?: unknown }).url;
1677
+ if (typeof id === "string" && typeof url === "string") {
1678
+ out.set(id, normalizeUrl(url));
1679
+ }
1680
+ }
1681
+ } catch {
1682
+ // The gateway may not be running yet; still write deterministic dev URLs.
1683
+ }
1684
+ return out;
1685
+ }
1686
+
1687
+ function devMcpUrl(
1688
+ app: ConnectableApp,
1689
+ gatewayUrl: string,
1690
+ gatewayUrls: Map<string, string>,
1691
+ ): string {
1692
+ const base = gatewayUrls.get(app.name) ?? `${gatewayUrl}/${app.name}`;
1693
+ return `${base.replace(/\/+$/, "")}${MCP_PATH}`;
1694
+ }
1695
+
1696
+ function serverNameForApp(app: ConnectableApp): string {
1697
+ return `${SERVER_NAME_PREFIX}-${app.name}`;
1698
+ }
1699
+
1700
+ async function connectDevProfile(
1701
+ parsed: ParsedConnectArgs,
1702
+ clients: ClientId[],
1703
+ deps: ConnectDeps,
1704
+ ): Promise<boolean> {
1705
+ const apps = await resolveProfileApps(parsed, deps);
1706
+ if (!apps || apps.length === 0) return true;
1707
+
1708
+ const baseDir = projectBaseDir();
1709
+ const scope = parsed.scope === "project" ? "project" : "user";
1710
+ const gatewayUrl = normalizeDevGateway(parsed);
1711
+ const gatewayUrls = await gatewayAppUrls(gatewayUrl, deps);
1712
+ const profilesFile = deps.profilesFile ?? connectProfilesPath();
1713
+ const profiles = readConnectProfiles(profilesFile);
1714
+ const rows: { app: string; client: string; status: string; file: string }[] =
1715
+ [];
1716
+ const ownerWarnings = new Set<string>();
1717
+
1718
+ for (const app of apps) {
1719
+ const serverName = serverNameForApp(app);
1720
+ const mcpUrl = devMcpUrl(app, gatewayUrl, gatewayUrls);
1721
+
1722
+ for (const client of clients) {
1723
+ const current = readCurrentMcpEntry(client, serverName, baseDir, scope);
1724
+ const backup = savedProfileEntry(
1725
+ profiles,
1726
+ serverName,
1727
+ client,
1728
+ current.file,
1729
+ );
1730
+ if (current.saved && !isLoopbackMcpUrl(savedEntryUrl(current.saved))) {
1731
+ setSavedProfileEntry(
1732
+ profiles,
1733
+ serverName,
1734
+ client,
1735
+ current.file,
1736
+ current.saved,
1737
+ );
1738
+ }
1739
+ const sourceEntry =
1740
+ current.saved && !isLoopbackMcpUrl(savedEntryUrl(current.saved))
1741
+ ? current.saved
1742
+ : backup;
1743
+ const headers = await devHeadersForApp({
1744
+ ownerEmail: parsed.ownerEmail,
1745
+ sourceEntry,
1746
+ baseDir,
1747
+ });
1748
+ if (!headers?.["X-Agent-Native-Owner-Email"]) {
1749
+ ownerWarnings.add(app.name);
1750
+ }
1751
+ const file = writeHttpEntryForClient(
1752
+ client,
1753
+ serverName,
1754
+ mcpUrl,
1755
+ undefined,
1756
+ baseDir,
1757
+ scope,
1758
+ headers,
1759
+ );
1760
+ rows.push({
1761
+ app: app.name,
1762
+ client,
1763
+ status: "dev",
1764
+ file,
1765
+ });
1766
+ }
1767
+ }
1768
+
1769
+ writeConnectProfiles(profilesFile, profiles);
1770
+
1771
+ logOut("");
1772
+ logOut(` Switched ${apps.length} app(s) to dev via ${gatewayUrl}`);
1773
+ for (const row of rows) {
1774
+ logOut(` ${row.app.padEnd(12)} ${row.client.padEnd(18)} ${row.file}`);
1775
+ }
1776
+ if (ownerWarnings.size) {
1777
+ logOut("");
1778
+ logOut(
1779
+ ` Tip: pass --owner-email <you@example.com> if local tools look sparse ` +
1780
+ `for ${Array.from(ownerWarnings).join(", ")}.`,
1781
+ );
1782
+ }
1783
+ logOut("");
1784
+ logOut(" Restart your coding agent to pick up the dev MCP servers.");
1785
+ return true;
1786
+ }
1787
+
1788
+ async function connectProdProfile(
1789
+ parsed: ParsedConnectArgs,
1790
+ clients: ClientId[],
1791
+ deps: ConnectDeps,
1792
+ ): Promise<boolean> {
1793
+ const apps = await resolveProfileApps(parsed, deps);
1794
+ if (!apps || apps.length === 0) return true;
1795
+
1796
+ const baseDir = projectBaseDir();
1797
+ const scope = parsed.scope === "project" ? "project" : "user";
1798
+ const profilesFile = deps.profilesFile ?? connectProfilesPath();
1799
+ const profiles = readConnectProfiles(profilesFile);
1800
+ const restored: { app: string; client: string; file: string }[] = [];
1801
+ const missing: { app: string; client: string }[] = [];
1802
+
1803
+ for (const app of apps) {
1804
+ const serverName = serverNameForApp(app);
1805
+ for (const client of clients) {
1806
+ const file = configPathFor(client, baseDir, scope);
1807
+ const saved = savedProfileEntry(profiles, serverName, client, file);
1808
+ if (!saved) {
1809
+ missing.push({ app: app.name, client });
1810
+ continue;
1811
+ }
1812
+ writeSavedMcpEntry(client, file, serverName, saved);
1813
+ restored.push({ app: app.name, client, file });
1814
+ }
1815
+ }
1816
+
1817
+ logOut("");
1818
+ if (restored.length) {
1819
+ logOut(
1820
+ ` Restored ${restored.length} production MCP entr${restored.length === 1 ? "y" : "ies"}.`,
1821
+ );
1822
+ for (const row of restored) {
1823
+ logOut(` ${row.app.padEnd(12)} ${row.client.padEnd(18)} ${row.file}`);
1824
+ }
1825
+ }
1826
+ if (missing.length) {
1827
+ logOut("");
1828
+ logOut(" No saved production entry for:");
1829
+ for (const row of missing) {
1830
+ const app = apps.find((candidate) => candidate.name === row.app);
1831
+ logOut(
1832
+ ` ${row.app.padEnd(12)} ${row.client.padEnd(18)} ` +
1833
+ `run: npx @agent-native/core@latest connect ${app?.url ?? "<url>"} --client ${row.client}`,
1834
+ );
1835
+ }
1836
+ }
1837
+ logOut("");
1838
+ logOut(" Restart your coding agent to pick up the production MCP servers.");
1839
+ return missing.length === 0;
1840
+ }
1841
+
1842
+ // ---------------------------------------------------------------------------
1843
+ // Single-app connect
1844
+ // ---------------------------------------------------------------------------
1845
+
1846
+ interface ReconnectTarget {
1847
+ rawUrl: string;
1848
+ serverName?: string;
1849
+ clients?: ClientId[];
1850
+ }
1851
+
1852
+ function distinctReconnectEntries(
1853
+ entries: ExistingMcpEntry[],
1854
+ ): ExistingMcpEntry[] {
1855
+ const seen = new Set<string>();
1856
+ const out: ExistingMcpEntry[] = [];
1857
+ for (const entry of entries) {
1858
+ const key = `${entry.serverName}\0${canonicalMcpUrl(entry.url) ?? entry.url}`;
1859
+ if (seen.has(key)) continue;
1860
+ seen.add(key);
1861
+ out.push(entry);
1862
+ }
1863
+ return out;
1864
+ }
1865
+
1866
+ function uniqueClients(entries: ExistingMcpEntry[]): ClientId[] {
1867
+ return [...new Set(entries.map((entry) => entry.client))];
1868
+ }
1869
+
1870
+ function preferredReconnectEntry(
1871
+ url: string,
1872
+ entries: ExistingMcpEntry[],
1873
+ ): ExistingMcpEntry | undefined {
1874
+ const canonicalName = CANONICAL_SERVER_NAME_BY_MCP_URL[url];
1875
+ return (
1876
+ (canonicalName
1877
+ ? entries.find((entry) => entry.serverName === canonicalName)
1878
+ : undefined) ??
1879
+ entries.find((entry) => !entry.serverName.startsWith("agent-native-")) ??
1880
+ entries[0]
1881
+ );
1882
+ }
1883
+
1884
+ /**
1885
+ * Return true when `url` is an agent-native MCP endpoint.
1886
+ * Matches either the public `/mcp` path or the legacy `/_agent-native/mcp`
1887
+ * path, regardless of the MCP server's name in the config.
1888
+ */
1889
+ function isAgentNativeMcpUrl(url: string | undefined): boolean {
1890
+ if (!url) return false;
1891
+ try {
1892
+ return Boolean(mcpPathSuffix(new URL(url).pathname));
1893
+ } catch {
1894
+ return false;
1895
+ }
1896
+ }
1897
+
1898
+ async function resolveReconnectTarget(
1899
+ parsed: ParsedConnectArgs,
1900
+ clients: ClientId[],
1901
+ deps: ConnectDeps,
1902
+ ): Promise<ReconnectTarget | null> {
1903
+ const baseDir = projectBaseDir();
1904
+ const scope = parsed.scope === "user" ? "user" : "project";
1905
+ const entries = readExistingMcpEntries(clients, baseDir, scope);
1906
+
1907
+ if (parsed.url) {
1908
+ const normalizedUrl = normalizeUrl(parsed.url);
1909
+ const mcpUrl = mcpUrlForBaseUrl(normalizedUrl);
1910
+ const matches = distinctReconnectEntries(
1911
+ entries.filter((entry) => sameMcpUrl(entry.url, mcpUrl)),
1912
+ );
1913
+
1914
+ if (matches.length === 0) {
1915
+ logErr(` No existing Agent Native MCP entry found for ${mcpUrl}.`);
1916
+ logErr(
1917
+ " First-time setup still uses: npx @agent-native/core@latest connect <url> --client <client>",
1918
+ );
1919
+ return null;
1920
+ }
1921
+
1922
+ if (parsed.name) {
1923
+ const namedMatches = matches.filter(
1924
+ (entry) => entry.serverName === parsed.name,
1925
+ );
1926
+ if (namedMatches.length === 0) {
1927
+ logErr(
1928
+ ` No existing MCP entry named "${parsed.name}" found for ${mcpUrl}.`,
1929
+ );
1930
+ logErr(" Re-run without --name to use the existing entry name.");
1931
+ return null;
1932
+ }
1933
+ return {
1934
+ rawUrl: parsed.url,
1935
+ serverName: parsed.name,
1936
+ clients: uniqueClients(namedMatches),
1937
+ };
1938
+ }
1939
+
1940
+ const key = canonicalMcpUrl(mcpUrl) ?? mcpUrl;
1941
+ const preferred = preferredReconnectEntry(key, matches);
1942
+ if (preferred) {
1943
+ const names = [...new Set(matches.map((entry) => entry.serverName))];
1944
+ if (names.length > 1) {
1945
+ logOut(
1946
+ ` Found duplicate MCP entries for ${mcpUrl}: ${names.join(", ")}.`,
1947
+ );
1948
+ logOut(
1949
+ ` Reconnecting "${preferred.serverName}" and removing the duplicate names.`,
1950
+ );
1951
+ }
1952
+ return {
1953
+ rawUrl: parsed.url,
1954
+ serverName:
1955
+ reconnectServerNameForMcpUrl(mcpUrl, preferred.serverName) ??
1956
+ preferred.serverName,
1957
+ clients: uniqueClients(matches),
1958
+ };
1959
+ }
1960
+
1961
+ const names = [...new Set(matches.map((entry) => entry.serverName))];
1962
+ if (names.length > 1) {
1963
+ logErr(
1964
+ ` Found multiple MCP entries for ${mcpUrl}: ${names.join(", ")}.`,
1965
+ );
1966
+ logErr(" Re-run with --name <serverName> to choose one.");
1967
+ return null;
1968
+ }
1969
+ return {
1970
+ rawUrl: parsed.url,
1971
+ serverName: names[0],
1972
+ clients: uniqueClients(matches),
1973
+ };
1974
+ }
1975
+
1976
+ // No URL provided: scan all configs for agent-native MCP entries by URL
1977
+ // pattern, not by server name prefix. This finds the canonical "plan" entry
1978
+ // (and any other custom-named entries) that the old prefix scan missed.
1979
+ const agentNativeEntries = distinctReconnectEntries(
1980
+ parsed.name
1981
+ ? entries.filter((entry) => entry.serverName === parsed.name)
1982
+ : entries.filter((entry) => isAgentNativeMcpUrl(entry.url)),
1983
+ );
1984
+
1985
+ // Group by normalised URL so we can detect multi-app situations.
1986
+ const byUrl = new Map<string, ExistingMcpEntry[]>();
1987
+ for (const entry of agentNativeEntries) {
1988
+ const key = canonicalMcpUrl(entry.url) ?? entry.url;
1989
+ const bucket = byUrl.get(key) ?? [];
1990
+ bucket.push(entry);
1991
+ byUrl.set(key, bucket);
1992
+ }
1993
+
1994
+ if (byUrl.size === 0) {
1995
+ logErr(" No existing Agent Native MCP entry found to reconnect.");
1996
+ logErr(
1997
+ " Pass a URL, or use --name <serverName> if the entry has a custom name.",
1998
+ );
1999
+ logErr(
2000
+ " First-time setup still uses: npx @agent-native/core@latest connect <url> --client <client>",
2001
+ );
2002
+ return null;
2003
+ }
2004
+
2005
+ if (byUrl.size === 1) {
2006
+ // Exactly one distinct URL: prefer the entry whose serverName matches the
2007
+ // canonical name for this app (e.g. "plan" over "agent-native-plans").
2008
+ // Fall back to any entry whose name doesn't start with "agent-native-"
2009
+ // (short canonical names like "plan"), then bucket[0].
2010
+ const [url, bucket] = [...byUrl.entries()][0];
2011
+ const preferred = preferredReconnectEntry(url, bucket) ?? bucket[0];
2012
+ return {
2013
+ rawUrl: preferred.url,
2014
+ serverName:
2015
+ reconnectServerNameForMcpUrl(preferred.url, preferred.serverName) ??
2016
+ preferred.serverName,
2017
+ clients: uniqueClients(bucket),
2018
+ };
2019
+ }
2020
+
2021
+ // Multiple distinct URLs: pick interactively when TTY, else list with hints.
2022
+ const urlList = [...byUrl.keys()];
2023
+ if (shouldPrompt(deps)) {
2024
+ const clack = await import("@clack/prompts");
2025
+ const result = await clack.select<
2026
+ { value: string; label: string; hint: string }[],
2027
+ string
2028
+ >({
2029
+ message:
2030
+ "Multiple Agent Native apps found. Which one do you want to reconnect?",
2031
+ options: urlList.map((u) => {
2032
+ const representativeEntry = byUrl.get(u)![0];
2033
+ return {
2034
+ value: u,
2035
+ label: representativeEntry.serverName,
2036
+ hint: u,
2037
+ };
2038
+ }),
2039
+ });
2040
+ if (clack.isCancel(result)) {
2041
+ clack.cancel("Cancelled.");
2042
+ return null;
2043
+ }
2044
+ const bucket = byUrl.get(result as string);
2045
+ const chosen = bucket
2046
+ ? (preferredReconnectEntry(result as string, bucket) ?? bucket[0])
2047
+ : undefined;
2048
+ if (!chosen || !bucket) return null;
2049
+ return {
2050
+ rawUrl: chosen.url,
2051
+ serverName:
2052
+ reconnectServerNameForMcpUrl(chosen.url, chosen.serverName) ??
2053
+ chosen.serverName,
2054
+ clients: uniqueClients(bucket),
2055
+ };
2056
+ }
2057
+
2058
+ logErr(" Found multiple Agent Native MCP entries:");
2059
+ for (const [u, bucket] of byUrl) {
2060
+ logErr(` ${bucket[0].serverName} → ${u}`);
2061
+ }
2062
+ logErr(" Re-run with a URL or --name <serverName>. For example:");
2063
+ for (const u of urlList) {
2064
+ // Strip the MCP path suffix for a cleaner reconnect URL suggestion.
2065
+ const baseUrl = stripMcpPath(u);
2066
+ logErr(` npx -y @agent-native/core@latest reconnect ${baseUrl}`);
2067
+ }
2068
+ return null;
2069
+ }
2070
+
2071
+ async function reconnectOne(
2072
+ parsed: ParsedConnectArgs,
2073
+ clients: ClientId[],
2074
+ deps: ConnectDeps,
2075
+ ): Promise<boolean> {
2076
+ const target = await resolveReconnectTarget(parsed, clients, deps);
2077
+ if (!target) return false;
2078
+ const effectiveParsed: ParsedConnectArgs = {
2079
+ ...parsed,
2080
+ url: target.rawUrl,
2081
+ name: target.serverName ?? parsed.name,
2082
+ };
2083
+ const effectiveClients = target.clients?.length ? target.clients : clients;
2084
+ logOut("");
2085
+ logOut(
2086
+ ` Reconnecting${effectiveParsed.name ? ` "${effectiveParsed.name}"` : ""}...`,
2087
+ );
2088
+ const res = await connectOne(
2089
+ target.rawUrl,
2090
+ effectiveParsed,
2091
+ effectiveClients,
2092
+ deps,
2093
+ );
2094
+ const skippedClients = clientsNotIn(clients, effectiveClients);
2095
+ if (res.ok && skippedClients.length > 0) {
2096
+ const baseUrl = stripMcpPath(normalizeUrl(target.rawUrl));
2097
+ logOut("");
2098
+ logOut(
2099
+ ` Reconnected existing client configs for ${clientLabelList(effectiveClients)}.`,
2100
+ );
2101
+ logOut(
2102
+ ` Did not touch ${clientLabelList(skippedClients)} because no matching MCP entry was found.`,
2103
+ );
2104
+ logOut(
2105
+ ` To add another client, run: npx @agent-native/core@latest connect ${baseUrl} --client CLIENT --scope ${effectiveParsed.scope}`,
2106
+ );
2107
+ }
2108
+ if (res.ok) {
2109
+ await showReconnectSuccessOutro({
2110
+ serverName: res.serverName ?? effectiveParsed.name,
2111
+ clients: effectiveClients,
2112
+ });
2113
+ }
2114
+ return res.ok;
2115
+ }
2116
+
2117
+ async function connectOne(
2118
+ rawUrl: string,
2119
+ parsed: ParsedConnectArgs,
2120
+ clients: ClientId[],
2121
+ deps: ConnectDeps,
2122
+ ): Promise<{ ok: boolean; serverName?: string; files?: string[] }> {
2123
+ const normalizedUrl = normalizeUrl(rawUrl);
2124
+ const baseUrl = stripMcpPath(normalizedUrl);
2125
+ const normalizedMcpUrl = mcpUrlForBaseUrl(normalizedUrl);
2126
+ const appSlug = appSlugFromUrl(baseUrl);
2127
+ const scope = parsed.scope === "user" ? "user" : "project";
2128
+ const baseDir = projectBaseDir();
2129
+ const allWritten: { client: ClientId; file: string }[] = [];
2130
+ let oauthClients = parsed.token
2131
+ ? []
2132
+ : clients.filter((client) => supportsRemoteMcpOAuth(client));
2133
+ let deviceFlowClients = parsed.token
2134
+ ? clients
2135
+ : clients.filter((client) => !supportsRemoteMcpOAuth(client));
2136
+ const oauthMigrations: ClientId[] = [];
2137
+
2138
+ let token: string | undefined;
2139
+ let mcpUrl: string;
2140
+ let serverName: string;
2141
+ let headers: Record<string, string> | undefined;
2142
+
2143
+ if (parsed.token) {
2144
+ // No-browser fallback: skip the device flow entirely.
2145
+ token = parsed.token;
2146
+ mcpUrl = normalizedMcpUrl;
2147
+ serverName = parsed.name ?? defaultServerName(baseUrl);
2148
+ logOut("");
2149
+ logOut(` Using supplied --token for ${baseUrl} (skipping browser flow).`);
2150
+ } else if (deviceFlowClients.length === 0) {
2151
+ token = undefined;
2152
+ mcpUrl = normalizedMcpUrl;
2153
+ serverName = parsed.name ?? defaultServerName(baseUrl);
2154
+ } else {
2155
+ const grant = await runDeviceFlow(
2156
+ baseUrl,
2157
+ appSlug,
2158
+ clientArgForDeviceFlow(deviceFlowClients),
2159
+ deps,
2160
+ { fullCatalog: parsed.fullCatalog },
2161
+ );
2162
+ if (!grant) return { ok: false };
2163
+ token = grant.token;
2164
+ mcpUrl = grant.mcpUrl;
2165
+ serverName =
2166
+ parsed.name ??
2167
+ reconnectServerNameForMcpUrl(grant.mcpUrl, grant.serverName) ??
2168
+ grant.serverName ??
2169
+ defaultServerName(baseUrl);
2170
+ headers = grant.headers;
2171
+ }
2172
+
2173
+ if (oauthClients.length > 0 && !parsed.token) {
2174
+ if (!(await validateOAuthMcpServer(baseUrl, mcpUrl, deps))) {
2175
+ if (parsed.mode !== "reconnect") {
2176
+ return { ok: false };
2177
+ }
2178
+
2179
+ logOut("");
2180
+ logOut(
2181
+ ` OAuth metadata was unavailable; falling back to bearer-token reconnect for ${clientLabelList(
2182
+ oauthClients,
2183
+ )}.`,
2184
+ );
2185
+
2186
+ if (!token) {
2187
+ const grant = await runDeviceFlow(
2188
+ baseUrl,
2189
+ appSlug,
2190
+ clientArgForDeviceFlow(oauthClients),
2191
+ deps,
2192
+ { fullCatalog: parsed.fullCatalog },
2193
+ );
2194
+ if (!grant) return { ok: false };
2195
+ token = grant.token;
2196
+ mcpUrl = grant.mcpUrl;
2197
+ serverName =
2198
+ parsed.name ??
2199
+ reconnectServerNameForMcpUrl(grant.mcpUrl, grant.serverName) ??
2200
+ grant.serverName ??
2201
+ defaultServerName(baseUrl);
2202
+ headers = grant.headers;
2203
+ }
2204
+
2205
+ deviceFlowClients = [...deviceFlowClients, ...oauthClients];
2206
+ oauthClients = [];
2207
+ }
2208
+ }
2209
+
2210
+ if (deviceFlowClients.length > 0) {
2211
+ allWritten.push(
2212
+ ...writeConfigs(
2213
+ deviceFlowClients,
2214
+ serverName,
2215
+ mcpUrl,
2216
+ token,
2217
+ scope,
2218
+ baseDir,
2219
+ headers,
2220
+ ),
2221
+ );
2222
+ }
2223
+
2224
+ if (oauthClients.length > 0) {
2225
+ for (const client of oauthClients) {
2226
+ const current = readCurrentMcpEntry(client, serverName, baseDir, scope);
2227
+ const currentHeaders = savedEntryHeaders(current.saved);
2228
+ if (typeof currentHeaders.Authorization === "string") {
2229
+ oauthMigrations.push(client);
2230
+ }
2231
+ }
2232
+ allWritten.push(
2233
+ ...writeConfigs(
2234
+ oauthClients,
2235
+ serverName,
2236
+ mcpUrl,
2237
+ undefined,
2238
+ scope,
2239
+ baseDir,
2240
+ undefined,
2241
+ ),
2242
+ );
2243
+ }
2244
+
2245
+ // After writing the canonical entry, remove any same-URL duplicates (alias
2246
+ // names, legacy default names, stale custom names) from the same config
2247
+ // files so each app has exactly one MCP session.
2248
+ const allRemovedNames: string[] = [];
2249
+ for (const client of clients) {
2250
+ const removed = removeSameUrlDuplicatesForClient(
2251
+ client,
2252
+ serverName,
2253
+ mcpUrl,
2254
+ baseDir,
2255
+ scope,
2256
+ );
2257
+ allRemovedNames.push(...removed);
2258
+ }
2259
+ if (allRemovedNames.length > 0) {
2260
+ logOut(
2261
+ ` Removed duplicate MCP entries: ${[...new Set(allRemovedNames)].join(", ")}`,
2262
+ );
2263
+ }
2264
+
2265
+ // Canonical publish-token write: when we have a real minted bearer token for
2266
+ // a first-party Plans app, also persist `{ url, token }` to
2267
+ // `~/.agent-native/plan-publish.json` so the local Plans server can read the
2268
+ // same token for a server-to-server publish (publish-on-share). This is an
2269
+ // ADDITIONAL write alongside the per-client MCP config; Best-effort and
2270
+ // merge-not-clobber — never fails the connect.
2271
+ //
2272
+ // OAuth clients authenticate in-host via standard MCP OAuth, so they never
2273
+ // mint a local bearer token. To still populate the publish store for them, we
2274
+ // run a supplemental device-flow mint using a non-OAuth client arg so the
2275
+ // Plans server gets a usable token and `publish-visual-plan` doesn't send the
2276
+ // user back to `agent-native connect` right after they just ran it.
2277
+ let publishToken = token;
2278
+ if (
2279
+ !publishToken &&
2280
+ oauthClients.length > 0 &&
2281
+ isFirstPartyPlanHost(baseUrl)
2282
+ ) {
2283
+ try {
2284
+ logOut("");
2285
+ logOut(
2286
+ ` Minting a publish token for the local Plans server (device flow)…`,
2287
+ );
2288
+ const grant = await runDeviceFlow(
2289
+ baseUrl,
2290
+ appSlug,
2291
+ // Use a non-OAuth client arg so the server mints a bearer token even
2292
+ // though our primary clients are OAuth-native. "codex" is a stable,
2293
+ // always-supported non-OAuth client identifier.
2294
+ "codex",
2295
+ deps,
2296
+ );
2297
+ if (grant?.token) {
2298
+ publishToken = grant.token;
2299
+ } else {
2300
+ logOut(
2301
+ ` Warning: could not mint a publish token for the local Plans ` +
2302
+ `server. You can still publish via the hosted UI.`,
2303
+ );
2304
+ }
2305
+ } catch {
2306
+ logOut(
2307
+ ` Warning: publish-token mint failed. You can still publish via the ` +
2308
+ `hosted UI.`,
2309
+ );
2310
+ }
2311
+ }
2312
+ if (publishToken && isFirstPartyPlanHost(baseUrl)) {
2313
+ const canonicalPath = writePlanPublishAuth({
2314
+ url: baseUrl,
2315
+ token: publishToken,
2316
+ });
2317
+ if (canonicalPath) {
2318
+ logOut("");
2319
+ logOut(
2320
+ ` Saved publish token for the local Plans server → ${canonicalPath}`,
2321
+ );
2322
+ }
2323
+ }
2324
+
2325
+ logOut("");
2326
+ logOut(` Configured "${serverName}" → ${mcpUrl}`);
2327
+ for (const w of allWritten) {
2328
+ logOut(` ${w.client.padEnd(18)} ${w.file}`);
2329
+ }
2330
+ logOut(
2331
+ ` Auth/config is per client: this command updated ${clientLabelList(clients)} only.`,
2332
+ );
2333
+ if (oauthClients.length > 0 && !parsed.token) {
2334
+ logOut("");
2335
+ if (oauthMigrations.length > 0) {
2336
+ logOut(
2337
+ ` Replaced legacy bearer headers for ${clientLabelList(
2338
+ oauthMigrations,
2339
+ )}; it will reconnect with standard MCP OAuth.`,
2340
+ );
2341
+ }
2342
+ logOut(
2343
+ ` ${clientLabelList(
2344
+ oauthClients,
2345
+ )}: wrote URL-only MCP config (no bearer headers).`,
2346
+ );
2347
+ for (const line of oauthNextStepsForClients(oauthClients, serverName)) {
2348
+ logOut(` Next: ${line}`);
2349
+ }
2350
+ }
2351
+ logOut("");
2352
+ logOut(
2353
+ ` Restart or reload ${sentenceClientLabelList(clients)} to pick up the new MCP server.`,
2354
+ );
2355
+ if (clients.includes("codex")) {
2356
+ logOut(
2357
+ " Codex sessions load MCP tools at startup; start a new Codex session if the tools are still missing.",
2358
+ );
2359
+ }
2360
+ return { ok: true, serverName, files: allWritten.map((w) => w.file) };
2361
+ }
2362
+
2363
+ // ---------------------------------------------------------------------------
2364
+ // --all : connect every first-party hosted app
2365
+ // ---------------------------------------------------------------------------
2366
+
2367
+ /** Hosted first-party apps: visible (non-hidden) templates with a prodUrl. */
2368
+ export function hostedApps(): HostedApp[] {
2369
+ return visibleTemplates()
2370
+ .filter((t) => typeof t.prodUrl === "string" && t.prodUrl.length > 0)
2371
+ .map((t) => ({
2372
+ name: t.name,
2373
+ label: t.label,
2374
+ url: t.prodUrl as string,
2375
+ }));
2376
+ }
2377
+
2378
+ async function connectApps(
2379
+ apps: HostedApp[],
2380
+ parsed: ParsedConnectArgs,
2381
+ clients: ClientId[],
2382
+ deps: ConnectDeps,
2383
+ ): Promise<boolean> {
2384
+ if (apps.length === 0) {
2385
+ logErr(" No hosted first-party apps found in the template registry.");
2386
+ return false;
2387
+ }
2388
+ logOut("");
2389
+ logOut(` Connecting ${apps.length} first-party hosted apps…`);
2390
+
2391
+ const results: { name: string; status: string; files: string[] }[] = [];
2392
+ for (const app of apps) {
2393
+ logOut("");
2394
+ logOut(` ── ${app.label} (${app.url}) ──`);
2395
+ try {
2396
+ const res = await connectOne(app.url, parsed, clients, deps);
2397
+ results.push({
2398
+ name: app.label,
2399
+ status: res.ok ? "connected" : "skipped",
2400
+ files: res.files ?? [],
2401
+ });
2402
+ } catch (err: any) {
2403
+ logErr(` ${app.name}: ${err?.message ?? err}`);
2404
+ results.push({ name: app.name, status: "error", files: [] });
2405
+ }
2406
+ }
2407
+
2408
+ logOut("");
2409
+ logOut(" Summary");
2410
+ for (const r of results) {
2411
+ const files = r.files.length ? r.files.join(", ") : "—";
2412
+ logOut(` ${r.name.padEnd(14)} ${r.status.padEnd(10)} ${files}`);
2413
+ }
2414
+ return results.every((r) => r.status === "connected");
2415
+ }
2416
+
2417
+ async function connectAll(
2418
+ parsed: ParsedConnectArgs,
2419
+ clients: ClientId[],
2420
+ deps: ConnectDeps,
2421
+ ): Promise<boolean> {
2422
+ return connectApps(hostedApps(), parsed, clients, deps);
2423
+ }
2424
+
2425
+ // ---------------------------------------------------------------------------
2426
+ // Org service-token mint (--service-token <name>)
2427
+ // ---------------------------------------------------------------------------
2428
+
2429
+ /** `postJson` with a bearer Authorization header (action-route calls). */
2430
+ async function postJsonAuthed(
2431
+ fetchImpl: typeof fetch,
2432
+ url: string,
2433
+ body: unknown,
2434
+ bearerToken: string,
2435
+ ): Promise<{ status: number; json: any }> {
2436
+ const controller = new AbortController();
2437
+ const timeout = setTimeout(() => controller.abort(), 30_000);
2438
+ try {
2439
+ const response = await fetchImpl(url, {
2440
+ method: "POST",
2441
+ headers: {
2442
+ "content-type": "application/json",
2443
+ authorization: `Bearer ${bearerToken}`,
2444
+ },
2445
+ body: JSON.stringify(body ?? {}),
2446
+ signal: controller.signal,
2447
+ });
2448
+ let json: any = null;
2449
+ try {
2450
+ json = await response.json();
2451
+ } catch {
2452
+ json = null;
2453
+ }
2454
+ return { status: response.status, json };
2455
+ } finally {
2456
+ clearTimeout(timeout);
2457
+ }
2458
+ }
2459
+
2460
+ /**
2461
+ * `agent-native connect <url> --service-token <name>` — mint an ORG service
2462
+ * token for CI (e.g. the PLAN_RECAP_TOKEN GitHub secret).
2463
+ *
2464
+ * Flow: authenticate the human via the existing browser device flow, then use
2465
+ * that short-lived grant to call the app's `create-org-service-token` action
2466
+ * (org owner/admin gated server-side). The service token is printed exactly
2467
+ * once and never written to any local config file.
2468
+ */
2469
+ export async function runServiceTokenMint(
2470
+ parsed: ParsedConnectArgs,
2471
+ deps: ConnectDeps = {},
2472
+ ): Promise<boolean> {
2473
+ const fetchImpl = deps.fetchImpl ?? fetch;
2474
+ const serviceName = parsed.serviceToken?.trim() ?? "";
2475
+ if (!parsed.url) {
2476
+ logErr(" --service-token requires the app URL.");
2477
+ logErr(
2478
+ " Usage: npx @agent-native/core@latest connect <url> --service-token <name> [--ttl-days <1-365>]",
2479
+ );
2480
+ return false;
2481
+ }
2482
+ if (!serviceName) {
2483
+ logErr(
2484
+ " --service-token requires a service name, e.g. --service-token ci",
2485
+ );
2486
+ return false;
2487
+ }
2488
+
2489
+ const normalizedUrl = normalizeUrl(parsed.url);
2490
+ const baseUrl = stripMcpPath(normalizedUrl);
2491
+ const appSlug = appSlugFromUrl(baseUrl);
2492
+
2493
+ logOut("");
2494
+ logOut(` Creating org service token "${serviceName}" on ${baseUrl}`);
2495
+ logOut(" First, verify it's you (the token will belong to your org)…");
2496
+
2497
+ // Use a non-OAuth client arg so the server mints a bearer grant we can use
2498
+ // against the action route (same approach as the Plans publish-token mint).
2499
+ const grant = await runDeviceFlow(baseUrl, appSlug, "codex", deps);
2500
+ if (!grant?.token) {
2501
+ logErr(" Could not authenticate (the server returned no bearer token).");
2502
+ logErr(" Org service tokens require a deployed app with auth configured.");
2503
+ return false;
2504
+ }
2505
+
2506
+ let status: number;
2507
+ let json: any;
2508
+ try {
2509
+ ({ status, json } = await postJsonAuthed(
2510
+ fetchImpl,
2511
+ `${baseUrl}/_agent-native/actions/create-org-service-token`,
2512
+ {
2513
+ name: serviceName,
2514
+ ...(Number.isFinite(parsed.ttlDays) && parsed.ttlDays
2515
+ ? { ttlDays: parsed.ttlDays }
2516
+ : {}),
2517
+ },
2518
+ grant.token,
2519
+ ));
2520
+ } catch (err: any) {
2521
+ logErr(` Could not reach ${baseUrl} (${err?.message ?? err}).`);
2522
+ return false;
2523
+ }
2524
+
2525
+ if (status === 404) {
2526
+ logErr(
2527
+ " This app does not expose the create-org-service-token action yet.",
2528
+ );
2529
+ logErr(" Redeploy it with a current @agent-native/core, then retry.");
2530
+ return false;
2531
+ }
2532
+ if (status < 200 || status >= 300 || typeof json?.token !== "string") {
2533
+ logErr(
2534
+ ` Could not create the service token (HTTP ${status}): ` +
2535
+ responseMessage(json, "server returned an error."),
2536
+ );
2537
+ if (status === 403) {
2538
+ logErr(" Only org owners or admins can create service tokens.");
2539
+ }
2540
+ return false;
2541
+ }
2542
+
2543
+ logOut("");
2544
+ logOut(" Org service token created.");
2545
+ logOut("");
2546
+ logOut(` Name: ${json.serviceName ?? serviceName}`);
2547
+ if (typeof json.serviceEmail === "string") {
2548
+ logOut(` Acts as: ${json.serviceEmail}`);
2549
+ }
2550
+ if (Number.isFinite(Number(json.ttlDays))) {
2551
+ logOut(` Expires: in ${json.ttlDays} days`);
2552
+ }
2553
+ logOut("");
2554
+ // The ONLY place the secret is ever printed. Never logged elsewhere,
2555
+ // never written to disk.
2556
+ logOut(` ${json.token}`);
2557
+ logOut("");
2558
+ logOut(" Shown once — store it now as your CI secret, e.g.:");
2559
+ logOut(` gh secret set PLAN_RECAP_TOKEN --body "<paste token>"`);
2560
+ logOut("");
2561
+ logOut(
2562
+ " Manage it later with the list-org-service-tokens / " +
2563
+ "revoke-org-service-token actions (org owners/admins).",
2564
+ );
2565
+ return true;
2566
+ }
2567
+
2568
+ // ---------------------------------------------------------------------------
2569
+ // Entry point
2570
+ // ---------------------------------------------------------------------------
2571
+
2572
+ const HELP = `npx @agent-native/core@latest connect — wire your coding agent to a deployed app
2573
+
2574
+ Usage:
2575
+ npx @agent-native/core@latest connect [--client <c>] [--scope user|project]
2576
+ With no URL, opens a picker for the built-in hosted apps
2577
+ (mail.agent-native.com, calendar.agent-native.com, and friends).
2578
+
2579
+ npx @agent-native/core@latest connect <url> [--client <c>] [--scope user|project] [--name <n>]
2580
+ Writes the HTTP MCP entry into your selected client config(s). Claude
2581
+ Code, Cursor, OpenCode, and GitHub Copilot / VS Code use standard remote
2582
+ MCP OAuth and get URL-only config. Codex / Cowork use the browser
2583
+ device-code fallback: the command prints a code, opens the verification
2584
+ URL, polls until approved, then writes bearer headers. With no --client,
2585
+ opens a brief picker preselected from ~/.agent-native/connect.json, or
2586
+ all clients on first run. Idempotent — re-running replaces the same entry.
2587
+ Auth is stored per client config/session; restart or reload each selected
2588
+ client before expecting new tools to appear.
2589
+ Re-running over an older OAuth-capable bearer entry upgrades it to
2590
+ URL-only OAuth config and prompts you to authenticate in that host.
2591
+
2592
+ For cross-app access, prefer the unified Dispatch gateway:
2593
+ npx @agent-native/core@latest connect https://dispatch.agent-native.com
2594
+
2595
+ npx @agent-native/core@latest connect <url> --token <token>
2596
+ No-browser fallback. Skip the device flow and write the entry with
2597
+ the supplied token (get it from the app's Connect page).
2598
+
2599
+ npx @agent-native/core@latest connect <url> --service-token <name> [--ttl-days <1-365>]
2600
+ Mint an ORG service token for CI (e.g. the PLAN_RECAP_TOKEN secret for
2601
+ PR Visual Recap). Authenticates you via the browser device flow, then
2602
+ mints a token owned by your ORGANIZATION — it keeps working if you
2603
+ leave or revoke your personal tokens, and CI-created plans are
2604
+ org-visible. Org owner/admin only. Printed once; nothing is written
2605
+ to local MCP configs.
2606
+
2607
+ npx -y @agent-native/core@latest reconnect [<url>] [--client <c>] [--scope user|project]
2608
+ npx -y @agent-native/core@latest connect reconnect [<url>] [--client <c>] [--scope user|project]
2609
+ Re-authenticate an existing MCP entry without reinstalling apps/skills.
2610
+ With a URL, it reuses the existing server name for that MCP URL when
2611
+ possible, reconnecting only clients that already have that entry. Pass
2612
+ --client to limit which configs it searches; for Codex recovery, prefer
2613
+ --client codex. Without a URL, it reconnects the only matching Agent
2614
+ Native entry in local client configs. Use --name for custom server names.
2615
+
2616
+ npx @agent-native/core@latest connect --all [--client <c>] [--scope user|project]
2617
+ Connect every first-party hosted app as separate MCP resources.
2618
+
2619
+ Developer:
2620
+ npx @agent-native/core@latest connect dev [--apps mail,calendar] [--client <c>]
2621
+ Switch selected first-party MCP entries to a local dev-lazy gateway.
2622
+ Defaults to ${DEFAULT_DEV_GATEWAY}; override with --gateway or --port.
2623
+
2624
+ npx @agent-native/core@latest connect prod [--apps mail,calendar] [--client <c>]
2625
+ Restore production MCP entries saved before the dev switch.
2626
+
2627
+ Clients: all (default), claude-code, codex, cowork, cursor, opencode, github-copilot
2628
+ Scope: user (default, ~/.claude.json) or project (.mcp.json)`;
2629
+
2630
+ /**
2631
+ * `agent-native connect` entry point. `deps` is injectable for tests; the
2632
+ * dispatcher in index.ts calls it with just `args`.
2633
+ *
2634
+ * Sets `process.exitCode = 1` on failure (so the process exits non-zero
2635
+ * once the event loop drains) rather than calling `process.exit`, keeping
2636
+ * the function testable — same pattern as `audit-agent-web`.
2637
+ */
2638
+ export async function runConnect(
2639
+ args: string[],
2640
+ deps: ConnectDeps = {},
2641
+ ): Promise<void> {
2642
+ const previousLogOut = logOutImpl;
2643
+ const previousLogErr = logErrImpl;
2644
+ logOutImpl = deps.logOut ?? previousLogOut;
2645
+ logErrImpl = deps.logErr ?? previousLogErr;
2646
+ try {
2647
+ if (args[0] === "--help" || args[0] === "-h" || args[0] === "help") {
2648
+ logOut(HELP);
2649
+ return;
2650
+ }
2651
+
2652
+ const parsed = parseConnectArgs(args);
2653
+
2654
+ if (parsed.mode) {
2655
+ let ok: boolean;
2656
+ if (parsed.mode === "reconnect" || parsed.mode === "reauth") {
2657
+ const clients = resolveClients(parsed.client);
2658
+ ok = await reconnectOne(parsed, clients, deps);
2659
+ } else {
2660
+ const clients = await resolveConnectClients(parsed, deps);
2661
+ if (!clients) return;
2662
+ ok =
2663
+ parsed.mode === "dev"
2664
+ ? await connectDevProfile(parsed, clients, deps)
2665
+ : await connectProdProfile(parsed, clients, deps);
2666
+ }
2667
+ if (!ok) process.exitCode = 1;
2668
+ return;
2669
+ }
2670
+
2671
+ if (parsed.serviceToken !== undefined) {
2672
+ const ok = await runServiceTokenMint(parsed, deps);
2673
+ if (!ok) process.exitCode = 1;
2674
+ return;
2675
+ }
2676
+
2677
+ if (parsed.all) {
2678
+ const clients = await resolveConnectClients(parsed, deps);
2679
+ if (!clients) return;
2680
+ const ok = await connectAll(parsed, clients, deps);
2681
+ if (!ok) process.exitCode = 1;
2682
+ return;
2683
+ }
2684
+
2685
+ if (!parsed.url) {
2686
+ const apps = await resolveHostedAppsFromPrompt(deps);
2687
+ if (apps) {
2688
+ if (apps.length === 0) return;
2689
+ const clients = await resolveConnectClients(parsed, deps);
2690
+ if (!clients) return;
2691
+ const ok = await connectApps(apps, parsed, clients, deps);
2692
+ if (!ok) process.exitCode = 1;
2693
+ return;
2694
+ }
2695
+
2696
+ logErr(" Missing app URL.");
2697
+ logErr("");
2698
+ logOut(HELP);
2699
+ process.exitCode = 1;
2700
+ return;
2701
+ }
2702
+
2703
+ const clients = await resolveConnectClients(parsed, deps);
2704
+ if (!clients) return;
2705
+ const res = await connectOne(parsed.url, parsed, clients, deps);
2706
+ if (!res.ok) process.exitCode = 1;
2707
+ } catch (err: any) {
2708
+ logErr(` ${err?.message ?? err}`);
2709
+ process.exitCode = 1;
2710
+ } finally {
2711
+ logOutImpl = previousLogOut;
2712
+ logErrImpl = previousLogErr;
2713
+ }
2714
+ }