@agent-native/core 0.115.4 → 0.116.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 (408) hide show
  1. package/agent-native.eject.json +1 -0
  2. package/corpus/README.md +3 -3
  3. package/corpus/core/CHANGELOG.md +28 -0
  4. package/corpus/core/agent-native.eject.json +1 -0
  5. package/corpus/core/docs/AGENTS.md +1 -1
  6. package/corpus/core/docs/content/agent-mentions.mdx +2 -2
  7. package/corpus/core/docs/content/{workspace.mdx → agent-resources.mdx} +1 -7
  8. package/corpus/core/docs/content/agent-teams.mdx +4 -4
  9. package/corpus/core/docs/content/dispatch.mdx +10 -10
  10. package/corpus/core/docs/content/drop-in-agent.mdx +4 -4
  11. package/corpus/core/docs/content/external-agents.mdx +1 -1
  12. package/corpus/core/docs/content/frames.mdx +1 -1
  13. package/corpus/core/docs/content/integrations.mdx +13 -2
  14. package/corpus/core/docs/content/key-concepts.mdx +2 -2
  15. package/corpus/core/docs/content/mcp-clients.mdx +7 -1
  16. package/corpus/core/docs/content/multi-app-workspace.mdx +3 -3
  17. package/corpus/core/docs/content/real-time-collaboration.mdx +33 -15
  18. package/corpus/core/docs/content/recurring-jobs.mdx +7 -7
  19. package/corpus/core/docs/content/skills-guide.mdx +4 -4
  20. package/corpus/core/docs/content/template-brain.mdx +1 -1
  21. package/corpus/core/docs/content/toolkit-collaboration.mdx +1 -1
  22. package/corpus/core/docs/content/using-your-agent.mdx +1 -1
  23. package/corpus/core/docs/content/what-is-agent-native.mdx +4 -4
  24. package/corpus/core/docs/content/workspace-management.mdx +4 -4
  25. package/corpus/core/package.json +1 -1
  26. package/corpus/core/src/agent/production-agent.ts +13 -3
  27. package/corpus/core/src/cli/doctor.ts +6 -1
  28. package/corpus/core/src/client/AgentPanel.tsx +79 -41
  29. package/corpus/core/src/client/AssistantChat.tsx +71 -25
  30. package/corpus/core/src/client/FeedbackButton.tsx +33 -7
  31. package/corpus/core/src/client/MultiTabAssistantChat.tsx +6 -8
  32. package/corpus/core/src/client/agent-chat-adapter.ts +11 -2
  33. package/corpus/core/src/client/agent-page/AgentTabFrame.tsx +22 -3
  34. package/corpus/core/src/client/agent-page/AgentTabsPage.tsx +34 -19
  35. package/corpus/core/src/client/chat/message-components.tsx +43 -16
  36. package/corpus/core/src/client/chat/tool-call-display.tsx +30 -18
  37. package/corpus/core/src/client/chat/tool-render-registry.tsx +2 -0
  38. package/corpus/core/src/client/resources/McpConnectionSuggestion.tsx +19 -2
  39. package/corpus/core/src/client/resources/ResourceTree.tsx +7 -10
  40. package/corpus/core/src/client/resources/ResourcesPanel.tsx +33 -70
  41. package/corpus/core/src/client/resources/mcp-connection-resume.ts +107 -0
  42. package/corpus/core/src/client/resources/mcp-integration-catalog.ts +65 -12
  43. package/corpus/core/src/client/resources/mcp-integration-logos.ts +4 -0
  44. package/corpus/core/src/client/sse-event-processor.ts +50 -14
  45. package/corpus/core/src/client/use-db-sync.ts +16 -6
  46. package/corpus/core/src/connections/catalog.ts +7 -1
  47. package/corpus/core/src/eject/remote-mcp-presets.ts +37 -5
  48. package/corpus/core/src/guards/explicit-collab-access.ts +229 -0
  49. package/corpus/core/src/guards/index.ts +1 -0
  50. package/corpus/core/src/localization/default-messages.ts +54 -5
  51. package/corpus/core/src/mcp/connect-route.ts +34 -51
  52. package/corpus/core/src/provider-api/index.ts +1 -1
  53. package/corpus/core/src/server/collab-plugin.ts +137 -18
  54. package/corpus/core/src/server/index.ts +2 -0
  55. package/corpus/core/src/styles/agent-native.css +40 -0
  56. package/corpus/core/src/templates/default/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
  57. package/corpus/core/src/templates/default/.agents/skills/real-time-collab/SKILL.md +35 -13
  58. package/corpus/core/src/templates/default/.agents/skills/real-time-sync/SKILL.md +1 -1
  59. package/corpus/core/src/templates/headless/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
  60. package/corpus/core/src/templates/workspace-core/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
  61. package/corpus/core/src/templates/workspace-core/.agents/skills/real-time-collab/SKILL.md +35 -13
  62. package/corpus/core/src/templates/workspace-core/.agents/skills/real-time-sync/SKILL.md +1 -1
  63. package/corpus/core/src/templates/workspace-core/.agents/skills/voice-transcription/SKILL.md +12 -8
  64. package/corpus/templates/analytics/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
  65. package/corpus/templates/analytics/.agents/skills/real-time-sync/SKILL.md +1 -1
  66. package/corpus/templates/analytics/AGENTS.md +7 -2
  67. package/corpus/templates/analytics/actions/export-dashboard-panel-to-google-sheet.ts +144 -0
  68. package/corpus/templates/analytics/app/components/layout/Layout.tsx +7 -88
  69. package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +34 -37
  70. package/corpus/templates/analytics/app/global.css +0 -4
  71. package/corpus/templates/analytics/app/hooks/use-navigation-state.ts +2 -7
  72. package/corpus/templates/analytics/app/i18n-data.ts +107 -0
  73. package/corpus/templates/analytics/app/lib/data-source-status.ts +9 -0
  74. package/corpus/templates/analytics/app/lib/sql-query.ts +1 -2
  75. package/corpus/templates/analytics/app/pages/Ask.tsx +2 -7
  76. package/corpus/templates/analytics/app/pages/DataSources.tsx +48 -0
  77. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/SqlChartCard.tsx +59 -0
  78. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/index.tsx +2 -0
  79. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/report-panel-window.ts +3 -1
  80. package/corpus/templates/analytics/changelog/2026-07-22-clear-background-chat-progress.md +6 -0
  81. package/corpus/templates/analytics/changelog/2026-07-22-daily-dashboard-email-query-batches.md +6 -0
  82. package/corpus/templates/analytics/changelog/2026-07-22-export-table-panels-directly-to-google-sheets.md +6 -0
  83. package/corpus/templates/analytics/changelog/2026-07-22-full-page-chat-keeps-the-active-conversation-when-moving-to-.md +6 -0
  84. package/corpus/templates/analytics/changelog/2026-07-22-recent-chats-can-expand-in-the-sidebar.md +6 -0
  85. package/corpus/templates/analytics/seeds/dashboards/agent-native-templates-first-party.json +8 -8
  86. package/corpus/templates/analytics/server/lib/canonical-first-party-dashboard-repair.ts +31 -0
  87. package/corpus/templates/analytics/server/lib/dashboard-report-subscriptions.ts +3 -5
  88. package/corpus/templates/analytics/server/lib/dashboard-report.ts +12 -0
  89. package/corpus/templates/analytics/server/lib/first-party-dashboard-repair.ts +3 -5
  90. package/corpus/templates/analytics/server/lib/first-party-metric-catalog.ts +150 -21
  91. package/corpus/templates/analytics/server/lib/google-sheets-export.ts +188 -0
  92. package/corpus/templates/analytics/server/lib/provider-api.ts +7 -2
  93. package/corpus/templates/analytics/server/plugins/collab.ts +6 -3
  94. package/corpus/templates/analytics/shared/sql-query-limits.ts +1 -0
  95. package/corpus/templates/assets/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
  96. package/corpus/templates/assets/.agents/skills/real-time-collab/SKILL.md +35 -13
  97. package/corpus/templates/assets/.agents/skills/real-time-sync/SKILL.md +1 -1
  98. package/corpus/templates/assets/app/components/layout/Layout.tsx +1 -1
  99. package/corpus/templates/assets/app/components/layout/Sidebar.tsx +54 -62
  100. package/corpus/templates/assets/app/hooks/use-navigation-state.ts +2 -6
  101. package/corpus/templates/assets/app/routes/_index.tsx +8 -5
  102. package/corpus/templates/assets/changelog/2026-07-22-full-page-chat-keeps-the-active-conversation-when-moving-to-.md +6 -0
  103. package/corpus/templates/assets/changelog/2026-07-22-recent-chats-expand-from-a-compact-list.md +6 -0
  104. package/corpus/templates/brain/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
  105. package/corpus/templates/brain/.agents/skills/real-time-sync/SKILL.md +1 -1
  106. package/corpus/templates/brain/actions/rotate-source-ingest-token.ts +77 -0
  107. package/corpus/templates/brain/app/components/layout/Layout.tsx +5 -1
  108. package/corpus/templates/brain/app/components/layout/Sidebar.tsx +38 -51
  109. package/corpus/templates/brain/app/hooks/use-navigation-state.ts +2 -9
  110. package/corpus/templates/brain/app/i18n-data.ts +120 -0
  111. package/corpus/templates/brain/app/routes/sources.tsx +156 -5
  112. package/corpus/templates/brain/changelog/2026-07-22-chat-runs-always-end-with-an-answer.md +6 -0
  113. package/corpus/templates/brain/changelog/2026-07-22-clear-background-chat-progress.md +6 -0
  114. package/corpus/templates/brain/changelog/2026-07-22-compact-sidebar-footer.md +6 -0
  115. package/corpus/templates/brain/changelog/2026-07-22-full-page-chat-keeps-the-active-conversation-when-moving-to-.md +6 -0
  116. package/corpus/templates/brain/changelog/2026-07-22-long-chat-titles-stay-inside-the-sidebar.md +6 -0
  117. package/corpus/templates/brain/changelog/2026-07-22-new-clips-and-webhook-sources-now-show-their-secure-connecti.md +6 -0
  118. package/corpus/templates/brain/jobs/emit-netlify-brain-queue-cron.ts +125 -0
  119. package/corpus/templates/brain/netlify.toml +5 -1
  120. package/corpus/templates/brain/scripts/configure-prod-clips-source.ts +50 -0
  121. package/corpus/templates/brain/server/lib/capture-sanitization.ts +64 -6
  122. package/corpus/templates/brain/server/plugins/agent-chat.ts +4 -0
  123. package/corpus/templates/brain/server/plugins/brain-jobs.ts +1 -0
  124. package/corpus/templates/brain/server/routes/api/brain/queue/run.post.ts +55 -0
  125. package/corpus/templates/calendar/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
  126. package/corpus/templates/calendar/.agents/skills/real-time-sync/SKILL.md +1 -1
  127. package/corpus/templates/chat/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
  128. package/corpus/templates/chat/.agents/skills/real-time-sync/SKILL.md +1 -1
  129. package/corpus/templates/chat/app/components/layout/Layout.tsx +1 -0
  130. package/corpus/templates/chat/app/components/layout/Sidebar.tsx +43 -67
  131. package/corpus/templates/chat/app/hooks/use-navigation-state.ts +2 -7
  132. package/corpus/templates/chat/app/routes/_index.tsx +8 -5
  133. package/corpus/templates/chat/changelog/2026-07-22-compact-sidebar-footer.md +6 -0
  134. package/corpus/templates/chat/changelog/2026-07-22-full-page-chat-keeps-the-active-conversation-when-moving-to-.md +6 -0
  135. package/corpus/templates/chat/changelog/2026-07-22-recent-chats-are-easier-to-scan-and-expand.md +6 -0
  136. package/corpus/templates/clips/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
  137. package/corpus/templates/clips/AGENTS.md +9 -1
  138. package/corpus/templates/clips/actions/export-to-brain.ts +82 -6
  139. package/corpus/templates/clips/actions/request-transcript.ts +25 -14
  140. package/corpus/templates/clips/changelog/2026-07-22-clips-transcripts-now-retry-brain-export.md +5 -0
  141. package/corpus/templates/clips/changelog/2026-07-22-german-umlauts-and-other-non-ascii-characters-now-paste-corr.md +6 -0
  142. package/corpus/templates/clips/desktop/src-tauri/src/clips/mod.rs +26 -3
  143. package/corpus/templates/clips/jobs/emit-netlify-brain-export-cron.ts +118 -0
  144. package/corpus/templates/clips/netlify.toml +4 -1
  145. package/corpus/templates/clips/scripts/configure-prod-brain-export.ts +92 -0
  146. package/corpus/templates/clips/server/jobs/brain-export.ts +182 -0
  147. package/corpus/templates/clips/server/lib/brain-export-state.ts +42 -0
  148. package/corpus/templates/clips/server/lib/post-finalize-dispatch.ts +5 -1
  149. package/corpus/templates/clips/server/plugins/calendar-jobs.ts +2 -0
  150. package/corpus/templates/clips/server/register-secrets.ts +42 -0
  151. package/corpus/templates/clips/server/routes/api/_agent-native-background/post-finalize-worker.post.ts +10 -1
  152. package/corpus/templates/clips/server/routes/api/clips/brain-export/run.post.ts +45 -0
  153. package/corpus/templates/content/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
  154. package/corpus/templates/content/.agents/skills/real-time-sync/SKILL.md +1 -1
  155. package/corpus/templates/content/app/components/sidebar/DocumentSidebar.tsx +1 -1
  156. package/corpus/templates/content/server/plugins/collab.ts +1 -1
  157. package/corpus/templates/crm/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
  158. package/corpus/templates/crm/actions/_crm-data-program-actions.ts +15 -0
  159. package/corpus/templates/crm/actions/get-crm-dashboard-panel.ts +2 -0
  160. package/corpus/templates/crm/actions/run.ts +2 -6
  161. package/corpus/templates/crm/actions/update-crm-record.ts +4 -2
  162. package/corpus/templates/crm/app/components/layout/CrmLayout.tsx +6 -0
  163. package/corpus/templates/crm/changelog/2026-07-22-crm-field-validation-now-explains-which-fields-cannot-be-edi.md +6 -0
  164. package/corpus/templates/crm/changelog/2026-07-22-fixed-hubspot-contact-syncs-missing-records-updated-after-th.md +6 -0
  165. package/corpus/templates/crm/changelog/2026-07-22-fixed-pipeline-dashboard-panels-so-their-opportunity-data-lo.md +6 -0
  166. package/corpus/templates/crm/changelog/2026-07-22-full-page-chat-keeps-the-active-conversation-when-moving-to-.md +6 -0
  167. package/corpus/templates/crm/server/crm/hubspot-adapter.ts +4 -1
  168. package/corpus/templates/design/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
  169. package/corpus/templates/design/app/components/layout/Sidebar.tsx +1 -1
  170. package/corpus/templates/design/server/plugins/collab.ts +11 -8
  171. package/corpus/templates/dispatch/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
  172. package/corpus/templates/forms/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
  173. package/corpus/templates/forms/.agents/skills/real-time-sync/SKILL.md +1 -1
  174. package/corpus/templates/forms/app/components/layout/Layout.tsx +1 -0
  175. package/corpus/templates/forms/app/components/layout/Sidebar.tsx +1 -1
  176. package/corpus/templates/forms/app/hooks/use-navigation-state.ts +2 -9
  177. package/corpus/templates/forms/app/root.tsx +1 -6
  178. package/corpus/templates/forms/changelog/2026-07-22-full-page-chat-keeps-the-active-conversation-when-moving-to-.md +6 -0
  179. package/corpus/templates/macros/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
  180. package/corpus/templates/mail/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
  181. package/corpus/templates/mail/.agents/skills/real-time-sync/SKILL.md +1 -1
  182. package/corpus/templates/mail/app/components/layout/AppLayout.tsx +2 -2
  183. package/corpus/templates/plan/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
  184. package/corpus/templates/plan/.agents/skills/real-time-sync/SKILL.md +1 -1
  185. package/corpus/templates/plan/app/components/layout/Layout.tsx +5 -1
  186. package/corpus/templates/plan/app/components/layout/Sidebar.tsx +57 -72
  187. package/corpus/templates/plan/app/hooks/use-navigation-state.ts +2 -9
  188. package/corpus/templates/plan/app/lib/create-plan-routing.ts +2 -2
  189. package/corpus/templates/plan/app/pages/PlanChatPage.tsx +0 -1
  190. package/corpus/templates/plan/changelog/2026-07-22-compact-sidebar-footer.md +6 -0
  191. package/corpus/templates/plan/changelog/2026-07-22-full-page-chat-keeps-the-active-conversation-when-moving-to-.md +6 -0
  192. package/corpus/templates/plan/changelog/2026-07-22-recent-chats-and-sidebar-controls-are-more-compact.md +6 -0
  193. package/corpus/templates/plan/server/plugins/collab.ts +5 -2
  194. package/corpus/templates/slides/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
  195. package/corpus/templates/slides/app/components/layout/Sidebar.tsx +1 -1
  196. package/corpus/templates/slides/server/plugins/collab.ts +11 -8
  197. package/corpus/templates/tasks/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
  198. package/corpus/templates/tasks/.agents/skills/real-time-sync/SKILL.md +1 -1
  199. package/corpus/templates/tasks/app/components/layout/Sidebar.tsx +5 -22
  200. package/corpus/templates/tasks/changelog/2026-07-22-compact-sidebar-footer.md +6 -0
  201. package/corpus/toolkit/CHANGELOG.md +7 -0
  202. package/corpus/toolkit/README.md +12 -3
  203. package/corpus/toolkit/package.json +1 -1
  204. package/corpus/toolkit/src/chat-history/ChatHistoryRail.tsx +89 -0
  205. package/corpus/toolkit/src/chat-history/index.ts +5 -0
  206. package/corpus/toolkit/src/chat-history.css +59 -0
  207. package/corpus/toolkit/src/composer/RealtimeVoiceMode.tsx +106 -36
  208. package/corpus/toolkit/src/composer/VoiceButton.tsx +49 -0
  209. package/corpus/toolkit/src/composer/realtime-voice-audio-level.ts +2 -1
  210. package/corpus/toolkit/src/composer/useRealtimeVoiceMode.tsx +5 -3
  211. package/corpus/toolkit/src/styles.css +35 -0
  212. package/dist/agent/production-agent.d.ts.map +1 -1
  213. package/dist/agent/production-agent.js +13 -3
  214. package/dist/agent/production-agent.js.map +1 -1
  215. package/dist/cli/doctor.d.ts +1 -1
  216. package/dist/cli/doctor.d.ts.map +1 -1
  217. package/dist/cli/doctor.js +5 -2
  218. package/dist/cli/doctor.js.map +1 -1
  219. package/dist/client/AgentPanel.d.ts +1 -0
  220. package/dist/client/AgentPanel.d.ts.map +1 -1
  221. package/dist/client/AgentPanel.js +38 -18
  222. package/dist/client/AgentPanel.js.map +1 -1
  223. package/dist/client/AssistantChat.d.ts.map +1 -1
  224. package/dist/client/AssistantChat.js +55 -20
  225. package/dist/client/AssistantChat.js.map +1 -1
  226. package/dist/client/FeedbackButton.d.ts +4 -2
  227. package/dist/client/FeedbackButton.d.ts.map +1 -1
  228. package/dist/client/FeedbackButton.js +18 -2
  229. package/dist/client/FeedbackButton.js.map +1 -1
  230. package/dist/client/MultiTabAssistantChat.d.ts +1 -1
  231. package/dist/client/MultiTabAssistantChat.d.ts.map +1 -1
  232. package/dist/client/MultiTabAssistantChat.js +2 -3
  233. package/dist/client/MultiTabAssistantChat.js.map +1 -1
  234. package/dist/client/agent-chat-adapter.d.ts.map +1 -1
  235. package/dist/client/agent-chat-adapter.js +11 -3
  236. package/dist/client/agent-chat-adapter.js.map +1 -1
  237. package/dist/client/agent-page/AgentTabFrame.d.ts +3 -1
  238. package/dist/client/agent-page/AgentTabFrame.d.ts.map +1 -1
  239. package/dist/client/agent-page/AgentTabFrame.js +3 -2
  240. package/dist/client/agent-page/AgentTabFrame.js.map +1 -1
  241. package/dist/client/agent-page/AgentTabsPage.d.ts +2 -0
  242. package/dist/client/agent-page/AgentTabsPage.d.ts.map +1 -1
  243. package/dist/client/agent-page/AgentTabsPage.js +26 -15
  244. package/dist/client/agent-page/AgentTabsPage.js.map +1 -1
  245. package/dist/client/chat/message-components.d.ts +6 -1
  246. package/dist/client/chat/message-components.d.ts.map +1 -1
  247. package/dist/client/chat/message-components.js +17 -11
  248. package/dist/client/chat/message-components.js.map +1 -1
  249. package/dist/client/chat/tool-call-display.d.ts +11 -1
  250. package/dist/client/chat/tool-call-display.d.ts.map +1 -1
  251. package/dist/client/chat/tool-call-display.js +16 -17
  252. package/dist/client/chat/tool-call-display.js.map +1 -1
  253. package/dist/client/chat/tool-render-registry.d.ts +2 -0
  254. package/dist/client/chat/tool-render-registry.d.ts.map +1 -1
  255. package/dist/client/chat/tool-render-registry.js.map +1 -1
  256. package/dist/client/resources/McpConnectionSuggestion.d.ts.map +1 -1
  257. package/dist/client/resources/McpConnectionSuggestion.js +15 -1
  258. package/dist/client/resources/McpConnectionSuggestion.js.map +1 -1
  259. package/dist/client/resources/ResourceTree.d.ts.map +1 -1
  260. package/dist/client/resources/ResourceTree.js +3 -3
  261. package/dist/client/resources/ResourceTree.js.map +1 -1
  262. package/dist/client/resources/ResourcesPanel.d.ts +1 -0
  263. package/dist/client/resources/ResourcesPanel.d.ts.map +1 -1
  264. package/dist/client/resources/ResourcesPanel.js +34 -20
  265. package/dist/client/resources/ResourcesPanel.js.map +1 -1
  266. package/dist/client/resources/mcp-connection-resume.d.ts +11 -0
  267. package/dist/client/resources/mcp-connection-resume.d.ts.map +1 -0
  268. package/dist/client/resources/mcp-connection-resume.js +95 -0
  269. package/dist/client/resources/mcp-connection-resume.js.map +1 -0
  270. package/dist/client/resources/mcp-integration-catalog.d.ts +1 -0
  271. package/dist/client/resources/mcp-integration-catalog.d.ts.map +1 -1
  272. package/dist/client/resources/mcp-integration-catalog.js +63 -8
  273. package/dist/client/resources/mcp-integration-catalog.js.map +1 -1
  274. package/dist/client/resources/mcp-integration-logos.d.ts.map +1 -1
  275. package/dist/client/resources/mcp-integration-logos.js +4 -0
  276. package/dist/client/resources/mcp-integration-logos.js.map +1 -1
  277. package/dist/client/sse-event-processor.d.ts +5 -0
  278. package/dist/client/sse-event-processor.d.ts.map +1 -1
  279. package/dist/client/sse-event-processor.js +39 -13
  280. package/dist/client/sse-event-processor.js.map +1 -1
  281. package/dist/client/use-db-sync.d.ts +3 -2
  282. package/dist/client/use-db-sync.d.ts.map +1 -1
  283. package/dist/client/use-db-sync.js +17 -6
  284. package/dist/client/use-db-sync.js.map +1 -1
  285. package/dist/collab/routes.d.ts +1 -1
  286. package/dist/connections/catalog.d.ts +1 -1
  287. package/dist/connections/catalog.d.ts.map +1 -1
  288. package/dist/connections/catalog.js +7 -1
  289. package/dist/connections/catalog.js.map +1 -1
  290. package/dist/eject/remote-mcp-presets.d.ts.map +1 -1
  291. package/dist/eject/remote-mcp-presets.js +33 -3
  292. package/dist/eject/remote-mcp-presets.js.map +1 -1
  293. package/dist/guards/explicit-collab-access.d.ts +8 -0
  294. package/dist/guards/explicit-collab-access.d.ts.map +1 -0
  295. package/dist/guards/explicit-collab-access.js +214 -0
  296. package/dist/guards/explicit-collab-access.js.map +1 -0
  297. package/dist/guards/index.d.ts +1 -0
  298. package/dist/guards/index.d.ts.map +1 -1
  299. package/dist/guards/index.js +1 -0
  300. package/dist/guards/index.js.map +1 -1
  301. package/dist/localization/default-messages.d.ts +43 -0
  302. package/dist/localization/default-messages.d.ts.map +1 -1
  303. package/dist/localization/default-messages.js +48 -5
  304. package/dist/localization/default-messages.js.map +1 -1
  305. package/dist/mcp/connect-route.d.ts.map +1 -1
  306. package/dist/mcp/connect-route.js +34 -48
  307. package/dist/mcp/connect-route.js.map +1 -1
  308. package/dist/notifications/routes.d.ts +3 -3
  309. package/dist/observability/routes.d.ts +1 -1
  310. package/dist/progress/routes.d.ts +1 -1
  311. package/dist/provider-api/actions/custom-provider-registration.d.ts +11 -11
  312. package/dist/provider-api/actions/provider-api.d.ts +7 -7
  313. package/dist/provider-api/corpus-jobs.d.ts +2 -2
  314. package/dist/provider-api/index.js +1 -1
  315. package/dist/provider-api/index.js.map +1 -1
  316. package/dist/server/collab-plugin.d.ts +34 -3
  317. package/dist/server/collab-plugin.d.ts.map +1 -1
  318. package/dist/server/collab-plugin.js +65 -12
  319. package/dist/server/collab-plugin.js.map +1 -1
  320. package/dist/server/index.d.ts +1 -1
  321. package/dist/server/index.d.ts.map +1 -1
  322. package/dist/server/index.js.map +1 -1
  323. package/dist/styles/agent-native.css +40 -0
  324. package/dist/templates/chat/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
  325. package/dist/templates/chat/.agents/skills/real-time-sync/SKILL.md +1 -1
  326. package/dist/templates/chat/app/components/layout/Layout.tsx +1 -0
  327. package/dist/templates/chat/app/components/layout/Sidebar.tsx +43 -67
  328. package/dist/templates/chat/app/hooks/use-navigation-state.ts +2 -7
  329. package/dist/templates/chat/app/routes/_index.tsx +8 -5
  330. package/dist/templates/chat/changelog/2026-07-22-compact-sidebar-footer.md +6 -0
  331. package/dist/templates/chat/changelog/2026-07-22-full-page-chat-keeps-the-active-conversation-when-moving-to-.md +6 -0
  332. package/dist/templates/chat/changelog/2026-07-22-recent-chats-are-easier-to-scan-and-expand.md +6 -0
  333. package/dist/templates/default/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
  334. package/dist/templates/default/.agents/skills/real-time-collab/SKILL.md +35 -13
  335. package/dist/templates/default/.agents/skills/real-time-sync/SKILL.md +1 -1
  336. package/dist/templates/headless/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
  337. package/dist/templates/workspace-core/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
  338. package/dist/templates/workspace-core/.agents/skills/real-time-collab/SKILL.md +35 -13
  339. package/dist/templates/workspace-core/.agents/skills/real-time-sync/SKILL.md +1 -1
  340. package/dist/templates/workspace-core/.agents/skills/voice-transcription/SKILL.md +12 -8
  341. package/docs/AGENTS.md +1 -1
  342. package/docs/content/agent-mentions.mdx +2 -2
  343. package/docs/content/{workspace.mdx → agent-resources.mdx} +1 -7
  344. package/docs/content/agent-teams.mdx +4 -4
  345. package/docs/content/dispatch.mdx +10 -10
  346. package/docs/content/drop-in-agent.mdx +4 -4
  347. package/docs/content/external-agents.mdx +1 -1
  348. package/docs/content/frames.mdx +1 -1
  349. package/docs/content/integrations.mdx +13 -2
  350. package/docs/content/key-concepts.mdx +2 -2
  351. package/docs/content/mcp-clients.mdx +7 -1
  352. package/docs/content/multi-app-workspace.mdx +3 -3
  353. package/docs/content/real-time-collaboration.mdx +33 -15
  354. package/docs/content/recurring-jobs.mdx +7 -7
  355. package/docs/content/skills-guide.mdx +4 -4
  356. package/docs/content/template-brain.mdx +1 -1
  357. package/docs/content/toolkit-collaboration.mdx +1 -1
  358. package/docs/content/using-your-agent.mdx +1 -1
  359. package/docs/content/what-is-agent-native.mdx +4 -4
  360. package/docs/content/workspace-management.mdx +4 -4
  361. package/package.json +3 -3
  362. package/src/agent/production-agent.ts +13 -3
  363. package/src/cli/doctor.ts +6 -1
  364. package/src/client/AgentPanel.tsx +79 -41
  365. package/src/client/AssistantChat.tsx +71 -25
  366. package/src/client/FeedbackButton.tsx +33 -7
  367. package/src/client/MultiTabAssistantChat.tsx +6 -8
  368. package/src/client/agent-chat-adapter.ts +11 -2
  369. package/src/client/agent-page/AgentTabFrame.tsx +22 -3
  370. package/src/client/agent-page/AgentTabsPage.tsx +34 -19
  371. package/src/client/chat/message-components.tsx +43 -16
  372. package/src/client/chat/tool-call-display.tsx +30 -18
  373. package/src/client/chat/tool-render-registry.tsx +2 -0
  374. package/src/client/resources/McpConnectionSuggestion.tsx +19 -2
  375. package/src/client/resources/ResourceTree.tsx +7 -10
  376. package/src/client/resources/ResourcesPanel.tsx +33 -70
  377. package/src/client/resources/mcp-connection-resume.ts +107 -0
  378. package/src/client/resources/mcp-integration-catalog.ts +65 -12
  379. package/src/client/resources/mcp-integration-logos.ts +4 -0
  380. package/src/client/sse-event-processor.ts +50 -14
  381. package/src/client/use-db-sync.ts +16 -6
  382. package/src/connections/catalog.ts +7 -1
  383. package/src/eject/remote-mcp-presets.ts +37 -5
  384. package/src/guards/explicit-collab-access.ts +229 -0
  385. package/src/guards/index.ts +1 -0
  386. package/src/localization/default-messages.ts +54 -5
  387. package/src/mcp/connect-route.ts +34 -51
  388. package/src/provider-api/index.ts +1 -1
  389. package/src/server/collab-plugin.ts +137 -18
  390. package/src/server/index.ts +2 -0
  391. package/src/styles/agent-native.css +40 -0
  392. package/src/templates/chat/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
  393. package/src/templates/chat/.agents/skills/real-time-sync/SKILL.md +1 -1
  394. package/src/templates/chat/app/components/layout/Layout.tsx +1 -0
  395. package/src/templates/chat/app/components/layout/Sidebar.tsx +43 -67
  396. package/src/templates/chat/app/hooks/use-navigation-state.ts +2 -7
  397. package/src/templates/chat/app/routes/_index.tsx +8 -5
  398. package/src/templates/chat/changelog/2026-07-22-compact-sidebar-footer.md +6 -0
  399. package/src/templates/chat/changelog/2026-07-22-full-page-chat-keeps-the-active-conversation-when-moving-to-.md +6 -0
  400. package/src/templates/chat/changelog/2026-07-22-recent-chats-are-easier-to-scan-and-expand.md +6 -0
  401. package/src/templates/default/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
  402. package/src/templates/default/.agents/skills/real-time-collab/SKILL.md +35 -13
  403. package/src/templates/default/.agents/skills/real-time-sync/SKILL.md +1 -1
  404. package/src/templates/headless/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
  405. package/src/templates/workspace-core/.agents/skills/agent-native-toolkit/SKILL.md +4 -1
  406. package/src/templates/workspace-core/.agents/skills/real-time-collab/SKILL.md +35 -13
  407. package/src/templates/workspace-core/.agents/skills/real-time-sync/SKILL.md +1 -1
  408. package/src/templates/workspace-core/.agents/skills/voice-transcription/SKILL.md +12 -8
@@ -1,5 +1,5 @@
1
1
  import { type MigrationManifest } from "../package-lifecycle/index.js";
2
- export type GuardName = "no-drizzle-push" | "no-unscoped-credentials" | "no-unscoped-queries" | "no-env-credentials" | "db-tool-scoping" | "no-env-mutation" | "no-localhost-fallback" | "migration-manifest";
2
+ export type GuardName = "no-drizzle-push" | "no-unscoped-credentials" | "no-unscoped-queries" | "no-env-credentials" | "db-tool-scoping" | "no-env-mutation" | "no-localhost-fallback" | "explicit-collab-access" | "migration-manifest";
3
3
  export declare const ALL_GUARD_NAMES: GuardName[];
4
4
  export interface DoctorConfig {
5
5
  disabledGuards: string[];
@@ -1 +1 @@
1
- {"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/cli/doctor.ts"],"names":[],"mappings":"AAmCA,OAAO,EAGL,KAAK,iBAAiB,EACvB,MAAM,+BAA+B,CAAC;AAEvC,MAAM,MAAM,SAAS,GACjB,iBAAiB,GACjB,yBAAyB,GACzB,qBAAqB,GACrB,oBAAoB,GACpB,iBAAiB,GACjB,iBAAiB,GACjB,uBAAuB,GACvB,oBAAoB,CAAC;AAEzB,eAAO,MAAM,eAAe,EAAE,SAAS,EAStC,CAAC;AAEF,MAAM,WAAW,YAAY;IAC3B,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,qBAAqB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9C,WAAW,EAAE,OAAO,CAAC;CACtB;AAQD,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,OAAO,CAAC;IACZ,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC1B,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC1B,SAAS,EAAE,MAAM,EAAE,CAAC;CACrB;AAMD;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,CA6B3D;AAoDD,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb;;;iEAG6D;IAC7D,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,kBAAkB,CAAC,EAAE,iBAAiB,EAAE,CAAC;CAC1C;AAED;;qDAEqD;AACrD,wBAAgB,aAAa,CAAC,OAAO,EAAE,oBAAoB,GAAG,YAAY,CA0CzE;AAED;;;sDAGsD;AACtD,wBAAgB,eAAe,CAC7B,WAAW,EAAE,OAAO,EACpB,IAAI,EAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAC;IAAC,WAAW,CAAC,EAAE,OAAO,CAAA;CAAE,GAChD,OAAO,CAET;AAED,MAAM,WAAW,QAAQ;IACvB,GAAG,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/B,GAAG,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CAChC;AA8BD,MAAM,WAAW,gBAAgB;IAC/B,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,gBAAgB,CAuBhE;AASD,wBAAgB,eAAe,CAAC,EAAE,GAAE,IAAI,CAAC,QAAQ,EAAE,KAAK,CAAa,GAAG,IAAI,CAyB3E;AAED;+DAC+D;AAC/D,wBAAsB,SAAS,CAC7B,IAAI,EAAE,MAAM,EAAE,EACd,EAAE,GAAE,QAAoB,GACvB,OAAO,CAAC,MAAM,CAAC,CAyDjB;AAED,MAAM,WAAW,sBAAsB;IACrC,GAAG,EAAE,MAAM,CAAC;IACZ,gEAAgE;IAChE,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,qBAAqB;IACpC;8DAC0D;IAC1D,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,EAAE,YAAY,CAAC;CACtB;AAED;;;;;;;;GAQG;AACH,wBAAsB,kBAAkB,CACtC,OAAO,EAAE,sBAAsB,EAC/B,EAAE,GAAE,QAAoB,GACvB,OAAO,CAAC,qBAAqB,CAAC,CAmChC"}
1
+ {"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/cli/doctor.ts"],"names":[],"mappings":"AAoCA,OAAO,EAGL,KAAK,iBAAiB,EACvB,MAAM,+BAA+B,CAAC;AAEvC,MAAM,MAAM,SAAS,GACjB,iBAAiB,GACjB,yBAAyB,GACzB,qBAAqB,GACrB,oBAAoB,GACpB,iBAAiB,GACjB,iBAAiB,GACjB,uBAAuB,GACvB,wBAAwB,GACxB,oBAAoB,CAAC;AAEzB,eAAO,MAAM,eAAe,EAAE,SAAS,EAUtC,CAAC;AAEF,MAAM,WAAW,YAAY;IAC3B,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,qBAAqB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9C,WAAW,EAAE,OAAO,CAAC;CACtB;AAQD,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,OAAO,CAAC;IACZ,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC1B,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC1B,SAAS,EAAE,MAAM,EAAE,CAAC;CACrB;AAMD;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,CA6B3D;AAsDD,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb;;;iEAG6D;IAC7D,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,kBAAkB,CAAC,EAAE,iBAAiB,EAAE,CAAC;CAC1C;AAED;;qDAEqD;AACrD,wBAAgB,aAAa,CAAC,OAAO,EAAE,oBAAoB,GAAG,YAAY,CA0CzE;AAED;;;sDAGsD;AACtD,wBAAgB,eAAe,CAC7B,WAAW,EAAE,OAAO,EACpB,IAAI,EAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAC;IAAC,WAAW,CAAC,EAAE,OAAO,CAAA;CAAE,GAChD,OAAO,CAET;AAED,MAAM,WAAW,QAAQ;IACvB,GAAG,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/B,GAAG,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CAChC;AA8BD,MAAM,WAAW,gBAAgB;IAC/B,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,gBAAgB,CAuBhE;AASD,wBAAgB,eAAe,CAAC,EAAE,GAAE,IAAI,CAAC,QAAQ,EAAE,KAAK,CAAa,GAAG,IAAI,CAyB3E;AAED;+DAC+D;AAC/D,wBAAsB,SAAS,CAC7B,IAAI,EAAE,MAAM,EAAE,EACd,EAAE,GAAE,QAAoB,GACvB,OAAO,CAAC,MAAM,CAAC,CAyDjB;AAED,MAAM,WAAW,sBAAsB;IACrC,GAAG,EAAE,MAAM,CAAC;IACZ,gEAAgE;IAChE,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,qBAAqB;IACpC;8DAC0D;IAC1D,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,EAAE,YAAY,CAAC;CACtB;AAED;;;;;;;;GAQG;AACH,wBAAsB,kBAAkB,CACtC,OAAO,EAAE,sBAAsB,EAC/B,EAAE,GAAE,QAAoB,GACvB,OAAO,CAAC,qBAAqB,CAAC,CAmChC"}
@@ -4,7 +4,7 @@
4
4
  * itself via `scripts/guard-*.mjs` (see
5
5
  * `advisor-plans/reports/005-doctor-design.md` for the full design and
6
6
  * `advisor-plans/015-doctor-v1-implementation.md` for the implementation
7
- * plan). v1 ships 8 of those guards, ported to work against a single
7
+ * plan). v1 ships 9 of those guards, ported to work against a single
8
8
  * generated app root instead of this monorepo's multi-template layout —
9
9
  * see `../guards/index.ts`.
10
10
  *
@@ -22,7 +22,7 @@
22
22
  */
23
23
  import fs from "node:fs";
24
24
  import path from "node:path";
25
- import { scanDbToolScoping, scanDrizzlePush, scanEnvCredentials, scanEnvMutation, scanLocalhostFallback, scanUnscopedCredentials, scanUnscopedQueries, } from "../guards/index.js";
25
+ import { scanDbToolScoping, scanDrizzlePush, scanEnvCredentials, scanEnvMutation, scanExplicitCollabAccess, scanLocalhostFallback, scanUnscopedCredentials, scanUnscopedQueries, } from "../guards/index.js";
26
26
  import { AGENT_NATIVE_UPGRADE_CODEMOD_COMMAND, scanDeprecatedImports, } from "../package-lifecycle/index.js";
27
27
  export const ALL_GUARD_NAMES = [
28
28
  "no-drizzle-push",
@@ -32,6 +32,7 @@ export const ALL_GUARD_NAMES = [
32
32
  "db-tool-scoping",
33
33
  "no-env-mutation",
34
34
  "no-localhost-fallback",
35
+ "explicit-collab-access",
35
36
  "migration-manifest",
36
37
  ];
37
38
  const DEFAULT_DOCTOR_CONFIG = {
@@ -86,6 +87,8 @@ function runGuard(name, root, config, migrationManifests) {
86
87
  return scanEnvMutation({ root });
87
88
  case "no-localhost-fallback":
88
89
  return scanLocalhostFallback({ root, extraExemptPaths: [] });
90
+ case "explicit-collab-access":
91
+ return scanExplicitCollabAccess({ root });
89
92
  case "migration-manifest": {
90
93
  const imports = scanDeprecatedImports({
91
94
  root,
@@ -1 +1 @@
1
- {"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/cli/doctor.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * `agent-native doctor` — scan an app's source tree for the security-\n * critical code-safety invariants this monorepo already enforces on\n * itself via `scripts/guard-*.mjs` (see\n * `advisor-plans/reports/005-doctor-design.md` for the full design and\n * `advisor-plans/015-doctor-v1-implementation.md` for the implementation\n * plan). v1 ships 8 of those guards, ported to work against a single\n * generated app root instead of this monorepo's multi-template layout —\n * see `../guards/index.ts`.\n *\n * This is a NEW top-level command, deliberately kept separate from the two\n * existing \"doctor\" precedents in this CLI:\n * - `agent-native upgrade check` (`upgrade.ts`) — dependency-pin health.\n * - `agent-native recap doctor` (`recap.ts`) — PR Visual Recap config health.\n * Each diagnoses a different domain; none are folded into a shared\n * mega-doctor (see report 005, \"Relationship to upgrade doctor and recap\n * doctor\").\n *\n * `--fix` is reserved, not implemented in v1 — it prints a message and\n * exits 2 rather than silently no-op, so a future implementation doesn't\n * collide with a script already passing the flag.\n */\nimport fs from \"node:fs\";\nimport path from \"node:path\";\n\nimport {\n scanDbToolScoping,\n scanDrizzlePush,\n scanEnvCredentials,\n scanEnvMutation,\n scanLocalhostFallback,\n scanUnscopedCredentials,\n scanUnscopedQueries,\n} from \"../guards/index.js\";\nimport type { GuardFinding, GuardResult } from \"../guards/index.js\";\nimport {\n AGENT_NATIVE_UPGRADE_CODEMOD_COMMAND,\n scanDeprecatedImports,\n type MigrationManifest,\n} from \"../package-lifecycle/index.js\";\n\nexport type GuardName =\n | \"no-drizzle-push\"\n | \"no-unscoped-credentials\"\n | \"no-unscoped-queries\"\n | \"no-env-credentials\"\n | \"db-tool-scoping\"\n | \"no-env-mutation\"\n | \"no-localhost-fallback\"\n | \"migration-manifest\";\n\nexport const ALL_GUARD_NAMES: GuardName[] = [\n \"no-drizzle-push\",\n \"no-unscoped-credentials\",\n \"no-unscoped-queries\",\n \"no-env-credentials\",\n \"db-tool-scoping\",\n \"no-env-mutation\",\n \"no-localhost-fallback\",\n \"migration-manifest\",\n];\n\nexport interface DoctorConfig {\n disabledGuards: string[];\n dbToolScopingDenylist: Record<string, string>;\n failOnBuild: boolean;\n}\n\nconst DEFAULT_DOCTOR_CONFIG: DoctorConfig = {\n disabledGuards: [],\n dbToolScopingDenylist: {},\n failOnBuild: false,\n};\n\nexport interface DoctorFinding {\n guard: string;\n file: string;\n line: number;\n message: string;\n}\n\nexport interface DoctorReport {\n ok: boolean;\n findings: DoctorFinding[];\n warnings: DoctorFinding[];\n guardsRun: string[];\n}\n\ninterface DoctorGuardResult extends GuardResult {\n warnings?: GuardFinding[];\n}\n\n/**\n * Reads the optional `\"doctor\"` key from `<root>/agent-native.json`. All\n * fields are optional with sane empty defaults — an app needs zero config\n * to run `agent-native doctor` with every v1 guard enabled.\n */\nexport function readDoctorConfig(root: string): DoctorConfig {\n const manifestPath = path.join(root, \"agent-native.json\");\n if (!fs.existsSync(manifestPath)) {\n return { ...DEFAULT_DOCTOR_CONFIG, dbToolScopingDenylist: {} };\n }\n try {\n const raw = fs.readFileSync(manifestPath, \"utf-8\");\n const parsed = JSON.parse(raw) as { doctor?: Record<string, unknown> };\n const doctor = parsed.doctor ?? {};\n const disabledGuards = Array.isArray(doctor.disabledGuards)\n ? doctor.disabledGuards.filter((v): v is string => typeof v === \"string\")\n : [];\n const dbToolScopingDenylist =\n doctor.dbToolScopingDenylist &&\n typeof doctor.dbToolScopingDenylist === \"object\"\n ? (Object.fromEntries(\n Object.entries(\n doctor.dbToolScopingDenylist as Record<string, unknown>,\n ).filter(\n (entry): entry is [string, string] =>\n typeof entry[1] === \"string\",\n ),\n ) as Record<string, string>)\n : {};\n const failOnBuild = doctor.failOnBuild === true;\n return { disabledGuards, dbToolScopingDenylist, failOnBuild };\n } catch {\n return { ...DEFAULT_DOCTOR_CONFIG, dbToolScopingDenylist: {} };\n }\n}\n\nfunction runGuard(\n name: GuardName,\n root: string,\n config: DoctorConfig,\n migrationManifests?: MigrationManifest[],\n): DoctorGuardResult {\n switch (name) {\n case \"no-drizzle-push\":\n return scanDrizzlePush({ root });\n case \"no-unscoped-credentials\":\n return scanUnscopedCredentials({ root });\n case \"no-unscoped-queries\":\n return scanUnscopedQueries({ root, extraExemptPaths: [] });\n case \"no-env-credentials\":\n return scanEnvCredentials({ root });\n case \"db-tool-scoping\":\n return scanDbToolScoping({\n root,\n denylist: config.dbToolScopingDenylist,\n });\n case \"no-env-mutation\":\n return scanEnvMutation({ root });\n case \"no-localhost-fallback\":\n return scanLocalhostFallback({ root, extraExemptPaths: [] });\n case \"migration-manifest\": {\n const imports = scanDeprecatedImports({\n root,\n manifests: migrationManifests,\n });\n return {\n name,\n findings: imports\n .filter((finding) => finding.status === \"active\")\n .map((finding) => ({\n file: path.relative(root, finding.file),\n line: finding.line,\n message: `${finding.from} moves to ${finding.to.join(\", \")}. Run: ${AGENT_NATIVE_UPGRADE_CODEMOD_COMMAND}`,\n })),\n warnings: imports\n .filter((finding) => finding.status === \"planned\")\n .map((finding) => ({\n file: path.relative(root, finding.file),\n line: finding.line,\n message: `${finding.from} is planned to move to ${finding.to.join(\", \")} in a future release. No rewrite is available yet.`,\n })),\n };\n }\n }\n}\n\nexport interface RunDoctorScanOptions {\n root: string;\n /** Restrict to these guard names. When omitted, runs every guard not\n * listed in `agent-native.json`'s `doctor.disabledGuards`. Unknown names\n * are silently ignored here — the CLI layer (`runDoctor`) validates\n * `--only` and reports a usage error before calling this. */\n only?: string[];\n migrationManifests?: MigrationManifest[];\n}\n\n/** Pure scan orchestrator: runs the selected guards against `root` and\n * returns a flat report. No I/O beyond reading `agent-native.json` and the\n * app source tree — no printing, no process.exit. */\nexport function runDoctorScan(options: RunDoctorScanOptions): DoctorReport {\n const root = options.root;\n const config = readDoctorConfig(root);\n\n let names: GuardName[];\n if (options.only && options.only.length > 0) {\n const knownOnly = options.only.filter((n): n is GuardName =>\n (ALL_GUARD_NAMES as string[]).includes(n),\n );\n names = knownOnly;\n } else {\n names = ALL_GUARD_NAMES.filter((n) => !config.disabledGuards.includes(n));\n }\n\n const findings: DoctorFinding[] = [];\n const warnings: DoctorFinding[] = [];\n for (const name of names) {\n const result = runGuard(name, root, config, options.migrationManifests);\n for (const f of result.findings) {\n findings.push({\n guard: name,\n file: f.file,\n line: f.line,\n message: f.message,\n });\n }\n for (const warning of result.warnings ?? []) {\n warnings.push({\n guard: name,\n file: warning.file,\n line: warning.line,\n message: warning.message,\n });\n }\n }\n\n return {\n ok: findings.length === 0,\n findings,\n warnings,\n guardsRun: names,\n };\n}\n\n/** Pure escalation rule shared by the CLI (`--strict`) and the `build`\n * pre-step (`--strict` / `agent-native.json` `doctor.failOnBuild`). Doctor\n * findings never fail anything on their own — only `strict` or\n * `failOnBuild` turn findings into a hard failure. */\nexport function shouldFailBuild(\n hasFindings: boolean,\n opts: { strict?: boolean; failOnBuild?: boolean },\n): boolean {\n return hasFindings && Boolean(opts.strict || opts.failOnBuild);\n}\n\nexport interface DoctorIo {\n log: (message: string) => void;\n err: (message: string) => void;\n}\n\nconst defaultIo: DoctorIo = {\n log: (message) => console.log(message),\n err: (message) => console.error(message),\n};\n\nfunction formatDoctorHuman(report: DoctorReport, root: string): string {\n const lines: string[] = [];\n lines.push(`agent-native doctor: ${root}`);\n lines.push(`Guards run: ${report.guardsRun.join(\", \") || \"(none)\"}`);\n if (report.findings.length === 0) {\n lines.push(\"Clean — no findings.\");\n } else {\n lines.push(`${report.findings.length} finding(s):`);\n for (const f of report.findings) {\n lines.push(` [${f.guard}] ${f.file}:${f.line} — ${f.message}`);\n }\n }\n if (report.warnings.length > 0) {\n lines.push(`${report.warnings.length} warning(s):`);\n for (const warning of report.warnings) {\n lines.push(\n ` [${warning.guard}] ${warning.file}:${warning.line} — ${warning.message}`,\n );\n }\n }\n return lines.join(\"\\n\");\n}\n\nexport interface DoctorCliOptions {\n json?: boolean;\n cwd?: string;\n only?: string[];\n strict?: boolean;\n help?: boolean;\n fix?: boolean;\n}\n\nexport function parseDoctorArgs(argv: string[]): DoctorCliOptions {\n const opts: DoctorCliOptions = {};\n for (let i = 0; i < argv.length; i++) {\n const arg = argv[i];\n if (arg === \"--help\" || arg === \"-h\") {\n opts.help = true;\n } else if (arg === \"--json\") {\n opts.json = true;\n } else if (arg === \"--strict\") {\n opts.strict = true;\n } else if (arg === \"--fix\") {\n opts.fix = true;\n } else if (arg === \"--cwd\" && argv[i + 1] !== undefined) {\n opts.cwd = argv[++i];\n } else if (arg.startsWith(\"--cwd=\")) {\n opts.cwd = arg.slice(\"--cwd=\".length);\n } else if (arg === \"--only\" && argv[i + 1] !== undefined) {\n opts.only = splitGuardList(argv[++i]);\n } else if (arg.startsWith(\"--only=\")) {\n opts.only = splitGuardList(arg.slice(\"--only=\".length));\n }\n }\n return opts;\n}\n\nfunction splitGuardList(value: string): string[] {\n return value\n .split(\",\")\n .map((s) => s.trim())\n .filter((s) => s.length > 0);\n}\n\nexport function printDoctorHelp(io: Pick<DoctorIo, \"log\"> = defaultIo): void {\n io.log(\n [\n \"Usage:\",\n \" agent-native doctor Scan app source for security-critical guard violations\",\n \" agent-native doctor --json Machine-readable report: { ok, findings, warnings, guardsRun, strict }\",\n \" agent-native doctor --only <guard,guard> Run only the named guard(s)\",\n \" agent-native doctor --strict Escalate findings to a hard failure when used by `agent-native build --strict`\",\n \" agent-native doctor --cwd <dir> Run against a project root other than the current directory\",\n \" agent-native doctor --fix Not implemented in this version\",\n \" agent-native doctor --help Show this help\",\n \"\",\n `Guards: ${ALL_GUARD_NAMES.join(\", \")}`,\n \"\",\n \"Exit codes: 0 clean, 1 findings present, 2 usage/execution error.\",\n \"\",\n \"`agent-native build` runs doctor as a warn-only pre-step by default — it\",\n \"never fails the build unless `agent-native build --strict` is passed or\",\n 'agent-native.json sets { \"doctor\": { \"failOnBuild\": true } }.',\n \"\",\n \"For dependency-pin health (framework overrides/patches, stale\",\n \"@agent-native/* pins), run `agent-native upgrade check` instead.\",\n `For import migrations, run \\`${AGENT_NATIVE_UPGRADE_CODEMOD_COMMAND}\\`.`,\n ].join(\"\\n\"),\n );\n}\n\n/** `agent-native doctor` CLI entrypoint. Returns the process exit code —\n * callers are responsible for calling `process.exit(code)`. */\nexport async function runDoctor(\n argv: string[],\n io: DoctorIo = defaultIo,\n): Promise<number> {\n const opts = parseDoctorArgs(argv);\n\n if (opts.help) {\n printDoctorHelp(io);\n return 0;\n }\n\n if (opts.fix) {\n io.err(\n \"agent-native doctor --fix is not implemented in this version. Fix findings manually and re-run `agent-native doctor`.\",\n );\n return 2;\n }\n\n const root = path.resolve(opts.cwd ?? process.cwd());\n if (!fs.existsSync(root) || !fs.statSync(root).isDirectory()) {\n const message = `--cwd path does not exist or is not a directory: ${root}`;\n if (opts.json) io.err(JSON.stringify({ ok: false, message }, null, 2));\n else io.err(message);\n return 2;\n }\n\n if (opts.only) {\n const unknown = opts.only.filter(\n (n) => !(ALL_GUARD_NAMES as string[]).includes(n),\n );\n if (unknown.length > 0) {\n const message = `Unknown guard name(s) in --only: ${unknown.join(\", \")}. Known guards: ${ALL_GUARD_NAMES.join(\", \")}`;\n if (opts.json) io.err(JSON.stringify({ ok: false, message }, null, 2));\n else io.err(message);\n return 2;\n }\n }\n\n const report = runDoctorScan({ root, only: opts.only });\n\n if (opts.json) {\n // The machine-readable report always goes to stdout (io.log), whether\n // or not findings are present, so `agent-native doctor --json >\n // report.json` in CI always captures the report. Only the usage/\n // execution error payloads above (bad --cwd, unknown --only) go to\n // stderr — those are diagnostics for exit code 2, not the report.\n io.log(\n JSON.stringify({ ...report, strict: Boolean(opts.strict) }, null, 2),\n );\n } else {\n io.log(formatDoctorHuman(report, root));\n if (!report.ok) {\n io.err(\"\");\n io.err(\n \"agent-native doctor found issues above. Fix them, or add a `// guard:allow-<check> — reason` opt-out with reviewer approval.\",\n );\n }\n }\n\n return report.ok ? 0 : 1;\n}\n\nexport interface DoctorBuildHookOptions {\n cwd: string;\n /** Set when the caller passed `agent-native build --strict`. */\n strict?: boolean;\n}\n\nexport interface DoctorBuildHookResult {\n /** False only when findings are present AND (`strict` was requested OR\n * `agent-native.json`'s `doctor.failOnBuild` is true). */\n ok: boolean;\n report: DoctorReport;\n}\n\n/**\n * `agent-native build`'s doctor pre-step. Always runs every enabled guard\n * and always prints findings (as warnings) to `io.err` — never silent.\n * Never causes the build to fail unless `strict` was passed or\n * `agent-native.json` sets `doctor.failOnBuild: true` (see report 005,\n * \"Where it runs\" — the v1 doctor has zero field mileage against arbitrary\n * app layouts, so shipping fail-by-default would risk breaking a first\n * deploy on a false positive).\n */\nexport async function runDoctorBuildHook(\n options: DoctorBuildHookOptions,\n io: DoctorIo = defaultIo,\n): Promise<DoctorBuildHookResult> {\n const root = path.resolve(options.cwd);\n const config = readDoctorConfig(root);\n const report = runDoctorScan({ root });\n\n if (report.findings.length > 0) {\n io.err(\n `\\n[doctor] ${report.findings.length} finding(s) from \\`agent-native doctor\\` — run it directly for details. This does not fail the build unless --strict was passed or agent-native.json's doctor.failOnBuild is true.`,\n );\n for (const f of report.findings) {\n io.err(` [${f.guard}] ${f.file}:${f.line} — ${f.message}`);\n }\n }\n if (report.warnings.length > 0) {\n io.err(\n `\\n[doctor] ${report.warnings.length} planned migration warning(s) — no rewrite is available yet.`,\n );\n for (const warning of report.warnings) {\n io.err(\n ` [${warning.guard}] ${warning.file}:${warning.line} — ${warning.message}`,\n );\n }\n }\n\n const fail = shouldFailBuild(report.findings.length > 0, {\n strict: options.strict,\n failOnBuild: config.failOnBuild,\n });\n if (fail) {\n io.err(\n `\\n[doctor] Failing build: ${options.strict ? \"--strict was passed\" : \"agent-native.json's doctor.failOnBuild is true\"}.`,\n );\n }\n\n return { ok: !fail, report };\n}\n"]}
1
+ {"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/cli/doctor.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * `agent-native doctor` — scan an app's source tree for the security-\n * critical code-safety invariants this monorepo already enforces on\n * itself via `scripts/guard-*.mjs` (see\n * `advisor-plans/reports/005-doctor-design.md` for the full design and\n * `advisor-plans/015-doctor-v1-implementation.md` for the implementation\n * plan). v1 ships 9 of those guards, ported to work against a single\n * generated app root instead of this monorepo's multi-template layout —\n * see `../guards/index.ts`.\n *\n * This is a NEW top-level command, deliberately kept separate from the two\n * existing \"doctor\" precedents in this CLI:\n * - `agent-native upgrade check` (`upgrade.ts`) — dependency-pin health.\n * - `agent-native recap doctor` (`recap.ts`) — PR Visual Recap config health.\n * Each diagnoses a different domain; none are folded into a shared\n * mega-doctor (see report 005, \"Relationship to upgrade doctor and recap\n * doctor\").\n *\n * `--fix` is reserved, not implemented in v1 — it prints a message and\n * exits 2 rather than silently no-op, so a future implementation doesn't\n * collide with a script already passing the flag.\n */\nimport fs from \"node:fs\";\nimport path from \"node:path\";\n\nimport {\n scanDbToolScoping,\n scanDrizzlePush,\n scanEnvCredentials,\n scanEnvMutation,\n scanExplicitCollabAccess,\n scanLocalhostFallback,\n scanUnscopedCredentials,\n scanUnscopedQueries,\n} from \"../guards/index.js\";\nimport type { GuardFinding, GuardResult } from \"../guards/index.js\";\nimport {\n AGENT_NATIVE_UPGRADE_CODEMOD_COMMAND,\n scanDeprecatedImports,\n type MigrationManifest,\n} from \"../package-lifecycle/index.js\";\n\nexport type GuardName =\n | \"no-drizzle-push\"\n | \"no-unscoped-credentials\"\n | \"no-unscoped-queries\"\n | \"no-env-credentials\"\n | \"db-tool-scoping\"\n | \"no-env-mutation\"\n | \"no-localhost-fallback\"\n | \"explicit-collab-access\"\n | \"migration-manifest\";\n\nexport const ALL_GUARD_NAMES: GuardName[] = [\n \"no-drizzle-push\",\n \"no-unscoped-credentials\",\n \"no-unscoped-queries\",\n \"no-env-credentials\",\n \"db-tool-scoping\",\n \"no-env-mutation\",\n \"no-localhost-fallback\",\n \"explicit-collab-access\",\n \"migration-manifest\",\n];\n\nexport interface DoctorConfig {\n disabledGuards: string[];\n dbToolScopingDenylist: Record<string, string>;\n failOnBuild: boolean;\n}\n\nconst DEFAULT_DOCTOR_CONFIG: DoctorConfig = {\n disabledGuards: [],\n dbToolScopingDenylist: {},\n failOnBuild: false,\n};\n\nexport interface DoctorFinding {\n guard: string;\n file: string;\n line: number;\n message: string;\n}\n\nexport interface DoctorReport {\n ok: boolean;\n findings: DoctorFinding[];\n warnings: DoctorFinding[];\n guardsRun: string[];\n}\n\ninterface DoctorGuardResult extends GuardResult {\n warnings?: GuardFinding[];\n}\n\n/**\n * Reads the optional `\"doctor\"` key from `<root>/agent-native.json`. All\n * fields are optional with sane empty defaults — an app needs zero config\n * to run `agent-native doctor` with every v1 guard enabled.\n */\nexport function readDoctorConfig(root: string): DoctorConfig {\n const manifestPath = path.join(root, \"agent-native.json\");\n if (!fs.existsSync(manifestPath)) {\n return { ...DEFAULT_DOCTOR_CONFIG, dbToolScopingDenylist: {} };\n }\n try {\n const raw = fs.readFileSync(manifestPath, \"utf-8\");\n const parsed = JSON.parse(raw) as { doctor?: Record<string, unknown> };\n const doctor = parsed.doctor ?? {};\n const disabledGuards = Array.isArray(doctor.disabledGuards)\n ? doctor.disabledGuards.filter((v): v is string => typeof v === \"string\")\n : [];\n const dbToolScopingDenylist =\n doctor.dbToolScopingDenylist &&\n typeof doctor.dbToolScopingDenylist === \"object\"\n ? (Object.fromEntries(\n Object.entries(\n doctor.dbToolScopingDenylist as Record<string, unknown>,\n ).filter(\n (entry): entry is [string, string] =>\n typeof entry[1] === \"string\",\n ),\n ) as Record<string, string>)\n : {};\n const failOnBuild = doctor.failOnBuild === true;\n return { disabledGuards, dbToolScopingDenylist, failOnBuild };\n } catch {\n return { ...DEFAULT_DOCTOR_CONFIG, dbToolScopingDenylist: {} };\n }\n}\n\nfunction runGuard(\n name: GuardName,\n root: string,\n config: DoctorConfig,\n migrationManifests?: MigrationManifest[],\n): DoctorGuardResult {\n switch (name) {\n case \"no-drizzle-push\":\n return scanDrizzlePush({ root });\n case \"no-unscoped-credentials\":\n return scanUnscopedCredentials({ root });\n case \"no-unscoped-queries\":\n return scanUnscopedQueries({ root, extraExemptPaths: [] });\n case \"no-env-credentials\":\n return scanEnvCredentials({ root });\n case \"db-tool-scoping\":\n return scanDbToolScoping({\n root,\n denylist: config.dbToolScopingDenylist,\n });\n case \"no-env-mutation\":\n return scanEnvMutation({ root });\n case \"no-localhost-fallback\":\n return scanLocalhostFallback({ root, extraExemptPaths: [] });\n case \"explicit-collab-access\":\n return scanExplicitCollabAccess({ root });\n case \"migration-manifest\": {\n const imports = scanDeprecatedImports({\n root,\n manifests: migrationManifests,\n });\n return {\n name,\n findings: imports\n .filter((finding) => finding.status === \"active\")\n .map((finding) => ({\n file: path.relative(root, finding.file),\n line: finding.line,\n message: `${finding.from} moves to ${finding.to.join(\", \")}. Run: ${AGENT_NATIVE_UPGRADE_CODEMOD_COMMAND}`,\n })),\n warnings: imports\n .filter((finding) => finding.status === \"planned\")\n .map((finding) => ({\n file: path.relative(root, finding.file),\n line: finding.line,\n message: `${finding.from} is planned to move to ${finding.to.join(\", \")} in a future release. No rewrite is available yet.`,\n })),\n };\n }\n }\n}\n\nexport interface RunDoctorScanOptions {\n root: string;\n /** Restrict to these guard names. When omitted, runs every guard not\n * listed in `agent-native.json`'s `doctor.disabledGuards`. Unknown names\n * are silently ignored here — the CLI layer (`runDoctor`) validates\n * `--only` and reports a usage error before calling this. */\n only?: string[];\n migrationManifests?: MigrationManifest[];\n}\n\n/** Pure scan orchestrator: runs the selected guards against `root` and\n * returns a flat report. No I/O beyond reading `agent-native.json` and the\n * app source tree — no printing, no process.exit. */\nexport function runDoctorScan(options: RunDoctorScanOptions): DoctorReport {\n const root = options.root;\n const config = readDoctorConfig(root);\n\n let names: GuardName[];\n if (options.only && options.only.length > 0) {\n const knownOnly = options.only.filter((n): n is GuardName =>\n (ALL_GUARD_NAMES as string[]).includes(n),\n );\n names = knownOnly;\n } else {\n names = ALL_GUARD_NAMES.filter((n) => !config.disabledGuards.includes(n));\n }\n\n const findings: DoctorFinding[] = [];\n const warnings: DoctorFinding[] = [];\n for (const name of names) {\n const result = runGuard(name, root, config, options.migrationManifests);\n for (const f of result.findings) {\n findings.push({\n guard: name,\n file: f.file,\n line: f.line,\n message: f.message,\n });\n }\n for (const warning of result.warnings ?? []) {\n warnings.push({\n guard: name,\n file: warning.file,\n line: warning.line,\n message: warning.message,\n });\n }\n }\n\n return {\n ok: findings.length === 0,\n findings,\n warnings,\n guardsRun: names,\n };\n}\n\n/** Pure escalation rule shared by the CLI (`--strict`) and the `build`\n * pre-step (`--strict` / `agent-native.json` `doctor.failOnBuild`). Doctor\n * findings never fail anything on their own — only `strict` or\n * `failOnBuild` turn findings into a hard failure. */\nexport function shouldFailBuild(\n hasFindings: boolean,\n opts: { strict?: boolean; failOnBuild?: boolean },\n): boolean {\n return hasFindings && Boolean(opts.strict || opts.failOnBuild);\n}\n\nexport interface DoctorIo {\n log: (message: string) => void;\n err: (message: string) => void;\n}\n\nconst defaultIo: DoctorIo = {\n log: (message) => console.log(message),\n err: (message) => console.error(message),\n};\n\nfunction formatDoctorHuman(report: DoctorReport, root: string): string {\n const lines: string[] = [];\n lines.push(`agent-native doctor: ${root}`);\n lines.push(`Guards run: ${report.guardsRun.join(\", \") || \"(none)\"}`);\n if (report.findings.length === 0) {\n lines.push(\"Clean — no findings.\");\n } else {\n lines.push(`${report.findings.length} finding(s):`);\n for (const f of report.findings) {\n lines.push(` [${f.guard}] ${f.file}:${f.line} — ${f.message}`);\n }\n }\n if (report.warnings.length > 0) {\n lines.push(`${report.warnings.length} warning(s):`);\n for (const warning of report.warnings) {\n lines.push(\n ` [${warning.guard}] ${warning.file}:${warning.line} — ${warning.message}`,\n );\n }\n }\n return lines.join(\"\\n\");\n}\n\nexport interface DoctorCliOptions {\n json?: boolean;\n cwd?: string;\n only?: string[];\n strict?: boolean;\n help?: boolean;\n fix?: boolean;\n}\n\nexport function parseDoctorArgs(argv: string[]): DoctorCliOptions {\n const opts: DoctorCliOptions = {};\n for (let i = 0; i < argv.length; i++) {\n const arg = argv[i];\n if (arg === \"--help\" || arg === \"-h\") {\n opts.help = true;\n } else if (arg === \"--json\") {\n opts.json = true;\n } else if (arg === \"--strict\") {\n opts.strict = true;\n } else if (arg === \"--fix\") {\n opts.fix = true;\n } else if (arg === \"--cwd\" && argv[i + 1] !== undefined) {\n opts.cwd = argv[++i];\n } else if (arg.startsWith(\"--cwd=\")) {\n opts.cwd = arg.slice(\"--cwd=\".length);\n } else if (arg === \"--only\" && argv[i + 1] !== undefined) {\n opts.only = splitGuardList(argv[++i]);\n } else if (arg.startsWith(\"--only=\")) {\n opts.only = splitGuardList(arg.slice(\"--only=\".length));\n }\n }\n return opts;\n}\n\nfunction splitGuardList(value: string): string[] {\n return value\n .split(\",\")\n .map((s) => s.trim())\n .filter((s) => s.length > 0);\n}\n\nexport function printDoctorHelp(io: Pick<DoctorIo, \"log\"> = defaultIo): void {\n io.log(\n [\n \"Usage:\",\n \" agent-native doctor Scan app source for security-critical guard violations\",\n \" agent-native doctor --json Machine-readable report: { ok, findings, warnings, guardsRun, strict }\",\n \" agent-native doctor --only <guard,guard> Run only the named guard(s)\",\n \" agent-native doctor --strict Escalate findings to a hard failure when used by `agent-native build --strict`\",\n \" agent-native doctor --cwd <dir> Run against a project root other than the current directory\",\n \" agent-native doctor --fix Not implemented in this version\",\n \" agent-native doctor --help Show this help\",\n \"\",\n `Guards: ${ALL_GUARD_NAMES.join(\", \")}`,\n \"\",\n \"Exit codes: 0 clean, 1 findings present, 2 usage/execution error.\",\n \"\",\n \"`agent-native build` runs doctor as a warn-only pre-step by default — it\",\n \"never fails the build unless `agent-native build --strict` is passed or\",\n 'agent-native.json sets { \"doctor\": { \"failOnBuild\": true } }.',\n \"\",\n \"For dependency-pin health (framework overrides/patches, stale\",\n \"@agent-native/* pins), run `agent-native upgrade check` instead.\",\n `For import migrations, run \\`${AGENT_NATIVE_UPGRADE_CODEMOD_COMMAND}\\`.`,\n ].join(\"\\n\"),\n );\n}\n\n/** `agent-native doctor` CLI entrypoint. Returns the process exit code —\n * callers are responsible for calling `process.exit(code)`. */\nexport async function runDoctor(\n argv: string[],\n io: DoctorIo = defaultIo,\n): Promise<number> {\n const opts = parseDoctorArgs(argv);\n\n if (opts.help) {\n printDoctorHelp(io);\n return 0;\n }\n\n if (opts.fix) {\n io.err(\n \"agent-native doctor --fix is not implemented in this version. Fix findings manually and re-run `agent-native doctor`.\",\n );\n return 2;\n }\n\n const root = path.resolve(opts.cwd ?? process.cwd());\n if (!fs.existsSync(root) || !fs.statSync(root).isDirectory()) {\n const message = `--cwd path does not exist or is not a directory: ${root}`;\n if (opts.json) io.err(JSON.stringify({ ok: false, message }, null, 2));\n else io.err(message);\n return 2;\n }\n\n if (opts.only) {\n const unknown = opts.only.filter(\n (n) => !(ALL_GUARD_NAMES as string[]).includes(n),\n );\n if (unknown.length > 0) {\n const message = `Unknown guard name(s) in --only: ${unknown.join(\", \")}. Known guards: ${ALL_GUARD_NAMES.join(\", \")}`;\n if (opts.json) io.err(JSON.stringify({ ok: false, message }, null, 2));\n else io.err(message);\n return 2;\n }\n }\n\n const report = runDoctorScan({ root, only: opts.only });\n\n if (opts.json) {\n // The machine-readable report always goes to stdout (io.log), whether\n // or not findings are present, so `agent-native doctor --json >\n // report.json` in CI always captures the report. Only the usage/\n // execution error payloads above (bad --cwd, unknown --only) go to\n // stderr — those are diagnostics for exit code 2, not the report.\n io.log(\n JSON.stringify({ ...report, strict: Boolean(opts.strict) }, null, 2),\n );\n } else {\n io.log(formatDoctorHuman(report, root));\n if (!report.ok) {\n io.err(\"\");\n io.err(\n \"agent-native doctor found issues above. Fix them, or add a `// guard:allow-<check> — reason` opt-out with reviewer approval.\",\n );\n }\n }\n\n return report.ok ? 0 : 1;\n}\n\nexport interface DoctorBuildHookOptions {\n cwd: string;\n /** Set when the caller passed `agent-native build --strict`. */\n strict?: boolean;\n}\n\nexport interface DoctorBuildHookResult {\n /** False only when findings are present AND (`strict` was requested OR\n * `agent-native.json`'s `doctor.failOnBuild` is true). */\n ok: boolean;\n report: DoctorReport;\n}\n\n/**\n * `agent-native build`'s doctor pre-step. Always runs every enabled guard\n * and always prints findings (as warnings) to `io.err` — never silent.\n * Never causes the build to fail unless `strict` was passed or\n * `agent-native.json` sets `doctor.failOnBuild: true` (see report 005,\n * \"Where it runs\" — the v1 doctor has zero field mileage against arbitrary\n * app layouts, so shipping fail-by-default would risk breaking a first\n * deploy on a false positive).\n */\nexport async function runDoctorBuildHook(\n options: DoctorBuildHookOptions,\n io: DoctorIo = defaultIo,\n): Promise<DoctorBuildHookResult> {\n const root = path.resolve(options.cwd);\n const config = readDoctorConfig(root);\n const report = runDoctorScan({ root });\n\n if (report.findings.length > 0) {\n io.err(\n `\\n[doctor] ${report.findings.length} finding(s) from \\`agent-native doctor\\` — run it directly for details. This does not fail the build unless --strict was passed or agent-native.json's doctor.failOnBuild is true.`,\n );\n for (const f of report.findings) {\n io.err(` [${f.guard}] ${f.file}:${f.line} — ${f.message}`);\n }\n }\n if (report.warnings.length > 0) {\n io.err(\n `\\n[doctor] ${report.warnings.length} planned migration warning(s) — no rewrite is available yet.`,\n );\n for (const warning of report.warnings) {\n io.err(\n ` [${warning.guard}] ${warning.file}:${warning.line} — ${warning.message}`,\n );\n }\n }\n\n const fail = shouldFailBuild(report.findings.length > 0, {\n strict: options.strict,\n failOnBuild: config.failOnBuild,\n });\n if (fail) {\n io.err(\n `\\n[doctor] Failing build: ${options.strict ? \"--strict was passed\" : \"agent-native.json's doctor.failOnBuild is true\"}.`,\n );\n }\n\n return { ok: !fail, report };\n}\n"]}
@@ -98,6 +98,7 @@ export interface AgentPanelProps extends Omit<AssistantChatProps, "onSwitchToCli
98
98
  codeAccess?: AgentPanelCodeAccess;
99
99
  }
100
100
  export declare function resolveAgentPanelChatSurface(explicitSurface: AgentChatSurfaceKind | undefined, desktopCodeSurfaceRequested: boolean): AgentChatSurfaceKind;
101
+ export declare function getActiveTabScrollDelta(containerRect: Pick<DOMRect, "left" | "right">, tabRect: Pick<DOMRect, "left" | "right">, margin?: number): number;
101
102
  export declare function AgentPanel(props: AgentPanelProps): React.JSX.Element;
102
103
  export type AgentChatSurfaceMode = "panel" | "page";
103
104
  export interface AgentChatSurfaceProps extends AgentPanelProps {
@@ -1 +1 @@
1
- {"version":3,"file":"AgentPanel.d.ts","sourceRoot":"","sources":["../../src/client/AgentPanel.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAmBH,OAAO,KASN,MAAM,OAAO,CAAC;AAmCf,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAapE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAY7D,OAAO,KAAK,EACV,gCAAgC,EAChC,0BAA0B,EAC3B,MAAM,4BAA4B,CAAC;AA0FpC,KAAK,SAAS,GAAG,MAAM,GAAG,KAAK,GAAG,WAAW,GAAG,UAAU,CAAC;AAC3D,wBAAgB,iCAAiC,CAC/C,IAAI,EAAE,SAAS,EACf,iBAAiB,EAAE,OAAO,GACzB,SAAS,CAEX;AA4LD,wBAAgB,0BAA0B,CACxC,IAAI,EAAE,gCAAgC,CAAC,MAAM,CAAC,EAC9C,WAAW,EAAE,MAAM;;;;;;EAcpB;AAED,wBAAgB,8BAA8B,CAC5C,IAAI,EAAE,gCAAgC,CAAC,MAAM,CAAC,EAC9C,WAAW,EAAE,MAAM,WAOpB;AAED,wBAAgB,mCAAmC,CACjD,IAAI,EAAE,gCAAgC,CAAC,MAAM,CAAC,WAG/C;AAED,wBAAgB,qCAAqC,CACnD,IAAI,EAAE,gCAAgC,CAAC,MAAM,CAAC,EAC9C,WAAW,EAAE,MAAM,EACnB,qBAAqB,EAAE,MAAM,WAO9B;AAED,wBAAgB,6BAA6B,CAAC,OAAO,EAAE,MAAM,EAAE,WAE9D;AAED,wBAAgB,+BAA+B,CAAC,SAAS,EAAE,OAAO,WAEjE;AAED,wBAAgB,kCAAkC,CAChD,aAAa,EAAE,MAAM,GAAG,SAAS,EACjC,IAAI,EAAE,SAAS,WAKhB;AAID,MAAM,WAAW,oBAAoB;IACnC,0EAA0E;IAC1E,OAAO,EAAE,OAAO,CAAC;IACjB,qDAAqD;IACrD,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,yDAAyD;IACzD,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,oDAAoD;IACpD,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,kDAAkD;IAClD,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,4EAA4E;IAC5E,4BAA4B,CAAC,EAAE,MAAM,CAAC;IACtC,mEAAmE;IACnE,2BAA2B,CAAC,EAAE,MAAM,CAAC;IACrC,wEAAwE;IACxE,8BAA8B,CAAC,EAAE,MAAM,CAAC;CACzC;AAgGD,MAAM,WAAW,eAAgB,SAAQ,IAAI,CAC3C,kBAAkB,EAClB,eAAe,CAChB;IACC,oCAAoC;IACpC,WAAW,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IAC7B,wCAAwC;IACxC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,6CAA6C;IAC7C,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;IAC5B,6GAA6G;IAC7G,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;IACxB,iFAAiF;IACjF,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,6HAA6H;IAC7H,kBAAkB,CAAC,EAAE,MAAM,IAAI,CAAC;IAChC,iGAAiG;IACjG,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,yFAAyF;IACzF,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,yEAAyE;IACzE,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,4DAA4D;IAC5D,KAAK,CAAC,EAAE,OAAO,uBAAuB,EAAE,eAAe,GAAG,IAAI,CAAC;IAC/D,iEAAiE;IACjE,cAAc,CAAC,EAAE,0BAA0B,CAAC,gBAAgB,CAAC,CAAC;IAC9D,mEAAmE;IACnE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,+CAA+C;IAC/C,aAAa,CAAC,EAAE,0BAA0B,CAAC,eAAe,CAAC,CAAC;IAC5D,gFAAgF;IAChF,UAAU,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC7B,mFAAmF;IACnF,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,kFAAkF;IAClF,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,kFAAkF;IAClF,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,mFAAmF;IACnF,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,uDAAuD;IACvD,UAAU,CAAC,EAAE,oBAAoB,CAAC;CACnC;AA8BD,wBAAgB,4BAA4B,CAC1C,eAAe,EAAE,oBAAoB,GAAG,SAAS,EACjD,2BAA2B,EAAE,OAAO,GACnC,oBAAoB,CAGtB;AAq4DD,wBAAgB,UAAU,CAAC,KAAK,EAAE,eAAe,qBAgBhD;AAED,MAAM,MAAM,oBAAoB,GAAG,OAAO,GAAG,MAAM,CAAC;AAEpD,MAAM,WAAW,qBAAsB,SAAQ,eAAe;IAC5D;;;;;OAKG;IACH,IAAI,CAAC,EAAE,oBAAoB,CAAC;IAC5B;;;;OAIG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B;AAED,wBAAgB,8CAA8C,CAC5D,IAAI,EAAE,oBAAoB,GAAG,SAAS,EACtC,WAAW,EAAE,OAAO,GAAG,SAAS,GAC/B,OAAO,CAET;AAED,wBAAgB,uCAAuC,CACrD,IAAI,EAAE,oBAAoB,GAAG,SAAS,EACtC,iBAAiB,EAAE,OAAO,GAAG,SAAS,GACrC,OAAO,CAET;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,EAC/B,IAAc,EACd,SAAS,EACT,WAAoB,EACpB,UAAkB,EAClB,UAAkB,EAClB,YAAY,EACZ,KAAK,EACL,kBAA0B,EAC1B,qBAAqB,EACrB,GAAG,KAAK,EACT,EAAE,qBAAqB,qBA6BvB;AAID,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,gDAAgD;IAChD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,gDAAgD;IAChD,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,+EAA+E;IAC/E,kBAAkB,CAAC,EAAE,kBAAkB,CAAC,oBAAoB,CAAC,CAAC;IAC9D,+DAA+D;IAC/D,mBAAmB,CAAC,EAAE,kBAAkB,CAAC,qBAAqB,CAAC,CAAC;IAChE,yEAAyE;IACzE,YAAY,CAAC,EAAE,kBAAkB,CAAC,cAAc,CAAC,CAAC;IAClD,6DAA6D;IAC7D,oBAAoB,CAAC,EAAE,kBAAkB,CAAC,sBAAsB,CAAC,CAAC;IAClE,iFAAiF;IACjF,cAAc,CAAC,EAAE,kBAAkB,CAAC,gBAAgB,CAAC,CAAC;IACtD,kEAAkE;IAClE,gBAAgB,CAAC,EAAE,kBAAkB,CAAC,kBAAkB,CAAC,CAAC;IAC1D;yDACqD;IACrD,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,uEAAuE;IACvE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,0DAA0D;IAC1D,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAC5B,sDAAsD;IACtD,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,kFAAkF;IAClF,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,wEAAwE;IACxE,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB;;;OAGG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,6EAA6E;IAC7E,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gEAAgE;IAChE,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,iFAAiF;IACjF,mBAAmB,CAAC,EAAE,MAAM,IAAI,CAAC;IACjC,4DAA4D;IAC5D,KAAK,CAAC,EAAE,OAAO,uBAAuB,EAAE,eAAe,GAAG,IAAI,CAAC;IAC/D,iEAAiE;IACjE,cAAc,CAAC,EAAE,0BAA0B,CAAC,gBAAgB,CAAC,CAAC;IAC9D,mEAAmE;IACnE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,+CAA+C;IAC/C,aAAa,CAAC,EAAE,0BAA0B,CAAC,eAAe,CAAC,CAAC;IAC5D,mFAAmF;IACnF,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,EAC3B,QAAQ,EACR,cAAsC,EACtC,WAAW,EACX,kBAAkB,EAClB,mBAAmB,EACnB,YAAY,EACZ,oBAAoB,EACpB,cAAc,EACd,gBAAgB,EAChB,mBAAmB,EACnB,YAAY,EACZ,QAAkB,EAClB,WAAmB,EACnB,aAAoB,EACpB,cAAqB,EACrB,kBAA0B,EAC1B,UAAU,EACV,iBAAyB,EACzB,mBAAmB,EACnB,KAAK,EACL,cAAc,EACd,YAAY,EACZ,aAAa,EACb,aAAa,GACd,EAAE,iBAAiB,qBAkmBnB;AAED;;;GAGG;AACH,wBAAgB,cAAc,SAqB7B;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,EAAE,SAAS,EAAE,EAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,4BAqCtE"}
1
+ {"version":3,"file":"AgentPanel.d.ts","sourceRoot":"","sources":["../../src/client/AgentPanel.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAmBH,OAAO,KASN,MAAM,OAAO,CAAC;AAmCf,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAapE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAY7D,OAAO,KAAK,EACV,gCAAgC,EAChC,0BAA0B,EAC3B,MAAM,4BAA4B,CAAC;AA0FpC,KAAK,SAAS,GAAG,MAAM,GAAG,KAAK,GAAG,WAAW,GAAG,UAAU,CAAC;AAC3D,wBAAgB,iCAAiC,CAC/C,IAAI,EAAE,SAAS,EACf,iBAAiB,EAAE,OAAO,GACzB,SAAS,CAEX;AA4LD,wBAAgB,0BAA0B,CACxC,IAAI,EAAE,gCAAgC,CAAC,MAAM,CAAC,EAC9C,WAAW,EAAE,MAAM;;;;;;EAcpB;AAED,wBAAgB,8BAA8B,CAC5C,IAAI,EAAE,gCAAgC,CAAC,MAAM,CAAC,EAC9C,WAAW,EAAE,MAAM,WAOpB;AAED,wBAAgB,mCAAmC,CACjD,IAAI,EAAE,gCAAgC,CAAC,MAAM,CAAC,WAG/C;AAED,wBAAgB,qCAAqC,CACnD,IAAI,EAAE,gCAAgC,CAAC,MAAM,CAAC,EAC9C,WAAW,EAAE,MAAM,EACnB,qBAAqB,EAAE,MAAM,WAO9B;AAED,wBAAgB,6BAA6B,CAAC,OAAO,EAAE,MAAM,EAAE,WAE9D;AAED,wBAAgB,+BAA+B,CAAC,SAAS,EAAE,OAAO,WAEjE;AAED,wBAAgB,kCAAkC,CAChD,aAAa,EAAE,MAAM,GAAG,SAAS,EACjC,IAAI,EAAE,SAAS,WAKhB;AAID,MAAM,WAAW,oBAAoB;IACnC,0EAA0E;IAC1E,OAAO,EAAE,OAAO,CAAC;IACjB,qDAAqD;IACrD,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,yDAAyD;IACzD,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,oDAAoD;IACpD,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,kDAAkD;IAClD,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,4EAA4E;IAC5E,4BAA4B,CAAC,EAAE,MAAM,CAAC;IACtC,mEAAmE;IACnE,2BAA2B,CAAC,EAAE,MAAM,CAAC;IACrC,wEAAwE;IACxE,8BAA8B,CAAC,EAAE,MAAM,CAAC;CACzC;AAgGD,MAAM,WAAW,eAAgB,SAAQ,IAAI,CAC3C,kBAAkB,EAClB,eAAe,CAChB;IACC,oCAAoC;IACpC,WAAW,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IAC7B,wCAAwC;IACxC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,6CAA6C;IAC7C,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;IAC5B,6GAA6G;IAC7G,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;IACxB,iFAAiF;IACjF,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,6HAA6H;IAC7H,kBAAkB,CAAC,EAAE,MAAM,IAAI,CAAC;IAChC,iGAAiG;IACjG,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,yFAAyF;IACzF,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,yEAAyE;IACzE,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,4DAA4D;IAC5D,KAAK,CAAC,EAAE,OAAO,uBAAuB,EAAE,eAAe,GAAG,IAAI,CAAC;IAC/D,iEAAiE;IACjE,cAAc,CAAC,EAAE,0BAA0B,CAAC,gBAAgB,CAAC,CAAC;IAC9D,mEAAmE;IACnE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,+CAA+C;IAC/C,aAAa,CAAC,EAAE,0BAA0B,CAAC,eAAe,CAAC,CAAC;IAC5D,gFAAgF;IAChF,UAAU,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC7B,mFAAmF;IACnF,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,kFAAkF;IAClF,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,kFAAkF;IAClF,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,mFAAmF;IACnF,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,uDAAuD;IACvD,UAAU,CAAC,EAAE,oBAAoB,CAAC;CACnC;AA8BD,wBAAgB,4BAA4B,CAC1C,eAAe,EAAE,oBAAoB,GAAG,SAAS,EACjD,2BAA2B,EAAE,OAAO,GACnC,oBAAoB,CAGtB;AAy8CD,wBAAgB,uBAAuB,CACrC,aAAa,EAAE,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,EAC9C,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,EACxC,MAAM,SAAK,GACV,MAAM,CAQR;AAsdD,wBAAgB,UAAU,CAAC,KAAK,EAAE,eAAe,qBAgBhD;AAED,MAAM,MAAM,oBAAoB,GAAG,OAAO,GAAG,MAAM,CAAC;AAEpD,MAAM,WAAW,qBAAsB,SAAQ,eAAe;IAC5D;;;;;OAKG;IACH,IAAI,CAAC,EAAE,oBAAoB,CAAC;IAC5B;;;;OAIG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B;AAED,wBAAgB,8CAA8C,CAC5D,IAAI,EAAE,oBAAoB,GAAG,SAAS,EACtC,WAAW,EAAE,OAAO,GAAG,SAAS,GAC/B,OAAO,CAET;AAED,wBAAgB,uCAAuC,CACrD,IAAI,EAAE,oBAAoB,GAAG,SAAS,EACtC,iBAAiB,EAAE,OAAO,GAAG,SAAS,GACrC,OAAO,CAET;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,EAC/B,IAAc,EACd,SAAS,EACT,WAAoB,EACpB,UAAkB,EAClB,UAAkB,EAClB,YAAY,EACZ,KAAK,EACL,kBAA0B,EAC1B,qBAAqB,EACrB,GAAG,KAAK,EACT,EAAE,qBAAqB,qBA6BvB;AAID,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,gDAAgD;IAChD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,gDAAgD;IAChD,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,+EAA+E;IAC/E,kBAAkB,CAAC,EAAE,kBAAkB,CAAC,oBAAoB,CAAC,CAAC;IAC9D,+DAA+D;IAC/D,mBAAmB,CAAC,EAAE,kBAAkB,CAAC,qBAAqB,CAAC,CAAC;IAChE,yEAAyE;IACzE,YAAY,CAAC,EAAE,kBAAkB,CAAC,cAAc,CAAC,CAAC;IAClD,6DAA6D;IAC7D,oBAAoB,CAAC,EAAE,kBAAkB,CAAC,sBAAsB,CAAC,CAAC;IAClE,iFAAiF;IACjF,cAAc,CAAC,EAAE,kBAAkB,CAAC,gBAAgB,CAAC,CAAC;IACtD,kEAAkE;IAClE,gBAAgB,CAAC,EAAE,kBAAkB,CAAC,kBAAkB,CAAC,CAAC;IAC1D;yDACqD;IACrD,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,uEAAuE;IACvE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,0DAA0D;IAC1D,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAC5B,sDAAsD;IACtD,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,kFAAkF;IAClF,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,wEAAwE;IACxE,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB;;;OAGG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,6EAA6E;IAC7E,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gEAAgE;IAChE,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,iFAAiF;IACjF,mBAAmB,CAAC,EAAE,MAAM,IAAI,CAAC;IACjC,4DAA4D;IAC5D,KAAK,CAAC,EAAE,OAAO,uBAAuB,EAAE,eAAe,GAAG,IAAI,CAAC;IAC/D,iEAAiE;IACjE,cAAc,CAAC,EAAE,0BAA0B,CAAC,gBAAgB,CAAC,CAAC;IAC9D,mEAAmE;IACnE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,+CAA+C;IAC/C,aAAa,CAAC,EAAE,0BAA0B,CAAC,eAAe,CAAC,CAAC;IAC5D,mFAAmF;IACnF,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,EAC3B,QAAQ,EACR,cAAsC,EACtC,WAAW,EACX,kBAAkB,EAClB,mBAAmB,EACnB,YAAY,EACZ,oBAAoB,EACpB,cAAc,EACd,gBAAgB,EAChB,mBAAmB,EACnB,YAAY,EACZ,QAAkB,EAClB,WAAmB,EACnB,aAAoB,EACpB,cAAqB,EACrB,kBAA0B,EAC1B,UAAU,EACV,iBAAyB,EACzB,mBAAmB,EACnB,KAAK,EACL,cAAc,EACd,YAAY,EACZ,aAAa,EACb,aAAa,GACd,EAAE,iBAAiB,qBAkmBnB;AAED;;;GAGG;AACH,wBAAgB,cAAc,SAqB7B;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,EAAE,SAAS,EAAE,EAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,4BAqCtE"}
@@ -27,7 +27,7 @@ import React, { useState, useEffect, useRef, useCallback, useMemo, lazy, Suspens
27
27
  import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuTrigger, } from "./components/ui/dropdown-menu.js";
28
28
  import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, normalizeTooltipText, } from "./components/ui/tooltip.js";
29
29
  import { ErrorReportActions } from "./ErrorReportActions.js";
30
- import { FeedbackButton } from "./FeedbackButton.js";
30
+ import { FeedbackButton, resolveFeedbackUrl } from "./FeedbackButton.js";
31
31
  import { RunsTrayMenuItem } from "./progress/RunsTray.js";
32
32
  import { ShareButton } from "./sharing/ShareButton.js";
33
33
  // Lazy-load the full assistant-ui chat stack (tiptap composer + react-markdown +
@@ -378,6 +378,7 @@ function CodeAccessUnavailablePanel({ title, description, ctaLabel, ctaHref, sec
378
378
  }
379
379
  function AgentPanelInner({ defaultMode = "chat", className, style, apiUrl, emptyStateText, emptyStateAddon, suggestions, dynamicSuggestions, showHeader = true, onCollapse, isFullscreen, onToggleFullscreen, devAppUrl, storageKey, restoreActiveThread = true, scope, showScopeBadge, browserTabId, threadUrlSync, chatNotice, showTabBar = true, showPageNewChatButton = false, allowSettingsMode = true, agentPageHref, codeAccess, ...assistantChatProps }) {
380
380
  const t = useT();
381
+ const feedbackEnabled = resolveFeedbackUrl() !== null;
381
382
  const navigate = useNavigate();
382
383
  const mounted = useClientOnly();
383
384
  const keyPrefix = storageKey ? `:${storageKey}` : "";
@@ -639,18 +640,18 @@ function AgentPanelInner({ defaultMode = "chat", className, style, apiUrl, empty
639
640
  return null;
640
641
  }
641
642
  return (_jsx(ShareButton, { resourceType: "chat_thread", resourceId: activeTab.id, resourceTitle: activeTab.label || "Chat", shareUrl: getChatThreadShareUrl(activeTab.id), trigger: "icon", triggerClassName: "h-7 w-7" }));
642
- })(), _jsx(FeedbackButton, { variant: "icon", side: "bottom", align: "end", chatSessionId: activeChatSessionId, chatStorageKey: storageKey, open: feedbackOpen, onOpenChange: setFeedbackOpen, trigger: _jsx("button", { type: "button", tabIndex: -1, "aria-hidden": "true", className: "pointer-events-none absolute end-0 top-full h-px w-px opacity-0" }) }), mode === "chat" && (_jsx(IconTooltip, { content: t("agentPanel.newChat"), children: _jsx("button", { onClick: addTab, "aria-label": t("agentPanel.newChat"), className: "flex h-6 w-6 items-center justify-center rounded text-muted-foreground hover:text-foreground hover:bg-accent/50", children: _jsx(IconPlus, { size: 14 }) }) })), !onCollapse && mode === "cli" && canUseCodeTools && (_jsx(IconTooltip, { content: t("agentPanel.newTerminal"), children: _jsx("button", { onClick: addCliTab, "aria-label": t("agentPanel.newTerminal"), className: "flex h-6 w-6 items-center justify-center rounded text-muted-foreground hover:text-foreground hover:bg-accent/50", children: _jsx(IconPlus, { size: 14 }) }) })), agentPageHref &&
643
+ })(), feedbackEnabled ? (_jsx(FeedbackButton, { variant: "icon", side: "bottom", align: "end", chatSessionId: activeChatSessionId, chatStorageKey: storageKey, open: feedbackOpen, onOpenChange: setFeedbackOpen, trigger: _jsx("button", { type: "button", tabIndex: -1, "aria-hidden": "true", className: "pointer-events-none absolute end-0 top-full h-px w-px opacity-0" }) })) : null, mode === "chat" && (_jsx(IconTooltip, { content: t("agentPanel.newChat"), children: _jsx("button", { onClick: addTab, "aria-label": t("agentPanel.newChat"), className: "flex h-6 w-6 items-center justify-center rounded text-muted-foreground hover:text-foreground hover:bg-accent/50", children: _jsx(IconPlus, { size: 14 }) }) })), !onCollapse && mode === "cli" && canUseCodeTools && (_jsx(IconTooltip, { content: t("agentPanel.newTerminal"), children: _jsx("button", { onClick: addCliTab, "aria-label": t("agentPanel.newTerminal"), className: "flex h-6 w-6 items-center justify-center rounded text-muted-foreground hover:text-foreground hover:bg-accent/50", children: _jsx(IconPlus, { size: 14 }) }) })), agentPageHref &&
643
644
  shouldShowAgentPanelFullViewAction(agentPageHref, mode) && (_jsx(IconTooltip, { content: t("agentPanel.openFullView"), children: _jsx(Link, { to: agentPageHref, "aria-label": t("agentPanel.openFullView"), className: "flex h-6 w-6 items-center justify-center rounded text-muted-foreground hover:bg-accent/50 hover:text-foreground", children: _jsx(IconArrowsMaximize, { size: 14 }) }) })), _jsxs(DropdownMenu, { open: headerMenuOpen, onOpenChange: setHeaderMenuOpen, children: [_jsx(DropdownMenuTrigger, { asChild: true, children: _jsx("button", { className: cn("flex h-6 w-6 items-center justify-center rounded text-muted-foreground hover:text-foreground hover:bg-accent/50", (headerMenuOpen || mode === "settings") &&
644
645
  "bg-accent text-foreground"), "aria-label": t("agentPanel.panelOptions"), children: _jsx(IconDotsVertical, { size: 14 }) }) }), _jsxs(DropdownMenuContent, { align: "end", sideOffset: 6, className: "w-48", children: [onCollapse && (_jsxs(_Fragment, { children: [_jsxs(DropdownMenuItem, { onSelect: onCollapse, children: [_jsx(IconLayoutSidebarRightCollapse, { size: 14, className: "shrink-0" }), t("agentPanel.collapseSidebar"), _jsx(DropdownMenuShortcut, { children: toggleSidebarHint })] }), _jsx(DropdownMenuSeparator, {})] })), onCollapse && mode === "chat" && (_jsxs(DropdownMenuItem, { onSelect: addTab, children: [_jsx(IconPlus, { size: 14, className: "shrink-0" }), t("agentPanel.newChat")] })), mode === "chat" && toggleHistory && (_jsxs(DropdownMenuItem, { onSelect: toggleHistory, children: [_jsx(IconHistory, { size: 14, className: "shrink-0" }), showHistory
645
646
  ? t("agentPanel.hideChats")
646
647
  : t("agentPanel.allChats")] })), mode === "chat" && (_jsx(RunsTrayMenuItem, { pollMs: 0, limit: 12, showRecent: true, onOpenThread: openRunThread })), mode === "chat" && _jsx(DropdownMenuSeparator, {}), mode === "cli" && availableClis.length > 0 && (_jsxs(_Fragment, { children: [availableClis.map((cli) => (_jsxs(DropdownMenuItem, { onSelect: () => selectCli(cli.command), className: cn(cli.command === selectedCli
647
648
  ? "font-medium"
648
- : "text-muted-foreground"), children: [cli.command === selectedCli ? (_jsx(IconCheck, { size: 12, className: "shrink-0" })) : (_jsx("span", { className: "w-3" })), cli.label] }, cli.command))), _jsx(DropdownMenuSeparator, {})] })), allowSettingsMode && (_jsxs(DropdownMenuItem, { onSelect: () => switchMode("settings"), className: cn(mode === "settings" ? "font-medium" : "text-muted-foreground"), children: [_jsx(IconSettings, { size: 14, className: "shrink-0" }), t("agentPanel.settings")] })), _jsxs(DropdownMenuItem, { onSelect: () => {
649
+ : "text-muted-foreground"), children: [cli.command === selectedCli ? (_jsx(IconCheck, { size: 12, className: "shrink-0" })) : (_jsx("span", { className: "w-3" })), cli.label] }, cli.command))), _jsx(DropdownMenuSeparator, {})] })), allowSettingsMode && (_jsxs(DropdownMenuItem, { onSelect: () => switchMode("settings"), className: cn(mode === "settings" ? "font-medium" : "text-muted-foreground"), children: [_jsx(IconSettings, { size: 14, className: "shrink-0" }), t("agentPanel.settings")] })), feedbackEnabled ? (_jsxs(DropdownMenuItem, { onSelect: () => {
649
650
  // Defer past the closing DropdownMenu's focus-restore/dismiss-layer
650
651
  // teardown, otherwise it can immediately dismiss the Popover we're
651
652
  // opening in the same tick (Radix nested-overlay race).
652
653
  setTimeout(() => setFeedbackOpen(true), 0);
653
- }, children: [_jsx(IconMessageDots, { size: 14, className: "shrink-0" }), t("agentPanel.feedback")] }), onToggleFullscreen && (_jsxs(DropdownMenuItem, { onSelect: onToggleFullscreen, children: [isFullscreen ? (_jsx(IconArrowsMinimize, { size: 14, className: "shrink-0" })) : (_jsx(IconArrowsMaximize, { size: 14, className: "shrink-0" })), isFullscreen
654
+ }, children: [_jsx(IconMessageDots, { size: 14, className: "shrink-0" }), t("agentPanel.feedback")] })) : null, onToggleFullscreen && (_jsxs(DropdownMenuItem, { onSelect: onToggleFullscreen, children: [isFullscreen ? (_jsx(IconArrowsMinimize, { size: 14, className: "shrink-0" })) : (_jsx(IconArrowsMaximize, { size: 14, className: "shrink-0" })), isFullscreen
654
655
  ? t("agentPanel.exitFullscreen")
655
656
  : t("agentPanel.fullscreen")] })), ((mode === "chat" && activeTabId) ||
656
657
  (mode === "cli" && canUseCodeTools && activeCliTab)) && (_jsxs(_Fragment, { children: [_jsx(DropdownMenuSeparator, {}), mode === "chat" ? (shouldShowAgentPanelChatTabBar(tabs, activeTabId) ? (_jsxs(_Fragment, { children: [_jsxs(DropdownMenuItem, { onSelect: () => closeTab(activeTabId), children: [_jsx(IconX, { size: 14, className: "shrink-0" }), t("agentPanel.closeTab"), _jsx(DropdownMenuShortcut, { children: closeTabHint })] }), _jsx(DropdownMenuItem, { onSelect: () => closeOtherTabs(activeTabId), children: t("agentPanel.closeOtherTabs") }), _jsxs(DropdownMenuItem, { onSelect: () => closeAllTabs(), children: [t("agentPanel.closeAllTabs"), _jsx(DropdownMenuShortcut, { children: closeAllTabsHint })] })] })) : (_jsxs(DropdownMenuItem, { onSelect: clearActiveTab, children: [_jsx(IconX, { size: 14, className: "shrink-0" }), t("agentPanel.clearChat")] }))) : (_jsxs(_Fragment, { children: [_jsxs(DropdownMenuItem, { onSelect: () => closeCliTab(activeCliTab), children: [_jsx(IconX, { size: 14, className: "shrink-0" }), t("agentPanel.closeTab"), _jsx(DropdownMenuShortcut, { children: closeTabHint })] }), _jsx(DropdownMenuItem, { onSelect: () => closeOtherCliTabs(activeCliTab), children: t("agentPanel.closeOtherTabs") }), _jsxs(DropdownMenuItem, { onSelect: () => closeAllCliTabs(), children: [t("agentPanel.closeAllTabs"), _jsx(DropdownMenuShortcut, { children: closeAllTabsHint })] })] }))] }))] })] }), onCollapse && (_jsx(IconTooltip, { content: t("agentPanel.collapseSidebar"), children: _jsx("button", { type: "button", onClick: onCollapse, "aria-label": t("agentPanel.collapseSidebar"), className: "flex h-6 w-6 items-center justify-center rounded text-muted-foreground hover:text-foreground hover:bg-accent/50", children: _jsx(IconX, { size: 14 }) }) }))] })), [
@@ -665,6 +666,7 @@ function AgentPanelInner({ defaultMode = "chat", className, style, apiUrl, empty
665
666
  closeOtherCliTabs,
666
667
  closeTabHint,
667
668
  feedbackOpen,
669
+ feedbackEnabled,
668
670
  getChatThreadShareUrl,
669
671
  headerMenuOpen,
670
672
  isFullscreen,
@@ -691,26 +693,35 @@ function AgentPanelInner({ defaultMode = "chat", className, style, apiUrl, empty
691
693
  addTab();
692
694
  }, className: "inline-flex h-8 items-center gap-1.5 rounded-md border border-border bg-background/95 px-2.5 text-xs font-medium text-foreground shadow-sm backdrop-blur transition-colors hover:bg-accent focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring", children: [_jsx(IconPlus, { size: 14 }), _jsx("span", { children: t("agentPanel.newChat") })] })] }) })] }));
693
695
  }, [getChatThreadShareUrl, t]);
694
- // Ref callback: scroll the active tab into view in the overflow container.
695
- // Uses getBoundingClientRect for reliable positioning regardless of offsetParent.
696
- const activeTabRefCb = useCallback((el) => {
697
- if (!el)
698
- return;
696
+ const activeTabResizeObserverRef = useRef(null);
697
+ const scrollActiveTabIntoView = useCallback((el) => {
699
698
  const container = el.parentElement;
700
699
  if (!container)
701
700
  return;
702
- // Use rAF so layout is settled after React commit
703
701
  requestAnimationFrame(() => {
704
- const containerRect = container.getBoundingClientRect();
705
- const tabRect = el.getBoundingClientRect();
706
- if (tabRect.left < containerRect.left) {
707
- container.scrollLeft += tabRect.left - containerRect.left;
708
- }
709
- else if (tabRect.right > containerRect.right) {
710
- container.scrollLeft += tabRect.right - containerRect.right;
711
- }
702
+ const delta = getActiveTabScrollDelta(container.getBoundingClientRect(), el.getBoundingClientRect());
703
+ if (delta !== 0)
704
+ container.scrollLeft += delta;
712
705
  });
713
706
  }, []);
707
+ // The sidebar stays mounted while closed and animates its width on open, so
708
+ // the active tab ref alone can run before the overflow container is usable.
709
+ const activeTabRefCb = useCallback((el) => {
710
+ activeTabResizeObserverRef.current?.disconnect();
711
+ activeTabResizeObserverRef.current = null;
712
+ if (!el)
713
+ return;
714
+ const container = el.parentElement;
715
+ if (!container)
716
+ return;
717
+ const observer = typeof ResizeObserver === "undefined"
718
+ ? null
719
+ : new ResizeObserver(() => scrollActiveTabIntoView(el));
720
+ observer?.observe(container);
721
+ activeTabResizeObserverRef.current = observer;
722
+ scrollActiveTabIntoView(el);
723
+ }, [scrollActiveTabIntoView]);
724
+ useEffect(() => () => activeTabResizeObserverRef.current?.disconnect(), []);
714
725
  const renderChatHeader = useCallback(({ tabs, activeTabId, activeTabMessageCount, setActiveTabId, addTab, clearActiveTab, closeTab, closeOtherTabs, closeAllTabs, showHistory, toggleHistory, }) => {
715
726
  const { activeTab, childTabs, focusParentId, hasSubTabs, mainTabs } = getAgentPanelChatTabGroups(tabs, activeTabId);
716
727
  const showSidebarChatTabs = Boolean(onCollapse) &&
@@ -870,6 +881,15 @@ const SIDEBAR_OVERLAY_Z_INDEX = 70;
870
881
  const SIDEBAR_FULLSCREEN_Z_INDEX = 90;
871
882
  /** Shared max width of the centered fullscreen chat column and composer. */
872
883
  const FULLSCREEN_CHAT_COLUMN_MAX_PX = 684;
884
+ export function getActiveTabScrollDelta(containerRect, tabRect, margin = 24) {
885
+ if (tabRect.left < containerRect.left + margin) {
886
+ return tabRect.left - containerRect.left - margin;
887
+ }
888
+ if (tabRect.right > containerRect.right - margin) {
889
+ return tabRect.right - containerRect.right + margin;
890
+ }
891
+ return 0;
892
+ }
873
893
  function ResizeHandle({ position, onDrag, onResizeStart, onResizeEnd, }) {
874
894
  const ref = useRef(null);
875
895
  const dragging = useRef(false);