@agent-native/core 0.99.3 → 0.100.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (382) hide show
  1. package/corpus/README.md +2 -2
  2. package/corpus/core/CHANGELOG.md +21 -0
  3. package/corpus/core/docs/content/agent-surfaces.mdx +43 -0
  4. package/corpus/core/docs/content/external-agents.mdx +11 -0
  5. package/corpus/core/docs/content/locales/ar-SA/agent-surfaces.mdx +30 -0
  6. package/corpus/core/docs/content/locales/ar-SA/external-agents.mdx +9 -0
  7. package/corpus/core/docs/content/locales/de-DE/agent-surfaces.mdx +34 -0
  8. package/corpus/core/docs/content/locales/de-DE/external-agents.mdx +10 -0
  9. package/corpus/core/docs/content/locales/es-ES/agent-surfaces.mdx +34 -0
  10. package/corpus/core/docs/content/locales/es-ES/external-agents.mdx +10 -0
  11. package/corpus/core/docs/content/locales/fr-FR/agent-surfaces.mdx +34 -0
  12. package/corpus/core/docs/content/locales/fr-FR/external-agents.mdx +11 -0
  13. package/corpus/core/docs/content/locales/hi-IN/agent-surfaces.mdx +31 -0
  14. package/corpus/core/docs/content/locales/hi-IN/external-agents.mdx +9 -0
  15. package/corpus/core/docs/content/locales/ja-JP/agent-surfaces.mdx +32 -0
  16. package/corpus/core/docs/content/locales/ja-JP/external-agents.mdx +10 -0
  17. package/corpus/core/docs/content/locales/ko-KR/agent-surfaces.mdx +32 -0
  18. package/corpus/core/docs/content/locales/ko-KR/external-agents.mdx +9 -0
  19. package/corpus/core/docs/content/locales/pt-BR/agent-surfaces.mdx +33 -0
  20. package/corpus/core/docs/content/locales/pt-BR/external-agents.mdx +10 -0
  21. package/corpus/core/docs/content/locales/zh-CN/agent-surfaces.mdx +29 -0
  22. package/corpus/core/docs/content/locales/zh-CN/external-agents.mdx +8 -0
  23. package/corpus/core/docs/content/locales/zh-TW/agent-surfaces.mdx +29 -0
  24. package/corpus/core/docs/content/locales/zh-TW/external-agents.mdx +8 -0
  25. package/corpus/core/package.json +1 -1
  26. package/corpus/core/src/agent/context-xray/actions/context-evict.ts +11 -0
  27. package/corpus/core/src/agent/context-xray/actions/context-pin.ts +11 -0
  28. package/corpus/core/src/agent/context-xray/actions/context-preview-get.ts +134 -0
  29. package/corpus/core/src/agent/context-xray/actions/context-restore.ts +11 -0
  30. package/corpus/core/src/agent/context-xray/actions/errors.ts +20 -0
  31. package/corpus/core/src/agent/context-xray/manifest.ts +106 -7
  32. package/corpus/core/src/agent/engine/context-directives-transform.ts +5 -1
  33. package/corpus/core/src/agent/production-agent.ts +100 -38
  34. package/corpus/core/src/agent/run-loop-with-resume.ts +7 -2
  35. package/corpus/core/src/client/AgentPanel.tsx +35 -8
  36. package/corpus/core/src/client/agent-page/AgentContextTab.tsx +501 -0
  37. package/corpus/core/src/client/agent-page/AgentJobsTab.tsx +370 -0
  38. package/corpus/core/src/client/agent-page/AgentTabsPage.tsx +1084 -0
  39. package/corpus/core/src/client/agent-page/types.ts +18 -0
  40. package/corpus/core/src/client/agent-page/use-jobs.ts +150 -0
  41. package/corpus/core/src/client/context-xray/ContextMeter.tsx +22 -5
  42. package/corpus/core/src/client/context-xray/ContextTreemap.tsx +16 -1
  43. package/corpus/core/src/client/context-xray/ContextXRayPanel.tsx +168 -3
  44. package/corpus/core/src/client/context-xray/format.ts +6 -0
  45. package/corpus/core/src/client/index.ts +6 -0
  46. package/corpus/core/src/client/resources/ResourcesPanel.tsx +51 -23
  47. package/corpus/core/src/client/settings/AutomationsSection.tsx +407 -387
  48. package/corpus/core/src/jobs/actions/list-recurring-jobs.ts +105 -0
  49. package/corpus/core/src/jobs/actions/manage-recurring-job.ts +85 -0
  50. package/corpus/core/src/jobs/tools.ts +1 -1
  51. package/corpus/core/src/localization/default-messages.ts +110 -0
  52. package/corpus/core/src/mcp/build-server.ts +1 -0
  53. package/corpus/core/src/mcp/connect-route.ts +62 -65
  54. package/corpus/core/src/server/action-discovery.ts +23 -0
  55. package/corpus/core/src/server/agent-chat/prompt-resources.ts +174 -2
  56. package/corpus/core/src/server/agent-chat-plugin.ts +175 -2
  57. package/corpus/core/src/server/auth.ts +1 -7
  58. package/corpus/core/src/server/google-oauth.ts +1 -7
  59. package/corpus/core/src/server/workspace-oauth.ts +31 -0
  60. package/corpus/core/src/shared/context-xray.ts +84 -1
  61. package/corpus/core/src/shared/mcp-connect-content.ts +130 -0
  62. package/corpus/core/src/templates/default/app/routes/_index.tsx +11 -0
  63. package/corpus/core/src/templates/default/app/routes/agent.tsx +33 -0
  64. package/corpus/core/src/templates/workspace-core/.agents/skills/agent-native-toolkit/SKILL.md +6 -0
  65. package/corpus/core/src/templates/workspace-core/.agents/skills/agent-page/SKILL.md +59 -0
  66. package/corpus/core/src/templates/workspace-core/.agents/skills/context-xray/SKILL.md +25 -0
  67. package/corpus/core/src/templates/workspace-core/.agents/skills/external-agents/SKILL.md +7 -0
  68. package/corpus/core/src/templates/workspace-core/.agents/skills/recurring-jobs/SKILL.md +9 -0
  69. package/corpus/core/src/triggers/actions/list-automations.ts +99 -0
  70. package/corpus/core/src/triggers/actions/manage-automation.ts +78 -0
  71. package/corpus/templates/analytics/actions/data-source-status.ts +33 -15
  72. package/corpus/templates/analytics/actions/query-agent-native-analytics.ts +1 -1
  73. package/corpus/templates/analytics/app/components/dashboard/SqlChart.tsx +149 -24
  74. package/corpus/templates/analytics/app/components/layout/CommandPalette.tsx +17 -0
  75. package/corpus/templates/analytics/app/components/layout/Header.tsx +1 -0
  76. package/corpus/templates/analytics/app/components/layout/Layout.tsx +1 -0
  77. package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +8 -0
  78. package/corpus/templates/analytics/app/i18n/zh-TW.ts +1 -0
  79. package/corpus/templates/analytics/app/i18n-data.ts +1 -0
  80. package/corpus/templates/analytics/app/routes/agent.tsx +5 -0
  81. package/corpus/templates/analytics/changelog/2026-07-13-a-full-agent-page-now-brings-context-files-connections-jobs-.md +6 -0
  82. package/corpus/templates/analytics/changelog/2026-07-13-analytics-answers-can-use-built-in-first-party-event-data.md +6 -0
  83. package/corpus/templates/analytics/changelog/2026-07-13-chart-legends-can-filter-to-one-series-or-hide-a-series-on-h.md +6 -0
  84. package/corpus/templates/analytics/changelog/2026-07-13-gpt-5-6-luna-answers-now-recover-normally-instead-of-showing.md +6 -0
  85. package/corpus/templates/analytics/server/plugins/agent-chat.ts +11 -2
  86. package/corpus/templates/assets/app/components/layout/Header.tsx +1 -0
  87. package/corpus/templates/assets/app/components/layout/Layout.tsx +1 -0
  88. package/corpus/templates/assets/app/components/layout/Sidebar.tsx +2 -0
  89. package/corpus/templates/assets/app/routes/agent.tsx +5 -0
  90. package/corpus/templates/assets/changelog/2026-07-13-a-full-agent-page-now-brings-context-files-connections-jobs-.md +6 -0
  91. package/corpus/templates/brain/app/components/layout/Layout.tsx +1 -0
  92. package/corpus/templates/brain/app/components/layout/Sidebar.tsx +4 -1
  93. package/corpus/templates/brain/app/lib/brain.ts +11 -0
  94. package/corpus/templates/brain/app/root.tsx +15 -1
  95. package/corpus/templates/brain/app/routes/agent.tsx +11 -0
  96. package/corpus/templates/brain/changelog/2026-07-13-a-full-agent-page-now-brings-context-files-connections-jobs-.md +6 -0
  97. package/corpus/templates/calendar/AGENTS.md +9 -0
  98. package/corpus/templates/calendar/actions/list-events.ts +659 -44
  99. package/corpus/templates/calendar/app/components/layout/AppLayout.tsx +1 -0
  100. package/corpus/templates/calendar/app/components/layout/Sidebar.tsx +2 -0
  101. package/corpus/templates/calendar/app/root.tsx +17 -1
  102. package/corpus/templates/calendar/app/routes/_app.agent.tsx +25 -0
  103. package/corpus/templates/calendar/changelog/2026-07-13-a-full-agent-page-now-brings-context-files-connections-jobs-.md +6 -0
  104. package/corpus/templates/calendar/changelog/2026-07-13-calendar-inventory-reads-report-source-coverage.md +6 -0
  105. package/corpus/templates/calendar/server/lib/calendar-connector-catalog.ts +8 -0
  106. package/corpus/templates/calendar/server/lib/google-calendar.ts +173 -51
  107. package/corpus/templates/calendar/server/lib/ical-fetcher.ts +13 -2
  108. package/corpus/templates/calendar/server/plugins/agent-chat.ts +5 -3
  109. package/corpus/templates/calendar/shared/api.ts +2 -0
  110. package/corpus/templates/chat/app/components/layout/Header.tsx +1 -0
  111. package/corpus/templates/chat/app/components/layout/Layout.tsx +1 -0
  112. package/corpus/templates/chat/app/components/layout/Sidebar.tsx +7 -0
  113. package/corpus/templates/chat/app/hooks/use-navigation-state.ts +3 -0
  114. package/corpus/templates/chat/app/root.tsx +24 -2
  115. package/corpus/templates/chat/app/routes/agent.tsx +15 -0
  116. package/corpus/templates/chat/changelog/2026-07-13-a-full-agent-page-now-brings-context-files-connections-jobs-.md +6 -0
  117. package/corpus/templates/clips/app/components/library/library-layout.tsx +8 -0
  118. package/corpus/templates/clips/app/i18n/ar-SA.ts +2 -0
  119. package/corpus/templates/clips/app/i18n/de-DE.ts +2 -0
  120. package/corpus/templates/clips/app/i18n/en-US.ts +2 -0
  121. package/corpus/templates/clips/app/i18n/es-ES.ts +2 -0
  122. package/corpus/templates/clips/app/i18n/fr-FR.ts +2 -0
  123. package/corpus/templates/clips/app/i18n/hi-IN.ts +2 -0
  124. package/corpus/templates/clips/app/i18n/ja-JP.ts +2 -0
  125. package/corpus/templates/clips/app/i18n/ko-KR.ts +2 -0
  126. package/corpus/templates/clips/app/i18n/pt-BR.ts +2 -0
  127. package/corpus/templates/clips/app/i18n/zh-CN.ts +2 -0
  128. package/corpus/templates/clips/app/i18n/zh-TW.ts +2 -0
  129. package/corpus/templates/clips/app/root.tsx +7 -1
  130. package/corpus/templates/clips/app/routes/_app.agent.tsx +15 -0
  131. package/corpus/templates/clips/changelog/2026-07-13-new-agent-page-see-and-manage-your-agent-s-context-files-con.md +6 -0
  132. package/corpus/templates/content/app/components/layout/Layout.tsx +1 -0
  133. package/corpus/templates/content/app/components/sidebar/DocumentSidebar.tsx +36 -0
  134. package/corpus/templates/content/app/i18n/zh-TW.ts +2 -0
  135. package/corpus/templates/content/app/i18n-data.ts +44 -6
  136. package/corpus/templates/content/app/root.tsx +8 -0
  137. package/corpus/templates/content/app/routes/_app.agent.tsx +15 -0
  138. package/corpus/templates/content/changelog/2026-07-13-new-agent-page-see-and-manage-your-agent-s-context-files-con.md +6 -0
  139. package/corpus/templates/design/app/components/layout/Layout.tsx +1 -0
  140. package/corpus/templates/design/app/components/layout/Sidebar.tsx +2 -0
  141. package/corpus/templates/design/app/i18n/zh-TW.ts +2 -0
  142. package/corpus/templates/design/app/i18n-data.ts +20 -0
  143. package/corpus/templates/design/app/root.tsx +7 -1
  144. package/corpus/templates/design/app/routes/agent.tsx +15 -0
  145. package/corpus/templates/design/changelog/2026-07-13-new-agent-page-see-and-manage-your-agent-s-context-files-con.md +6 -0
  146. package/corpus/templates/dispatch/app/dispatch-extensions.tsx +10 -1
  147. package/corpus/templates/dispatch/app/i18n/zh-TW.ts +2 -0
  148. package/corpus/templates/dispatch/app/i18n-data.ts +20 -0
  149. package/corpus/templates/dispatch/app/root.tsx +7 -2
  150. package/corpus/templates/dispatch/app/routes/agent.tsx +18 -0
  151. package/corpus/templates/dispatch/changelog/2026-07-13-new-agent-page-see-and-manage-your-agent-s-context-files-con.md +6 -0
  152. package/corpus/templates/forms/app/components/layout/Layout.tsx +1 -0
  153. package/corpus/templates/forms/app/components/layout/Sidebar.tsx +35 -0
  154. package/corpus/templates/forms/app/i18n/ar-SA.ts +2 -0
  155. package/corpus/templates/forms/app/i18n/de-DE.ts +2 -0
  156. package/corpus/templates/forms/app/i18n/en-US.ts +2 -0
  157. package/corpus/templates/forms/app/i18n/es-ES.ts +2 -0
  158. package/corpus/templates/forms/app/i18n/fr-FR.ts +2 -0
  159. package/corpus/templates/forms/app/i18n/hi-IN.ts +2 -0
  160. package/corpus/templates/forms/app/i18n/ja-JP.ts +2 -0
  161. package/corpus/templates/forms/app/i18n/ko-KR.ts +2 -0
  162. package/corpus/templates/forms/app/i18n/pt-BR.ts +2 -0
  163. package/corpus/templates/forms/app/i18n/zh-CN.ts +2 -0
  164. package/corpus/templates/forms/app/i18n/zh-TW.ts +2 -0
  165. package/corpus/templates/forms/app/root.tsx +6 -1
  166. package/corpus/templates/forms/app/routes/_app.agent.tsx +15 -0
  167. package/corpus/templates/forms/changelog/2026-07-13-new-agent-page-see-and-manage-your-agent-s-context-files-con.md +6 -0
  168. package/corpus/templates/macros/app/components/layout/AppLayout.tsx +14 -2
  169. package/corpus/templates/macros/app/components/layout/Header.tsx +1 -0
  170. package/corpus/templates/macros/app/root.tsx +17 -2
  171. package/corpus/templates/macros/app/routes/agent.tsx +15 -0
  172. package/corpus/templates/macros/changelog/2026-07-13-new-agent-page-see-and-manage-your-agent-s-context-files-con.md +6 -0
  173. package/corpus/templates/mail/AGENTS.md +12 -0
  174. package/corpus/templates/mail/actions/list-emails.ts +486 -4
  175. package/corpus/templates/mail/app/components/layout/AppLayout.tsx +42 -0
  176. package/corpus/templates/mail/app/components/layout/CommandPalette.tsx +6 -0
  177. package/corpus/templates/mail/app/routes/agent.tsx +15 -0
  178. package/corpus/templates/mail/changelog/2026-07-13-coverage-aware-connected-inbox-inventory.md +6 -0
  179. package/corpus/templates/mail/changelog/2026-07-13-new-agent-page-see-and-manage-your-agent-s-context-files-con.md +6 -0
  180. package/corpus/templates/mail/server/db/schema.ts +17 -0
  181. package/corpus/templates/mail/server/lib/google-auth.ts +33 -5
  182. package/corpus/templates/mail/server/lib/inventory-cursor.ts +406 -0
  183. package/corpus/templates/mail/server/lib/list-inbox-emails.ts +21 -2
  184. package/corpus/templates/mail/server/lib/mail-connector-catalog.ts +8 -0
  185. package/corpus/templates/mail/server/plugins/agent-chat.ts +4 -9
  186. package/corpus/templates/mail/server/plugins/db.ts +20 -0
  187. package/corpus/templates/plan/app/components/layout/Header.tsx +1 -0
  188. package/corpus/templates/plan/app/components/layout/Layout.tsx +1 -0
  189. package/corpus/templates/plan/app/components/layout/Sidebar.tsx +2 -0
  190. package/corpus/templates/plan/app/root.tsx +8 -0
  191. package/corpus/templates/plan/app/routes/agent.tsx +15 -0
  192. package/corpus/templates/plan/changelog/2026-07-13-new-agent-page-see-and-manage-your-agent-s-context-files-con.md +6 -0
  193. package/corpus/templates/slides/app/components/layout/Header.tsx +1 -0
  194. package/corpus/templates/slides/app/components/layout/Layout.tsx +1 -0
  195. package/corpus/templates/slides/app/components/layout/Sidebar.tsx +2 -0
  196. package/corpus/templates/slides/app/root.tsx +10 -1
  197. package/corpus/templates/slides/app/routes/agent.tsx +15 -0
  198. package/corpus/templates/slides/changelog/2026-07-13-new-agent-page-see-and-manage-your-agent-s-context-files-con.md +6 -0
  199. package/dist/agent/context-xray/actions/context-evict.js +5 -2
  200. package/dist/agent/context-xray/actions/context-evict.js.map +1 -1
  201. package/dist/agent/context-xray/actions/context-pin.js +5 -2
  202. package/dist/agent/context-xray/actions/context-pin.js.map +1 -1
  203. package/dist/agent/context-xray/actions/context-preview-get.d.ts +17 -0
  204. package/dist/agent/context-xray/actions/context-preview-get.d.ts.map +1 -0
  205. package/dist/agent/context-xray/actions/context-preview-get.js +94 -0
  206. package/dist/agent/context-xray/actions/context-preview-get.js.map +1 -0
  207. package/dist/agent/context-xray/actions/context-restore.js +5 -2
  208. package/dist/agent/context-xray/actions/context-restore.js.map +1 -1
  209. package/dist/agent/context-xray/actions/errors.d.ts +3 -0
  210. package/dist/agent/context-xray/actions/errors.d.ts.map +1 -1
  211. package/dist/agent/context-xray/actions/errors.js +6 -0
  212. package/dist/agent/context-xray/actions/errors.js.map +1 -1
  213. package/dist/agent/context-xray/manifest.d.ts +18 -1
  214. package/dist/agent/context-xray/manifest.d.ts.map +1 -1
  215. package/dist/agent/context-xray/manifest.js +68 -6
  216. package/dist/agent/context-xray/manifest.js.map +1 -1
  217. package/dist/agent/engine/context-directives-transform.d.ts +2 -0
  218. package/dist/agent/engine/context-directives-transform.d.ts.map +1 -1
  219. package/dist/agent/engine/context-directives-transform.js +2 -1
  220. package/dist/agent/engine/context-directives-transform.js.map +1 -1
  221. package/dist/agent/production-agent.d.ts +15 -0
  222. package/dist/agent/production-agent.d.ts.map +1 -1
  223. package/dist/agent/production-agent.js +74 -36
  224. package/dist/agent/production-agent.js.map +1 -1
  225. package/dist/agent/run-loop-with-resume.d.ts.map +1 -1
  226. package/dist/agent/run-loop-with-resume.js +6 -3
  227. package/dist/agent/run-loop-with-resume.js.map +1 -1
  228. package/dist/client/AgentPanel.d.ts +5 -1
  229. package/dist/client/AgentPanel.d.ts.map +1 -1
  230. package/dist/client/AgentPanel.js +9 -11
  231. package/dist/client/AgentPanel.js.map +1 -1
  232. package/dist/client/agent-page/AgentContextTab.d.ts +5 -0
  233. package/dist/client/agent-page/AgentContextTab.d.ts.map +1 -0
  234. package/dist/client/agent-page/AgentContextTab.js +202 -0
  235. package/dist/client/agent-page/AgentContextTab.js.map +1 -0
  236. package/dist/client/agent-page/AgentJobsTab.d.ts +3 -0
  237. package/dist/client/agent-page/AgentJobsTab.d.ts.map +1 -0
  238. package/dist/client/agent-page/AgentJobsTab.js +98 -0
  239. package/dist/client/agent-page/AgentJobsTab.js.map +1 -0
  240. package/dist/client/agent-page/AgentTabsPage.d.ts +20 -0
  241. package/dist/client/agent-page/AgentTabsPage.d.ts.map +1 -0
  242. package/dist/client/agent-page/AgentTabsPage.js +420 -0
  243. package/dist/client/agent-page/AgentTabsPage.js.map +1 -0
  244. package/dist/client/agent-page/types.d.ts +17 -0
  245. package/dist/client/agent-page/types.d.ts.map +1 -0
  246. package/dist/client/agent-page/types.js +9 -0
  247. package/dist/client/agent-page/types.js.map +1 -0
  248. package/dist/client/agent-page/use-jobs.d.ts +61 -0
  249. package/dist/client/agent-page/use-jobs.d.ts.map +1 -0
  250. package/dist/client/agent-page/use-jobs.js +71 -0
  251. package/dist/client/agent-page/use-jobs.js.map +1 -0
  252. package/dist/client/context-xray/ContextMeter.d.ts +3 -1
  253. package/dist/client/context-xray/ContextMeter.d.ts.map +1 -1
  254. package/dist/client/context-xray/ContextMeter.js +14 -5
  255. package/dist/client/context-xray/ContextMeter.js.map +1 -1
  256. package/dist/client/context-xray/ContextTreemap.d.ts +3 -2
  257. package/dist/client/context-xray/ContextTreemap.d.ts.map +1 -1
  258. package/dist/client/context-xray/ContextTreemap.js +9 -1
  259. package/dist/client/context-xray/ContextTreemap.js.map +1 -1
  260. package/dist/client/context-xray/ContextXRayPanel.d.ts.map +1 -1
  261. package/dist/client/context-xray/ContextXRayPanel.js +95 -20
  262. package/dist/client/context-xray/ContextXRayPanel.js.map +1 -1
  263. package/dist/client/context-xray/format.d.ts.map +1 -1
  264. package/dist/client/context-xray/format.js +12 -0
  265. package/dist/client/context-xray/format.js.map +1 -1
  266. package/dist/client/index.d.ts +3 -0
  267. package/dist/client/index.d.ts.map +1 -1
  268. package/dist/client/index.js +1 -0
  269. package/dist/client/index.js.map +1 -1
  270. package/dist/client/resources/ResourcesPanel.d.ts +9 -1
  271. package/dist/client/resources/ResourcesPanel.d.ts.map +1 -1
  272. package/dist/client/resources/ResourcesPanel.js +26 -10
  273. package/dist/client/resources/ResourcesPanel.js.map +1 -1
  274. package/dist/client/settings/AutomationsSection.d.ts +9 -0
  275. package/dist/client/settings/AutomationsSection.d.ts.map +1 -1
  276. package/dist/client/settings/AutomationsSection.js +128 -147
  277. package/dist/client/settings/AutomationsSection.js.map +1 -1
  278. package/dist/collab/routes.d.ts +1 -1
  279. package/dist/collab/struct-routes.d.ts +1 -1
  280. package/dist/file-upload/actions/upload-image.d.ts +1 -1
  281. package/dist/jobs/actions/list-recurring-jobs.d.ts +21 -0
  282. package/dist/jobs/actions/list-recurring-jobs.d.ts.map +1 -0
  283. package/dist/jobs/actions/list-recurring-jobs.js +74 -0
  284. package/dist/jobs/actions/list-recurring-jobs.js.map +1 -0
  285. package/dist/jobs/actions/manage-recurring-job.d.ts +18 -0
  286. package/dist/jobs/actions/manage-recurring-job.d.ts.map +1 -0
  287. package/dist/jobs/actions/manage-recurring-job.js +68 -0
  288. package/dist/jobs/actions/manage-recurring-job.js.map +1 -0
  289. package/dist/jobs/tools.d.ts +13 -0
  290. package/dist/jobs/tools.d.ts.map +1 -1
  291. package/dist/jobs/tools.js +1 -1
  292. package/dist/jobs/tools.js.map +1 -1
  293. package/dist/localization/default-messages.d.ts +96 -0
  294. package/dist/localization/default-messages.d.ts.map +1 -1
  295. package/dist/localization/default-messages.js +96 -0
  296. package/dist/localization/default-messages.js.map +1 -1
  297. package/dist/mcp/build-server.d.ts.map +1 -1
  298. package/dist/mcp/build-server.js +1 -0
  299. package/dist/mcp/build-server.js.map +1 -1
  300. package/dist/mcp/connect-route.d.ts.map +1 -1
  301. package/dist/mcp/connect-route.js +44 -59
  302. package/dist/mcp/connect-route.js.map +1 -1
  303. package/dist/notifications/routes.d.ts +1 -1
  304. package/dist/observability/routes.d.ts +5 -5
  305. package/dist/progress/routes.d.ts +1 -1
  306. package/dist/resources/handlers.d.ts +3 -3
  307. package/dist/secrets/routes.d.ts +9 -9
  308. package/dist/server/action-discovery.d.ts.map +1 -1
  309. package/dist/server/action-discovery.js +23 -0
  310. package/dist/server/action-discovery.js.map +1 -1
  311. package/dist/server/agent-chat/prompt-resources.d.ts +14 -0
  312. package/dist/server/agent-chat/prompt-resources.d.ts.map +1 -1
  313. package/dist/server/agent-chat/prompt-resources.js +139 -2
  314. package/dist/server/agent-chat/prompt-resources.js.map +1 -1
  315. package/dist/server/agent-chat-plugin.d.ts +1 -0
  316. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  317. package/dist/server/agent-chat-plugin.js +136 -3
  318. package/dist/server/agent-chat-plugin.js.map +1 -1
  319. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  320. package/dist/server/auth.d.ts.map +1 -1
  321. package/dist/server/auth.js +1 -4
  322. package/dist/server/auth.js.map +1 -1
  323. package/dist/server/google-oauth.d.ts.map +1 -1
  324. package/dist/server/google-oauth.js +1 -4
  325. package/dist/server/google-oauth.js.map +1 -1
  326. package/dist/server/workspace-oauth.d.ts +11 -0
  327. package/dist/server/workspace-oauth.d.ts.map +1 -0
  328. package/dist/server/workspace-oauth.js +25 -0
  329. package/dist/server/workspace-oauth.js.map +1 -0
  330. package/dist/shared/context-xray.d.ts +45 -1
  331. package/dist/shared/context-xray.d.ts.map +1 -1
  332. package/dist/shared/context-xray.js +12 -0
  333. package/dist/shared/context-xray.js.map +1 -1
  334. package/dist/shared/mcp-connect-content.d.ts +37 -0
  335. package/dist/shared/mcp-connect-content.d.ts.map +1 -0
  336. package/dist/shared/mcp-connect-content.js +92 -0
  337. package/dist/shared/mcp-connect-content.js.map +1 -0
  338. package/dist/templates/default/app/routes/_index.tsx +11 -0
  339. package/dist/templates/default/app/routes/agent.tsx +33 -0
  340. package/dist/templates/workspace-core/.agents/skills/agent-native-toolkit/SKILL.md +6 -0
  341. package/dist/templates/workspace-core/.agents/skills/agent-page/SKILL.md +59 -0
  342. package/dist/templates/workspace-core/.agents/skills/context-xray/SKILL.md +25 -0
  343. package/dist/templates/workspace-core/.agents/skills/external-agents/SKILL.md +7 -0
  344. package/dist/templates/workspace-core/.agents/skills/recurring-jobs/SKILL.md +9 -0
  345. package/dist/triggers/actions/list-automations.d.ts +24 -0
  346. package/dist/triggers/actions/list-automations.d.ts.map +1 -0
  347. package/dist/triggers/actions/list-automations.js +72 -0
  348. package/dist/triggers/actions/list-automations.js.map +1 -0
  349. package/dist/triggers/actions/manage-automation.d.ts +18 -0
  350. package/dist/triggers/actions/manage-automation.d.ts.map +1 -0
  351. package/dist/triggers/actions/manage-automation.js +60 -0
  352. package/dist/triggers/actions/manage-automation.js.map +1 -0
  353. package/docs/content/agent-surfaces.mdx +43 -0
  354. package/docs/content/external-agents.mdx +11 -0
  355. package/docs/content/locales/ar-SA/agent-surfaces.mdx +30 -0
  356. package/docs/content/locales/ar-SA/external-agents.mdx +9 -0
  357. package/docs/content/locales/de-DE/agent-surfaces.mdx +34 -0
  358. package/docs/content/locales/de-DE/external-agents.mdx +10 -0
  359. package/docs/content/locales/es-ES/agent-surfaces.mdx +34 -0
  360. package/docs/content/locales/es-ES/external-agents.mdx +10 -0
  361. package/docs/content/locales/fr-FR/agent-surfaces.mdx +34 -0
  362. package/docs/content/locales/fr-FR/external-agents.mdx +11 -0
  363. package/docs/content/locales/hi-IN/agent-surfaces.mdx +31 -0
  364. package/docs/content/locales/hi-IN/external-agents.mdx +9 -0
  365. package/docs/content/locales/ja-JP/agent-surfaces.mdx +32 -0
  366. package/docs/content/locales/ja-JP/external-agents.mdx +10 -0
  367. package/docs/content/locales/ko-KR/agent-surfaces.mdx +32 -0
  368. package/docs/content/locales/ko-KR/external-agents.mdx +9 -0
  369. package/docs/content/locales/pt-BR/agent-surfaces.mdx +33 -0
  370. package/docs/content/locales/pt-BR/external-agents.mdx +10 -0
  371. package/docs/content/locales/zh-CN/agent-surfaces.mdx +29 -0
  372. package/docs/content/locales/zh-CN/external-agents.mdx +8 -0
  373. package/docs/content/locales/zh-TW/agent-surfaces.mdx +29 -0
  374. package/docs/content/locales/zh-TW/external-agents.mdx +8 -0
  375. package/package.json +1 -1
  376. package/src/templates/default/app/routes/_index.tsx +11 -0
  377. package/src/templates/default/app/routes/agent.tsx +33 -0
  378. package/src/templates/workspace-core/.agents/skills/agent-native-toolkit/SKILL.md +6 -0
  379. package/src/templates/workspace-core/.agents/skills/agent-page/SKILL.md +59 -0
  380. package/src/templates/workspace-core/.agents/skills/context-xray/SKILL.md +25 -0
  381. package/src/templates/workspace-core/.agents/skills/external-agents/SKILL.md +7 -0
  382. package/src/templates/workspace-core/.agents/skills/recurring-jobs/SKILL.md +9 -0
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Shared contracts for the full-page Agent surface (`AgentTabsPage`).
3
+ *
4
+ * Ownership note for concurrent implementation work: the page shell and the
5
+ * Files/MCP/Connect tabs may ADD exports here; the Context and Jobs tab
6
+ * implementations consume these types but must not edit this file.
7
+ */
8
+
9
+ /** Which configuration scope the page-level toggle is showing. */
10
+ export type AgentPageScope = "user" | "org";
11
+
12
+ /** Props every Agent page tab receives from the page shell. */
13
+ export interface AgentPageTabProps {
14
+ /** Current scope selected by the page-level Personal/Organization toggle. */
15
+ scope: AgentPageScope;
16
+ /** Whether the current user can administer org-scoped agent config. */
17
+ canManageOrg?: boolean;
18
+ }
@@ -0,0 +1,150 @@
1
+ import { useQueryClient } from "@tanstack/react-query";
2
+
3
+ import { useActionMutation, useActionQuery } from "../use-action.js";
4
+
5
+ export type JobsScope = "user" | "org";
6
+
7
+ export interface RecurringJob {
8
+ id: string;
9
+ name: string;
10
+ path: string;
11
+ scope: "personal" | "organization";
12
+ schedule: string;
13
+ scheduleDescription: string;
14
+ instructions: string;
15
+ enabled: boolean;
16
+ lastRun: string | null;
17
+ lastStatus: string | null;
18
+ lastError: string | null;
19
+ nextRun: string | null;
20
+ createdBy: string | null;
21
+ canUpdate: boolean;
22
+ }
23
+
24
+ export interface Automation {
25
+ id: string;
26
+ name: string;
27
+ path: string;
28
+ scope: "personal" | "organization";
29
+ triggerType: "event" | "schedule";
30
+ event: string | null;
31
+ schedule: string | null;
32
+ scheduleDescription: string | null;
33
+ condition: string | null;
34
+ body: string;
35
+ enabled: boolean;
36
+ lastRun: string | null;
37
+ lastStatus: string | null;
38
+ lastError: string | null;
39
+ nextRun: string | null;
40
+ createdBy: string | null;
41
+ canUpdate: boolean;
42
+ }
43
+
44
+ export type ManageJobInput = {
45
+ operation: "update" | "delete";
46
+ name: string;
47
+ scope: "personal" | "organization";
48
+ enabled?: boolean;
49
+ };
50
+
51
+ export type ManageAutomationInput = {
52
+ operation: "update" | "delete";
53
+ name: string;
54
+ scope: "personal" | "organization";
55
+ enabled?: boolean;
56
+ };
57
+
58
+ function recurringParams(scope: JobsScope) {
59
+ return { scope: scope === "org" ? "organization" : "personal" } as const;
60
+ }
61
+
62
+ function automationParams(scope: JobsScope) {
63
+ return { scope: scope === "org" ? "organization" : "personal" } as const;
64
+ }
65
+
66
+ export function useRecurringJobs(scope: JobsScope) {
67
+ return useActionQuery<RecurringJob[]>(
68
+ "list-recurring-jobs",
69
+ recurringParams(scope),
70
+ { staleTime: 5_000 },
71
+ );
72
+ }
73
+
74
+ export function useAutomations(scope: JobsScope) {
75
+ return useActionQuery<Automation[]>(
76
+ "list-automations",
77
+ automationParams(scope),
78
+ { staleTime: 5_000 },
79
+ );
80
+ }
81
+
82
+ export function useManageRecurringJob(scope: JobsScope) {
83
+ const queryClient = useQueryClient();
84
+ const params = recurringParams(scope);
85
+ const queryKey = ["action", "list-recurring-jobs", params] as const;
86
+
87
+ return useActionMutation<
88
+ { deleted?: boolean; name: string; enabled?: boolean },
89
+ ManageJobInput
90
+ >("manage-recurring-job", {
91
+ onMutate: async (variables) => {
92
+ await queryClient.cancelQueries({ queryKey });
93
+ const previous = queryClient.getQueryData<RecurringJob[]>(queryKey);
94
+ queryClient.setQueryData<RecurringJob[]>(queryKey, (current) => {
95
+ if (!current) return current;
96
+ if (variables.operation === "delete") {
97
+ return current.filter((job) => job.name !== variables.name);
98
+ }
99
+ return current.map((job) =>
100
+ job.name === variables.name && variables.enabled !== undefined
101
+ ? { ...job, enabled: variables.enabled }
102
+ : job,
103
+ );
104
+ });
105
+ return { previous };
106
+ },
107
+ onError: (_error, _variables, context) => {
108
+ const rollback = context as { previous?: RecurringJob[] } | undefined;
109
+ if (rollback && "previous" in rollback) {
110
+ queryClient.setQueryData(queryKey, rollback.previous);
111
+ }
112
+ },
113
+ });
114
+ }
115
+
116
+ export function useManageAutomation(scope: JobsScope) {
117
+ const queryClient = useQueryClient();
118
+ const params = automationParams(scope);
119
+ const queryKey = ["action", "list-automations", params] as const;
120
+
121
+ return useActionMutation<
122
+ { deleted?: boolean; name: string; enabled?: boolean },
123
+ ManageAutomationInput
124
+ >("manage-automation", {
125
+ onMutate: async (variables) => {
126
+ await queryClient.cancelQueries({ queryKey });
127
+ const previous = queryClient.getQueryData<Automation[]>(queryKey);
128
+ queryClient.setQueryData<Automation[]>(queryKey, (current) => {
129
+ if (!current) return current;
130
+ if (variables.operation === "delete") {
131
+ return current.filter(
132
+ (automation) => automation.name !== variables.name,
133
+ );
134
+ }
135
+ return current.map((automation) =>
136
+ automation.name === variables.name && variables.enabled !== undefined
137
+ ? { ...automation, enabled: variables.enabled }
138
+ : automation,
139
+ );
140
+ });
141
+ return { previous };
142
+ },
143
+ onError: (_error, _variables, context) => {
144
+ const rollback = context as { previous?: Automation[] } | undefined;
145
+ if (rollback && "previous" in rollback) {
146
+ queryClient.setQueryData(queryKey, rollback.previous);
147
+ }
148
+ },
149
+ });
150
+ }
@@ -4,6 +4,10 @@ import type {
4
4
  ContextManifest,
5
5
  ContextSegmentStatus,
6
6
  } from "../../shared/context-xray.js";
7
+ import {
8
+ manifestConversationTokens,
9
+ manifestSystemTokens,
10
+ } from "../../shared/context-xray.js";
7
11
  import {
8
12
  Popover,
9
13
  PopoverContent,
@@ -61,9 +65,11 @@ function ContextDonut({ pct, advisory }: { pct: number; advisory: boolean }) {
61
65
 
62
66
  export function ContextMeter({
63
67
  threadId,
68
+ manifest: providedManifest,
64
69
  enabled = true,
65
70
  }: {
66
71
  threadId?: string | null;
72
+ manifest?: ContextManifest | null;
67
73
  enabled?: boolean;
68
74
  }) {
69
75
  const [open, setOpen] = useState(false);
@@ -71,7 +77,7 @@ export function ContextMeter({
71
77
  Map<string, ContextSegmentStatus>
72
78
  >(new Map());
73
79
  const currentThreadId = useRef(threadId);
74
- const shouldQuery = Boolean(threadId && enabled);
80
+ const shouldQuery = Boolean(threadId && enabled && !providedManifest);
75
81
  const query = useActionQuery(
76
82
  "context-manifest-get",
77
83
  shouldQuery && threadId ? { threadId } : undefined,
@@ -99,13 +105,21 @@ export function ContextMeter({
99
105
  }
100
106
  }, [enabled, threadId]);
101
107
 
102
- const manifest = query.data;
108
+ const manifest = providedManifest ?? query.data;
103
109
  const contextWindow = resolveContextWindow(manifest?.model);
104
110
  const pct = manifest
105
111
  ? Math.min(100, Math.round((manifest.totalTokens / contextWindow) * 100))
106
112
  : 0;
113
+ const systemTokens = manifest ? manifestSystemTokens(manifest) : 0;
114
+ const conversationTokens = manifest
115
+ ? manifestConversationTokens(manifest)
116
+ : 0;
107
117
 
108
- if (!shouldQuery || !threadId || !manifest || manifest.rawTokens <= 0) {
118
+ if (
119
+ (!shouldQuery && !providedManifest) ||
120
+ !manifest ||
121
+ (manifest.rawTokens <= 0 && manifest.totalTokens <= 0)
122
+ ) {
109
123
  return null;
110
124
  }
111
125
 
@@ -139,9 +153,9 @@ export function ContextMeter({
139
153
  type="button"
140
154
  aria-label={`Context ${pct}%, ${formatTokens(
141
155
  manifest.totalTokens,
142
- )}. Open Context X-Ray.`}
156
+ )}${systemTokens > 0 ? ` total: ${formatTokens(systemTokens)} system + ${formatTokens(conversationTokens)} conversation` : ""}. Open Context X-Ray.`}
143
157
  className={cn(
144
- "flex size-7 shrink-0 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-accent/50 hover:text-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring",
158
+ "flex size-7 shrink-0 cursor-pointer items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-accent/50 hover:text-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring",
145
159
  open && "bg-accent/60 text-foreground",
146
160
  )}
147
161
  >
@@ -151,6 +165,9 @@ export function ContextMeter({
151
165
  </TooltipTrigger>
152
166
  <TooltipContent>
153
167
  Context {pct}% · {formatTokens(manifest.totalTokens)}
168
+ {systemTokens > 0
169
+ ? ` (${formatTokens(systemTokens)} system + ${formatTokens(conversationTokens)} conversation)`
170
+ : ""}
154
171
  </TooltipContent>
155
172
  </Tooltip>
156
173
  <PopoverContent
@@ -1,7 +1,10 @@
1
1
  import { useEffect, useRef, useState } from "react";
2
2
  import { Treemap } from "recharts";
3
3
 
4
- import type { ContextManifestSegment } from "../../shared/context-xray.js";
4
+ import type {
5
+ ContextManifestSegment,
6
+ ContextManifestSystemSection,
7
+ } from "../../shared/context-xray.js";
5
8
  import { formatTokens, groupFill } from "./format.js";
6
9
 
7
10
  interface TreemapDatum {
@@ -47,9 +50,11 @@ function TreemapContent(props: any) {
47
50
 
48
51
  export function ContextTreemap({
49
52
  segments,
53
+ systemSections = [],
50
54
  onSelect,
51
55
  }: {
52
56
  segments: ContextManifestSegment[];
57
+ systemSections?: ContextManifestSystemSection[];
53
58
  onSelect?: (segmentId: string) => void;
54
59
  }) {
55
60
  const containerRef = useRef<HTMLDivElement>(null);
@@ -62,6 +67,16 @@ export function ContextTreemap({
62
67
  group: segment.group,
63
68
  segmentId: segment.segmentId,
64
69
  }));
70
+ data.push(
71
+ ...systemSections
72
+ .filter((section) => section.tokenCount > 0)
73
+ .map((section) => ({
74
+ name: section.label,
75
+ size: section.tokenCount,
76
+ group: `System · ${section.governance}`,
77
+ segmentId: section.segmentId,
78
+ })),
79
+ );
65
80
 
66
81
  useEffect(() => {
67
82
  const element = containerRef.current;
@@ -2,6 +2,7 @@ import {
2
2
  IconChartTreemap,
3
3
  IconChevronDown,
4
4
  IconChevronRight,
5
+ IconLock,
5
6
  IconListDetails,
6
7
  } from "@tabler/icons-react";
7
8
  import { useMemo, useState } from "react";
@@ -9,13 +10,19 @@ import { useMemo, useState } from "react";
9
10
  import type {
10
11
  ContextManifest,
11
12
  ContextManifestSegment,
13
+ ContextManifestSystemSection,
12
14
  ContextSegmentStatus,
13
15
  } from "../../shared/context-xray.js";
16
+ import {
17
+ manifestConversationTokens,
18
+ manifestSystemTokens,
19
+ } from "../../shared/context-xray.js";
14
20
  import {
15
21
  Tooltip,
16
22
  TooltipContent,
17
23
  TooltipTrigger,
18
24
  } from "../components/ui/tooltip.js";
25
+ import { useT } from "../i18n.js";
19
26
  import { cn } from "../utils.js";
20
27
  import { ContextSegmentRow } from "./ContextSegmentRow.js";
21
28
  import { ContextTreemap } from "./ContextTreemap.js";
@@ -72,6 +79,69 @@ function groupedSegments(segments: ContextManifestSegment[]): Group[] {
72
79
  });
73
80
  }
74
81
 
82
+ const GOVERNANCE_ORDER = ["required", "inherited", "user"] as const;
83
+
84
+ function governanceLabel(
85
+ governance: ContextManifestSystemSection["governance"],
86
+ t: (key: string, options?: Record<string, unknown>) => string,
87
+ ): string {
88
+ switch (governance) {
89
+ case "required":
90
+ return t("contextXray.governance.required", {
91
+ defaultValue: "Required",
92
+ });
93
+ case "inherited":
94
+ return t("contextXray.governance.inherited", {
95
+ defaultValue: "Inherited",
96
+ });
97
+ case "user":
98
+ return t("contextXray.governance.user", {
99
+ defaultValue: "Your context",
100
+ });
101
+ }
102
+ }
103
+
104
+ function sourceLabel(section: ContextManifestSystemSection): string {
105
+ return (
106
+ section.sourceRef?.path ??
107
+ section.sourceRef?.resourceId ??
108
+ section.sourceRef?.scope ??
109
+ "framework"
110
+ );
111
+ }
112
+
113
+ function SystemSectionRow({
114
+ section,
115
+ totalTokens,
116
+ }: {
117
+ section: ContextManifestSystemSection;
118
+ totalTokens: number;
119
+ }) {
120
+ const share =
121
+ totalTokens > 0 ? Math.round((section.tokenCount / totalTokens) * 100) : 0;
122
+ return (
123
+ <div className="flex min-h-12 items-start gap-2 rounded-sm px-2 py-1.5">
124
+ <span className="mt-1 flex size-6 shrink-0 items-center justify-center rounded-md text-muted-foreground">
125
+ <IconLock className="h-3.5 w-3.5" />
126
+ </span>
127
+ <div className="min-w-0 flex-1">
128
+ <div className="truncate text-[13px] font-medium leading-5 text-foreground">
129
+ {section.label}
130
+ </div>
131
+ <div className="truncate text-[11px] text-muted-foreground">
132
+ {sourceLabel(section)} · {formatTokens(section.tokenCount)} tokens ·{" "}
133
+ {share}%{section.tokenMethod === "estimate" ? " · estimated" : ""}
134
+ </div>
135
+ {section.preview ? (
136
+ <div className="mt-0.5 line-clamp-2 text-[11px] text-muted-foreground/80">
137
+ {section.preview}
138
+ </div>
139
+ ) : null}
140
+ </div>
141
+ </div>
142
+ );
143
+ }
144
+
75
145
  export function ContextXRayPanel({
76
146
  manifest,
77
147
  optimistic,
@@ -85,6 +155,7 @@ export function ContextXRayPanel({
85
155
  onEvict: (segmentId: string) => void;
86
156
  onRestore: (segmentId: string) => void;
87
157
  }) {
158
+ const t = useT();
88
159
  const [mode, setMode] = useState<"list" | "map">("list");
89
160
  const [collapsed, setCollapsed] = useState<Set<string>>(new Set());
90
161
  const segments = useMemo(
@@ -92,6 +163,33 @@ export function ContextXRayPanel({
92
163
  [manifest.segments, optimistic],
93
164
  );
94
165
  const groups = useMemo(() => groupedSegments(segments), [segments]);
166
+ const systemSections = manifest.systemSections ?? [];
167
+ const systemGroups = useMemo(() => {
168
+ const grouped = new Map<
169
+ ContextManifestSystemSection["governance"],
170
+ ContextManifestSystemSection[]
171
+ >();
172
+ for (const section of systemSections) {
173
+ const list = grouped.get(section.governance) ?? [];
174
+ list.push(section);
175
+ grouped.set(section.governance, list);
176
+ }
177
+ return GOVERNANCE_ORDER.flatMap((governance) => {
178
+ const sections = grouped.get(governance);
179
+ return sections && sections.length > 0
180
+ ? [
181
+ {
182
+ governance,
183
+ sections,
184
+ tokens: sections.reduce(
185
+ (sum, section) => sum + section.tokenCount,
186
+ 0,
187
+ ),
188
+ },
189
+ ]
190
+ : [];
191
+ });
192
+ }, [systemSections]);
95
193
  const contextWindow = resolveContextWindow(manifest.model);
96
194
  const pct = Math.min(
97
195
  100,
@@ -100,8 +198,12 @@ export function ContextXRayPanel({
100
198
  const headroom = Math.max(0, contextWindow - manifest.totalTokens);
101
199
  const pinned = segments.filter((s) => s.status === "pinned").length;
102
200
  const evicted = segments.filter((s) => s.status === "evicted").length;
201
+ const systemTokens = manifestSystemTokens(manifest);
202
+ const conversationTokens = manifestConversationTokens(manifest);
103
203
  const details = [
104
204
  `${formatTokens(headroom)} free`,
205
+ systemTokens > 0 ? `${formatTokens(systemTokens)} system` : null,
206
+ `${formatTokens(conversationTokens)} conversation`,
105
207
  pinned > 0 ? `${pinned} pinned` : null,
106
208
  evicted > 0 ? `${evicted} evicted` : null,
107
209
  manifest.tokenCountMethod === "estimate" ? "estimated" : null,
@@ -150,7 +252,7 @@ export function ContextXRayPanel({
150
252
  onClick={() => setMode("list")}
151
253
  aria-label="Show context list"
152
254
  className={cn(
153
- "flex size-7 items-center justify-center rounded text-muted-foreground",
255
+ "flex size-7 cursor-pointer items-center justify-center rounded text-muted-foreground",
154
256
  mode === "list"
155
257
  ? "bg-background text-foreground shadow-sm"
156
258
  : "hover:text-foreground",
@@ -168,7 +270,7 @@ export function ContextXRayPanel({
168
270
  onClick={() => setMode("map")}
169
271
  aria-label="Show context map"
170
272
  className={cn(
171
- "flex size-7 items-center justify-center rounded text-muted-foreground",
273
+ "flex size-7 cursor-pointer items-center justify-center rounded text-muted-foreground",
172
274
  mode === "map"
173
275
  ? "bg-background text-foreground shadow-sm"
174
276
  : "hover:text-foreground",
@@ -185,6 +287,7 @@ export function ContextXRayPanel({
185
287
  {mode === "map" ? (
186
288
  <ContextTreemap
187
289
  segments={segments}
290
+ systemSections={systemSections}
188
291
  onSelect={(segmentId) => {
189
292
  const segment = segments.find((s) => s.segmentId === segmentId);
190
293
  if (segment) setCollapsed(new Set());
@@ -192,6 +295,68 @@ export function ContextXRayPanel({
192
295
  />
193
296
  ) : (
194
297
  <div className="divide-y divide-border/60">
298
+ {systemGroups.length > 0 && (
299
+ <div>
300
+ <div className="px-1.5 pb-1 pt-2 text-[10px] font-semibold uppercase tracking-[0.12em] text-muted-foreground">
301
+ {t("contextXray.systemOrdered", {
302
+ defaultValue: "System · ordered, not evictable",
303
+ })}
304
+ </div>
305
+ {systemGroups.map((group) => {
306
+ const groupKey = `system:${group.governance}`;
307
+ const isCollapsed = collapsed.has(groupKey);
308
+ return (
309
+ <div key={groupKey}>
310
+ <button
311
+ type="button"
312
+ onClick={() => {
313
+ setCollapsed((prev) => {
314
+ const next = new Set(prev);
315
+ if (next.has(groupKey)) next.delete(groupKey);
316
+ else next.add(groupKey);
317
+ return next;
318
+ });
319
+ }}
320
+ className="flex w-full cursor-pointer items-center gap-2 rounded-sm px-1.5 py-2 text-left hover:bg-accent/35"
321
+ >
322
+ {isCollapsed ? (
323
+ <IconChevronRight className="h-3.5 w-3.5 text-muted-foreground" />
324
+ ) : (
325
+ <IconChevronDown className="h-3.5 w-3.5 text-muted-foreground" />
326
+ )}
327
+ <IconLock className="h-3 w-3 text-muted-foreground" />
328
+ <span className="min-w-0 flex-1 truncate text-xs font-medium">
329
+ {governanceLabel(group.governance, t)}
330
+ </span>
331
+ <span className="text-[11px] text-muted-foreground">
332
+ {formatTokens(group.tokens)} ·{" "}
333
+ {manifest.totalTokens > 0
334
+ ? Math.round(
335
+ (group.tokens / manifest.totalTokens) * 100,
336
+ )
337
+ : 0}
338
+ %
339
+ </span>
340
+ </button>
341
+ {!isCollapsed && (
342
+ <div className="pb-1">
343
+ {group.sections
344
+ .slice()
345
+ .sort((a, b) => b.tokenCount - a.tokenCount)
346
+ .map((section) => (
347
+ <SystemSectionRow
348
+ key={section.segmentId}
349
+ section={section}
350
+ totalTokens={manifest.totalTokens}
351
+ />
352
+ ))}
353
+ </div>
354
+ )}
355
+ </div>
356
+ );
357
+ })}
358
+ </div>
359
+ )}
195
360
  {groups.map((group) => {
196
361
  const isCollapsed = collapsed.has(group.name);
197
362
  return (
@@ -206,7 +371,7 @@ export function ContextXRayPanel({
206
371
  return next;
207
372
  });
208
373
  }}
209
- className="flex w-full items-center gap-2 rounded-sm px-1.5 py-2 text-left hover:bg-accent/35"
374
+ className="flex w-full cursor-pointer items-center gap-2 rounded-sm px-1.5 py-2 text-left hover:bg-accent/35"
210
375
  >
211
376
  {isCollapsed ? (
212
377
  <IconChevronRight className="h-3.5 w-3.5 text-muted-foreground" />
@@ -41,6 +41,9 @@ export function groupColor(group: string): string {
41
41
  if (group === "Files read") return "bg-sky-500";
42
42
  if (group === "Thinking") return "bg-violet-500";
43
43
  if (group === "Task & instructions") return "bg-rose-500";
44
+ if (group === "System · required") return "bg-slate-700";
45
+ if (group === "System · inherited") return "bg-indigo-500";
46
+ if (group === "System · user") return "bg-teal-500";
44
47
  return "bg-slate-400";
45
48
  }
46
49
 
@@ -50,5 +53,8 @@ export function groupFill(group: string): string {
50
53
  if (group === "Files read") return "#0ea5e9";
51
54
  if (group === "Thinking") return "#8b5cf6";
52
55
  if (group === "Task & instructions") return "#f43f5e";
56
+ if (group === "System · required") return "#334155";
57
+ if (group === "System · inherited") return "#6366f1";
58
+ if (group === "System · user") return "#14b8a6";
53
59
  return "#94a3b8";
54
60
  }
@@ -594,6 +594,11 @@ export {
594
594
  type AgentPanelProps,
595
595
  type AgentSidebarProps,
596
596
  } from "./AgentPanel.js";
597
+ export {
598
+ AgentTabsPage,
599
+ type AgentTabsPageProps,
600
+ } from "./agent-page/AgentTabsPage.js";
601
+ export type { AgentPageScope, AgentPageTabProps } from "./agent-page/types.js";
597
602
  export {
598
603
  AGENT_CHAT_HOME_HANDOFF_TTL_MS,
599
604
  AGENT_CHAT_VIEW_TRANSITION_CLASS,
@@ -838,6 +843,7 @@ export {
838
843
  type ResourceTreeProps,
839
844
  type ResourceEditorProps,
840
845
  } from "./resources/index.js";
846
+ export type { ResourcesPanelProps } from "./resources/ResourcesPanel.js";
841
847
  export {
842
848
  HistoryTimeline,
843
849
  VersionHistoryPanel,
@@ -1004,15 +1004,34 @@ Workspace resources are for files users intentionally add, edit, or manage. Agen
1004
1004
  const WORKSPACE_RESOURCE_OWNER = "__workspace__";
1005
1005
  const SHARED_RESOURCE_OWNER = "__shared__";
1006
1006
 
1007
- export function ResourcesPanel() {
1007
+ export interface ResourcesPanelProps {
1008
+ /** Hide the virtual MCP folder when Files is hosted by the Agent page. */
1009
+ showMcpServers?: boolean;
1010
+ /** Optional page-level scope to mirror in the resource toolbar. */
1011
+ scope?: ResourceScope;
1012
+ }
1013
+
1014
+ export function resolveInitialResourceScope(
1015
+ requestedScope: ResourceScope | undefined,
1016
+ canEditOrg: boolean,
1017
+ ): ResourceScope {
1018
+ if (requestedScope === "shared") return "shared";
1019
+ if (requestedScope === "personal") return "personal";
1020
+ return canEditOrg ? "shared" : "personal";
1021
+ }
1022
+
1023
+ export function ResourcesPanel({
1024
+ showMcpServers = true,
1025
+ scope: requestedScope,
1026
+ }: ResourcesPanelProps = {}) {
1008
1027
  const { data: org } = useOrg();
1009
1028
  // Non-admin org members get read-only access to organization resources.
1010
1029
  // Solo deployments (no orgId) behave as owner — users can edit their own.
1011
1030
  const canEditOrg =
1012
1031
  !org?.orgId || org.role === "owner" || org.role === "admin";
1013
1032
 
1014
- const [activeScope, setActiveScope] = useState<ResourceScope>(
1015
- canEditOrg ? "shared" : "personal",
1033
+ const [activeScope, setActiveScope] = useState<ResourceScope>(() =>
1034
+ resolveInitialResourceScope(requestedScope, canEditOrg),
1016
1035
  );
1017
1036
  const [selectedResourceId, setSelectedResourceId] = useState<string | null>(
1018
1037
  null,
@@ -1074,27 +1093,31 @@ export function ResourcesPanel() {
1074
1093
  // `handleSelect` and `handleDelete` below recognize to route back to
1075
1094
  // the MCP endpoints.
1076
1095
  const personalTree = withAgentScratchFolder(
1077
- withMcpServersFolder(
1078
- personalTreeQuery.data ?? [],
1079
- mcpServersQuery.data?.user ?? [],
1080
- {
1081
- builtins: (builtinCapabilitiesQuery.data?.capabilities ?? []).map(
1082
- (capability) => ({ capability, scope: "user" as const }),
1083
- ),
1084
- },
1085
- ),
1096
+ showMcpServers
1097
+ ? withMcpServersFolder(
1098
+ personalTreeQuery.data ?? [],
1099
+ mcpServersQuery.data?.user ?? [],
1100
+ {
1101
+ builtins: (builtinCapabilitiesQuery.data?.capabilities ?? []).map(
1102
+ (capability) => ({ capability, scope: "user" as const }),
1103
+ ),
1104
+ },
1105
+ )
1106
+ : (personalTreeQuery.data ?? []),
1086
1107
  { show: showAgentScratch },
1087
1108
  );
1088
1109
  const sharedTree = withAgentScratchFolder(
1089
- withMcpServersFolder(
1090
- sharedTreeQuery.data ?? [],
1091
- mcpServersQuery.data?.org ?? [],
1092
- {
1093
- builtins: (builtinCapabilitiesQuery.data?.capabilities ?? []).map(
1094
- (capability) => ({ capability, scope: "org" as const }),
1095
- ),
1096
- },
1097
- ),
1110
+ showMcpServers
1111
+ ? withMcpServersFolder(
1112
+ sharedTreeQuery.data ?? [],
1113
+ mcpServersQuery.data?.org ?? [],
1114
+ {
1115
+ builtins: (builtinCapabilitiesQuery.data?.capabilities ?? []).map(
1116
+ (capability) => ({ capability, scope: "org" as const }),
1117
+ ),
1118
+ },
1119
+ )
1120
+ : (sharedTreeQuery.data ?? []),
1098
1121
  { show: showAgentScratch },
1099
1122
  );
1100
1123
  const workspaceTree = workspaceTreeQuery.data ?? [];
@@ -1132,10 +1155,15 @@ export function ResourcesPanel() {
1132
1155
 
1133
1156
  // Sync activeScope once the org role arrives (canEditOrg is resolved async).
1134
1157
  useEffect(() => {
1135
- if (!canEditOrg && activeScope === "shared") {
1158
+ if (!requestedScope && !canEditOrg && activeScope === "shared") {
1136
1159
  setActiveScope("personal");
1137
1160
  }
1138
- }, [canEditOrg, activeScope]);
1161
+ }, [canEditOrg, activeScope, requestedScope]);
1162
+
1163
+ useEffect(() => {
1164
+ if (!requestedScope) return;
1165
+ setActiveScope(requestedScope);
1166
+ }, [requestedScope]);
1139
1167
  // Virtual MCP ids aren't in the resources store — skip the fetch so
1140
1168
  // useResource doesn't 404-flash.
1141
1169
  const resourceQuery = useResource(