@agent-native/core 0.90.10 → 0.91.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 (360) hide show
  1. package/corpus/README.md +2 -2
  2. package/corpus/core/CHANGELOG.md +30 -0
  3. package/corpus/core/docs/content/toolkit-settings.mdx +56 -3
  4. package/corpus/core/package.json +2 -1
  5. package/corpus/core/src/agent/durable-background.ts +5 -5
  6. package/corpus/core/src/agent/engine/ai-sdk-engine.ts +40 -8
  7. package/corpus/core/src/agent/engine/anthropic-engine.ts +25 -7
  8. package/corpus/core/src/agent/engine/output-tokens.ts +94 -0
  9. package/corpus/core/src/agent/production-agent.ts +34 -6
  10. package/corpus/core/src/agent/run-ownership.ts +29 -1
  11. package/corpus/core/src/agent/types.ts +3 -2
  12. package/corpus/core/src/changelog/parse.ts +78 -0
  13. package/corpus/core/src/chat-threads/schema.ts +43 -0
  14. package/corpus/core/src/chat-threads/store.ts +144 -12
  15. package/corpus/core/src/cli/workspace-dev.ts +25 -5
  16. package/corpus/core/src/client/AgentPanel.tsx +79 -14
  17. package/corpus/core/src/client/AssistantChat.tsx +359 -425
  18. package/corpus/core/src/client/analytics-session.ts +70 -0
  19. package/corpus/core/src/client/analytics.ts +175 -49
  20. package/corpus/core/src/client/chat/message-components.tsx +22 -2
  21. package/corpus/core/src/client/components/ui/message-scroller.tsx +131 -0
  22. package/corpus/core/src/client/conversation/AgentConversation.tsx +63 -41
  23. package/corpus/core/src/client/error-capture.ts +616 -0
  24. package/corpus/core/src/client/index.ts +12 -0
  25. package/corpus/core/src/client/session-replay.ts +57 -7
  26. package/corpus/core/src/client/settings/SettingsPanel.tsx +123 -1
  27. package/corpus/core/src/client/settings/SettingsTabsPage.tsx +292 -45
  28. package/corpus/core/src/client/settings/index.ts +1 -0
  29. package/corpus/core/src/client/sharing/ShareButton.tsx +14 -11
  30. package/corpus/core/src/client/sharing/ShareDialog.tsx +13 -10
  31. package/corpus/core/src/db/client.ts +12 -9
  32. package/corpus/core/src/mcp/builtin-tools.ts +29 -2
  33. package/corpus/core/src/server/agent-chat-plugin.ts +174 -79
  34. package/corpus/core/src/server/onboarding-html.ts +28 -16
  35. package/corpus/core/src/shared/reasoning-effort.ts +23 -0
  36. package/corpus/core/src/sharing/actions/list-resource-shares.ts +45 -1
  37. package/corpus/core/src/sharing/actions/share-resource.ts +9 -0
  38. package/corpus/core/src/templates/workspace-core/.agents/skills/agent-native-toolkit/SKILL.md +4 -2
  39. package/corpus/core/src/templates/workspace-core/.agents/skills/changelog/SKILL.md +9 -6
  40. package/corpus/core/src/vite/client.ts +217 -35
  41. package/corpus/templates/analytics/.agents/skills/adhoc-analysis/SKILL.md +8 -7
  42. package/corpus/templates/analytics/.agents/skills/analysis-workspace/SKILL.md +14 -10
  43. package/corpus/templates/analytics/.agents/skills/bigquery/SKILL.md +15 -15
  44. package/corpus/templates/analytics/.agents/skills/cross-source-analysis/SKILL.md +1 -0
  45. package/corpus/templates/analytics/.agents/skills/dashboard-management/SKILL.md +38 -22
  46. package/corpus/templates/analytics/.agents/skills/data-programs/SKILL.md +114 -61
  47. package/corpus/templates/analytics/.agents/skills/data-querying/SKILL.md +1 -0
  48. package/corpus/templates/analytics/.agents/skills/gong/SKILL.md +7 -7
  49. package/corpus/templates/analytics/.agents/skills/hubspot/SKILL.md +1 -0
  50. package/corpus/templates/analytics/.agents/skills/prometheus/SKILL.md +1 -1
  51. package/corpus/templates/analytics/.builder/skills/bigquery/SKILL.md +17 -17
  52. package/corpus/templates/analytics/.builder/skills/gcloud/SKILL.md +5 -5
  53. package/corpus/templates/analytics/.builder/skills/github/SKILL.md +7 -7
  54. package/corpus/templates/analytics/.builder/skills/gong/SKILL.md +12 -12
  55. package/corpus/templates/analytics/.builder/skills/grafana/SKILL.md +7 -7
  56. package/corpus/templates/analytics/.builder/skills/sentry/SKILL.md +7 -7
  57. package/corpus/templates/analytics/.builder/skills/slack/SKILL.md +6 -6
  58. package/corpus/templates/analytics/.builder/skills/stripe/SKILL.md +7 -7
  59. package/corpus/templates/analytics/AGENTS.md +47 -2
  60. package/corpus/templates/analytics/actions/add-status-page-monitor.ts +36 -0
  61. package/corpus/templates/analytics/actions/capture-test-error.ts +33 -0
  62. package/corpus/templates/analytics/actions/delete-monitor.ts +24 -0
  63. package/corpus/templates/analytics/actions/delete-status-page.ts +23 -0
  64. package/corpus/templates/analytics/actions/get-error-issue.ts +36 -0
  65. package/corpus/templates/analytics/actions/get-monitor-stats.ts +55 -0
  66. package/corpus/templates/analytics/actions/get-monitor.ts +27 -0
  67. package/corpus/templates/analytics/actions/get-public-status-page.ts +41 -0
  68. package/corpus/templates/analytics/actions/get-status-page.ts +29 -0
  69. package/corpus/templates/analytics/actions/list-error-issues.ts +40 -0
  70. package/corpus/templates/analytics/actions/list-monitors.ts +21 -0
  71. package/corpus/templates/analytics/actions/list-status-pages.ts +21 -0
  72. package/corpus/templates/analytics/actions/match-error-issues.ts +51 -0
  73. package/corpus/templates/analytics/actions/navigate.ts +58 -4
  74. package/corpus/templates/analytics/actions/remove-status-page-monitor.ts +22 -0
  75. package/corpus/templates/analytics/actions/reorder-status-page-monitors.ts +25 -0
  76. package/corpus/templates/analytics/actions/resolve-error-issue.ts +38 -0
  77. package/corpus/templates/analytics/actions/run-monitor-check.ts +23 -0
  78. package/corpus/templates/analytics/actions/save-analysis.ts +1 -0
  79. package/corpus/templates/analytics/actions/save-monitor.ts +145 -0
  80. package/corpus/templates/analytics/actions/save-status-page.ts +47 -0
  81. package/corpus/templates/analytics/actions/view-screen.ts +212 -0
  82. package/corpus/templates/analytics/app/components/layout/Header.tsx +1 -0
  83. package/corpus/templates/analytics/app/components/layout/Layout.tsx +10 -1
  84. package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +134 -39
  85. package/corpus/templates/analytics/app/components/monitoring/PublicStatusView.tsx +351 -0
  86. package/corpus/templates/analytics/app/components/monitoring/ResponseTimeChart.tsx +174 -0
  87. package/corpus/templates/analytics/app/components/monitoring/UptimeStatCards.tsx +85 -0
  88. package/corpus/templates/analytics/app/components/monitoring/UptimeTimelineBars.tsx +106 -0
  89. package/corpus/templates/analytics/app/components/monitoring/chart-utils.ts +101 -0
  90. package/corpus/templates/analytics/app/components/monitoring/index.ts +28 -0
  91. package/corpus/templates/analytics/app/components/monitoring/types.ts +42 -0
  92. package/corpus/templates/analytics/app/hooks/use-navigation-state.ts +34 -0
  93. package/corpus/templates/analytics/app/i18n/zh-TW.ts +6 -0
  94. package/corpus/templates/analytics/app/i18n-data.ts +33 -0
  95. package/corpus/templates/analytics/app/pages/DataSources.tsx +28 -0
  96. package/corpus/templates/analytics/app/pages/Settings.tsx +77 -9
  97. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/SqlChartCard.tsx +3 -3
  98. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/dashboard-layout.ts +7 -0
  99. package/corpus/templates/analytics/app/pages/monitoring/ErrorsPanel.tsx +205 -0
  100. package/corpus/templates/analytics/app/pages/monitoring/MonitoringPage.tsx +100 -0
  101. package/corpus/templates/analytics/app/pages/monitoring/UptimePanel.tsx +475 -0
  102. package/corpus/templates/analytics/app/pages/monitoring/errors/IssueDetail.tsx +372 -0
  103. package/corpus/templates/analytics/app/pages/monitoring/errors/IssueList.tsx +360 -0
  104. package/corpus/templates/analytics/app/pages/monitoring/errors/Sparkline.tsx +55 -0
  105. package/corpus/templates/analytics/app/pages/monitoring/errors/i18n.ts +106 -0
  106. package/corpus/templates/analytics/app/pages/monitoring/errors/types.ts +75 -0
  107. package/corpus/templates/analytics/app/pages/monitoring/errors/utils.ts +132 -0
  108. package/corpus/templates/analytics/app/pages/monitoring/uptime/MonitorDetail.tsx +535 -0
  109. package/corpus/templates/analytics/app/pages/monitoring/uptime/MonitorFormPage.tsx +1026 -0
  110. package/corpus/templates/analytics/app/pages/monitoring/uptime/MonitorList.tsx +311 -0
  111. package/corpus/templates/analytics/app/pages/monitoring/uptime/i18n.ts +235 -0
  112. package/corpus/templates/analytics/app/pages/monitoring/uptime/status-pages/StatusPageEditor.tsx +661 -0
  113. package/corpus/templates/analytics/app/pages/monitoring/uptime/status-pages/StatusPagesView.tsx +355 -0
  114. package/corpus/templates/analytics/app/pages/monitoring/uptime/status-pages/i18n.ts +106 -0
  115. package/corpus/templates/analytics/app/pages/monitoring/uptime/status-pages/slug.ts +24 -0
  116. package/corpus/templates/analytics/app/pages/monitoring/uptime/status-pages/types.ts +20 -0
  117. package/corpus/templates/analytics/app/pages/monitoring/uptime/status-summary.ts +87 -0
  118. package/corpus/templates/analytics/app/pages/monitoring/uptime/types.ts +161 -0
  119. package/corpus/templates/analytics/app/pages/monitoring/uptime/utils.ts +210 -0
  120. package/corpus/templates/analytics/app/pages/sessions/SessionDetailPage.tsx +76 -1
  121. package/corpus/templates/analytics/app/pages/sessions/SessionDevToolsPanel.tsx +74 -9
  122. package/corpus/templates/analytics/app/pages/sessions/SessionsPage.tsx +197 -20
  123. package/corpus/templates/analytics/app/root.tsx +33 -1
  124. package/corpus/templates/analytics/app/routes/monitoring._index.tsx +10 -0
  125. package/corpus/templates/analytics/app/routes/status.$slug.tsx +118 -0
  126. package/corpus/templates/analytics/changelog/2026-07-08-add-uptime-monitors-that-ping-your-urls-and-alert-you-when-t.md +6 -0
  127. package/corpus/templates/analytics/changelog/2026-07-08-analytics-chats-keep-large-data-dictionaries-compact-so-prov.md +6 -0
  128. package/corpus/templates/analytics/changelog/2026-07-08-create-public-status-pages-that-share-the-live-health-of-cho.md +6 -0
  129. package/corpus/templates/analytics/changelog/2026-07-08-dashboard-extension-panels-use-clearer-open-copy.md +6 -0
  130. package/corpus/templates/analytics/changelog/2026-07-08-error-capture.md +6 -0
  131. package/corpus/templates/analytics/changelog/2026-07-08-fixed-single-panel-dashboard-drags-so-they-no-longer-rewrite.md +6 -0
  132. package/corpus/templates/analytics/changelog/2026-07-08-jump-straight-from-an-error-in-a-session-recording-to-its-fu.md +6 -0
  133. package/corpus/templates/analytics/changelog/2026-07-08-monitor-detail-and-list-now-show-colorful-uptime-timelines-r.md +6 -0
  134. package/corpus/templates/analytics/changelog/2026-07-08-pinned-ask-chats-now-show-a-pin-icon-in-the-sidebar.md +6 -0
  135. package/corpus/templates/analytics/changelog/2026-07-08-publish-a-public-uptime-status-page-with-colorful-uptime-tim.md +6 -0
  136. package/corpus/templates/analytics/changelog/2026-07-08-sessions-now-hide-visitor-emails-in-demo-mode-and-show-clean.md +6 -0
  137. package/corpus/templates/analytics/changelog/2026-07-08-settings-are-cleaner-searchable-and-alerts-have-their-own-tab.md +5 -0
  138. package/corpus/templates/analytics/changelog/2026-07-08-sidebar-sections-stay-collapsed-until-opened.md +5 -0
  139. package/corpus/templates/analytics/changelog/2026-07-08-the-uptime-monitor-list-now-has-a-current-status-overview-wi.md +6 -0
  140. package/corpus/templates/analytics/docs/error-capture.md +172 -0
  141. package/corpus/templates/analytics/docs/uptime-monitoring.md +150 -0
  142. package/corpus/templates/analytics/server/db/schema-errors.ts +150 -0
  143. package/corpus/templates/analytics/server/db/schema-monitoring.ts +177 -0
  144. package/corpus/templates/analytics/server/db/schema.ts +6 -0
  145. package/corpus/templates/analytics/server/jobs/uptime-monitors.ts +123 -0
  146. package/corpus/templates/analytics/server/lib/agent-chat-plan-mode.ts +41 -0
  147. package/corpus/templates/analytics/server/lib/data-dictionary-context.ts +55 -12
  148. package/corpus/templates/analytics/server/lib/error-capture.ts +1331 -0
  149. package/corpus/templates/analytics/server/lib/first-party-analytics.ts +47 -1
  150. package/corpus/templates/analytics/server/lib/monitor-stats.ts +494 -0
  151. package/corpus/templates/analytics/server/lib/status-pages.ts +798 -0
  152. package/corpus/templates/analytics/server/lib/uptime-monitors.ts +1665 -0
  153. package/corpus/templates/analytics/server/plugins/agent-chat.ts +7 -37
  154. package/corpus/templates/analytics/server/plugins/auth.ts +11 -1
  155. package/corpus/templates/analytics/server/plugins/db.ts +408 -0
  156. package/corpus/templates/analytics/server/plugins/uptime-monitor-jobs.ts +63 -0
  157. package/corpus/templates/assets/app/routes/_index.tsx +1 -1
  158. package/corpus/templates/assets/app/routes/settings.tsx +22 -1
  159. package/corpus/templates/assets/changelog/2026-07-08-recent-drafts-keep-comfortable-side-padding.md +6 -0
  160. package/corpus/templates/assets/changelog/2026-07-08-settings-are-cleaner-and-searchable.md +5 -0
  161. package/corpus/templates/brain/app/routes/settings.tsx +43 -5
  162. package/corpus/templates/brain/changelog/2026-07-08-settings-are-cleaner-and-searchable.md +5 -0
  163. package/corpus/templates/calendar/app/pages/Settings.tsx +44 -6
  164. package/corpus/templates/calendar/changelog/2026-07-08-settings-are-cleaner-and-searchable.md +5 -0
  165. package/corpus/templates/chat/app/routes/settings.tsx +16 -1
  166. package/corpus/templates/chat/changelog/2026-07-08-settings-are-cleaner-and-searchable.md +5 -0
  167. package/corpus/templates/clips/actions/lib/audio-only-transcription.ts +79 -37
  168. package/corpus/templates/clips/actions/regenerate-chapters.ts +7 -0
  169. package/corpus/templates/clips/app/components/player/player-controls.tsx +35 -0
  170. package/corpus/templates/clips/app/components/player/video-player.tsx +162 -18
  171. package/corpus/templates/clips/app/hooks/use-auto-title.ts +15 -5
  172. package/corpus/templates/clips/app/routes/_app.settings._index.tsx +63 -6
  173. package/corpus/templates/clips/app/routes/download.tsx +12 -4
  174. package/corpus/templates/clips/app/routes/r.$recordingId.tsx +1 -0
  175. package/corpus/templates/clips/app/routes/record.tsx +18 -1
  176. package/corpus/templates/clips/changelog/2026-07-07-auto-generated-chapter-requests-now-open-the-matching-agent-.md +6 -0
  177. package/corpus/templates/clips/changelog/2026-07-07-shared-clips-start-playback-reliably-from-the-first-play-click.md +6 -0
  178. package/corpus/templates/clips/changelog/2026-07-07-the-clips-desktop-download-page-now-uses-the-agent-native-ap.md +6 -0
  179. package/corpus/templates/clips/changelog/2026-07-08-chrome-extension-camera-and-microphone-menus-now-show-which-.md +6 -0
  180. package/corpus/templates/clips/changelog/2026-07-08-chrome-extension-copies-new-clip-links-after-saving.md +6 -0
  181. package/corpus/templates/clips/changelog/2026-07-08-chrome-extension-recordings-now-continue-after-granting-came.md +6 -0
  182. package/corpus/templates/clips/changelog/2026-07-08-mobile-shared-clips-now-have-loom-style-tap-and-skip-controls.md +6 -0
  183. package/corpus/templates/clips/changelog/2026-07-08-recordings-and-uploads-copy-links-after-saving.md +6 -0
  184. package/corpus/templates/clips/changelog/2026-07-08-settings-are-cleaner-searchable-and-collapse-s3-with-builder.md +5 -0
  185. package/corpus/templates/clips/changelog/2026-07-08-transcripts-are-more-reliable-for-longer-desktop-recordings-.md +6 -0
  186. package/corpus/templates/clips/chrome-extension/public/manifest.json +1 -0
  187. package/corpus/templates/clips/chrome-extension/src/background.ts +162 -13
  188. package/corpus/templates/clips/chrome-extension/src/content-script.ts +14 -0
  189. package/corpus/templates/clips/chrome-extension/src/offscreen.ts +36 -0
  190. package/corpus/templates/clips/chrome-extension/src/overlay.ts +99 -25
  191. package/corpus/templates/clips/chrome-extension/src/permission.ts +63 -14
  192. package/corpus/templates/clips/chrome-extension/src/popup.ts +123 -23
  193. package/corpus/templates/content/actions/_builder-cms-read-client.ts +47 -0
  194. package/corpus/templates/content/actions/_database-source-utils.ts +33 -4
  195. package/corpus/templates/content/actions/add-content-database-source-field-property.ts +214 -29
  196. package/corpus/templates/content/actions/attach-content-database-source.ts +3 -0
  197. package/corpus/templates/content/actions/change-content-database-source-role.ts +1 -0
  198. package/corpus/templates/content/app/components/editor/DocumentProperties.tsx +42 -32
  199. package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +352 -81
  200. package/corpus/templates/content/app/components/editor/database/settings.tsx +49 -24
  201. package/corpus/templates/content/app/routes/_app.settings.tsx +19 -1
  202. package/corpus/templates/content/changelog/2026-07-07-builder-source-tag-fields-now-import-as-multi-select.md +6 -0
  203. package/corpus/templates/content/changelog/2026-07-08-settings-are-cleaner-and-searchable.md +5 -0
  204. package/corpus/templates/content/shared/api.ts +3 -0
  205. package/corpus/templates/content/shared/properties.ts +42 -0
  206. package/corpus/templates/design/actions/generate-design.ts +3 -0
  207. package/corpus/templates/design/actions/get-design-system.ts +147 -1
  208. package/corpus/templates/design/app/routes/settings.tsx +16 -1
  209. package/corpus/templates/design/changelog/2026-07-08-design-generation-now-follows-hydrated-builder-design-system.md +6 -0
  210. package/corpus/templates/design/changelog/2026-07-08-settings-are-cleaner-and-searchable.md +5 -0
  211. package/corpus/templates/dispatch/app/routes/settings.tsx +23 -2
  212. package/corpus/templates/dispatch/changelog/2026-07-08-settings-are-cleaner-and-searchable.md +5 -0
  213. package/corpus/templates/forms/app/routes/_app.settings.tsx +16 -1
  214. package/corpus/templates/forms/changelog/2026-07-08-settings-are-cleaner-and-searchable.md +5 -0
  215. package/corpus/templates/macros/app/routes/settings.tsx +16 -1
  216. package/corpus/templates/macros/changelog/2026-07-08-settings-are-cleaner-and-searchable.md +5 -0
  217. package/corpus/templates/mail/app/components/settings/GmailFiltersSection.tsx +1 -1
  218. package/corpus/templates/mail/app/components/settings/SnippetsSection.tsx +1 -1
  219. package/corpus/templates/mail/app/pages/SettingsPage.tsx +123 -105
  220. package/corpus/templates/mail/changelog/2026-07-08-settings-redesigned-with-a-consistent-searchable-layout.md +5 -0
  221. package/corpus/templates/plan/app/routes/settings.tsx +23 -2
  222. package/corpus/templates/plan/changelog/2026-07-08-settings-are-cleaner-and-searchable.md +5 -0
  223. package/corpus/templates/slides/actions/add-slide.ts +1 -0
  224. package/corpus/templates/slides/actions/get-design-system.ts +147 -1
  225. package/corpus/templates/slides/app/pages/Index.tsx +46 -1
  226. package/corpus/templates/slides/app/routes/settings.tsx +16 -1
  227. package/corpus/templates/slides/changelog/2026-07-08-deck-generation-now-follows-hydrated-builder-design-system-g.md +6 -0
  228. package/corpus/templates/slides/changelog/2026-07-08-settings-are-cleaner-and-searchable.md +5 -0
  229. package/dist/agent/durable-background.d.ts +1 -1
  230. package/dist/agent/durable-background.d.ts.map +1 -1
  231. package/dist/agent/durable-background.js +5 -3
  232. package/dist/agent/durable-background.js.map +1 -1
  233. package/dist/agent/engine/ai-sdk-engine.d.ts.map +1 -1
  234. package/dist/agent/engine/ai-sdk-engine.js +24 -4
  235. package/dist/agent/engine/ai-sdk-engine.js.map +1 -1
  236. package/dist/agent/engine/anthropic-engine.d.ts.map +1 -1
  237. package/dist/agent/engine/anthropic-engine.js +13 -3
  238. package/dist/agent/engine/anthropic-engine.js.map +1 -1
  239. package/dist/agent/engine/output-tokens.d.ts +27 -0
  240. package/dist/agent/engine/output-tokens.d.ts.map +1 -1
  241. package/dist/agent/engine/output-tokens.js +70 -0
  242. package/dist/agent/engine/output-tokens.js.map +1 -1
  243. package/dist/agent/production-agent.d.ts.map +1 -1
  244. package/dist/agent/production-agent.js +28 -7
  245. package/dist/agent/production-agent.js.map +1 -1
  246. package/dist/agent/run-ownership.d.ts +6 -0
  247. package/dist/agent/run-ownership.d.ts.map +1 -1
  248. package/dist/agent/run-ownership.js +11 -1
  249. package/dist/agent/run-ownership.js.map +1 -1
  250. package/dist/agent/types.d.ts +3 -2
  251. package/dist/agent/types.d.ts.map +1 -1
  252. package/dist/agent/types.js.map +1 -1
  253. package/dist/changelog/parse.d.ts +7 -0
  254. package/dist/changelog/parse.d.ts.map +1 -1
  255. package/dist/changelog/parse.js +64 -0
  256. package/dist/changelog/parse.js.map +1 -1
  257. package/dist/chat-threads/schema.d.ts +445 -0
  258. package/dist/chat-threads/schema.d.ts.map +1 -0
  259. package/dist/chat-threads/schema.js +39 -0
  260. package/dist/chat-threads/schema.js.map +1 -0
  261. package/dist/chat-threads/store.d.ts +12 -0
  262. package/dist/chat-threads/store.d.ts.map +1 -1
  263. package/dist/chat-threads/store.js +99 -10
  264. package/dist/chat-threads/store.js.map +1 -1
  265. package/dist/cli/workspace-dev.d.ts.map +1 -1
  266. package/dist/cli/workspace-dev.js +20 -5
  267. package/dist/cli/workspace-dev.js.map +1 -1
  268. package/dist/client/AgentPanel.d.ts.map +1 -1
  269. package/dist/client/AgentPanel.js +35 -7
  270. package/dist/client/AgentPanel.js.map +1 -1
  271. package/dist/client/AssistantChat.d.ts.map +1 -1
  272. package/dist/client/AssistantChat.js +105 -183
  273. package/dist/client/AssistantChat.js.map +1 -1
  274. package/dist/client/analytics-session.d.ts +3 -0
  275. package/dist/client/analytics-session.d.ts.map +1 -0
  276. package/dist/client/analytics-session.js +66 -0
  277. package/dist/client/analytics-session.js.map +1 -0
  278. package/dist/client/analytics.d.ts +32 -0
  279. package/dist/client/analytics.d.ts.map +1 -1
  280. package/dist/client/analytics.js +116 -46
  281. package/dist/client/analytics.js.map +1 -1
  282. package/dist/client/chat/message-components.d.ts +2 -1
  283. package/dist/client/chat/message-components.d.ts.map +1 -1
  284. package/dist/client/chat/message-components.js +16 -6
  285. package/dist/client/chat/message-components.js.map +1 -1
  286. package/dist/client/components/ui/message-scroller.d.ts +16 -0
  287. package/dist/client/components/ui/message-scroller.d.ts.map +1 -0
  288. package/dist/client/components/ui/message-scroller.js +25 -0
  289. package/dist/client/components/ui/message-scroller.js.map +1 -0
  290. package/dist/client/conversation/AgentConversation.d.ts +1 -1
  291. package/dist/client/conversation/AgentConversation.d.ts.map +1 -1
  292. package/dist/client/conversation/AgentConversation.js +3 -8
  293. package/dist/client/conversation/AgentConversation.js.map +1 -1
  294. package/dist/client/error-capture.d.ts +99 -0
  295. package/dist/client/error-capture.d.ts.map +1 -0
  296. package/dist/client/error-capture.js +437 -0
  297. package/dist/client/error-capture.js.map +1 -0
  298. package/dist/client/index.d.ts +2 -2
  299. package/dist/client/index.d.ts.map +1 -1
  300. package/dist/client/index.js +3 -1
  301. package/dist/client/index.js.map +1 -1
  302. package/dist/client/session-replay.d.ts +22 -0
  303. package/dist/client/session-replay.d.ts.map +1 -1
  304. package/dist/client/session-replay.js +45 -4
  305. package/dist/client/session-replay.js.map +1 -1
  306. package/dist/client/settings/SettingsPanel.d.ts.map +1 -1
  307. package/dist/client/settings/SettingsPanel.js +100 -5
  308. package/dist/client/settings/SettingsPanel.js.map +1 -1
  309. package/dist/client/settings/SettingsTabsPage.d.ts +49 -1
  310. package/dist/client/settings/SettingsTabsPage.d.ts.map +1 -1
  311. package/dist/client/settings/SettingsTabsPage.js +131 -19
  312. package/dist/client/settings/SettingsTabsPage.js.map +1 -1
  313. package/dist/client/settings/index.d.ts +1 -1
  314. package/dist/client/settings/index.d.ts.map +1 -1
  315. package/dist/client/settings/index.js.map +1 -1
  316. package/dist/client/sharing/ShareButton.d.ts.map +1 -1
  317. package/dist/client/sharing/ShareButton.js +13 -8
  318. package/dist/client/sharing/ShareButton.js.map +1 -1
  319. package/dist/client/sharing/ShareDialog.d.ts.map +1 -1
  320. package/dist/client/sharing/ShareDialog.js +12 -7
  321. package/dist/client/sharing/ShareDialog.js.map +1 -1
  322. package/dist/collab/routes.d.ts +1 -1
  323. package/dist/collab/struct-routes.d.ts +1 -1
  324. package/dist/db/client.d.ts.map +1 -1
  325. package/dist/db/client.js +12 -7
  326. package/dist/db/client.js.map +1 -1
  327. package/dist/mcp/builtin-tools.d.ts.map +1 -1
  328. package/dist/mcp/builtin-tools.js +21 -2
  329. package/dist/mcp/builtin-tools.js.map +1 -1
  330. package/dist/notifications/routes.d.ts +1 -1
  331. package/dist/observability/routes.d.ts +5 -5
  332. package/dist/org/schema.d.ts +15 -15
  333. package/dist/progress/routes.d.ts +1 -1
  334. package/dist/provider-api/corpus-jobs.d.ts +2 -2
  335. package/dist/resources/handlers.d.ts +3 -3
  336. package/dist/secrets/routes.d.ts +9 -9
  337. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  338. package/dist/server/agent-chat-plugin.js +109 -73
  339. package/dist/server/agent-chat-plugin.js.map +1 -1
  340. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  341. package/dist/server/onboarding-html.d.ts.map +1 -1
  342. package/dist/server/onboarding-html.js +28 -16
  343. package/dist/server/onboarding-html.js.map +1 -1
  344. package/dist/shared/reasoning-effort.d.ts +1 -0
  345. package/dist/shared/reasoning-effort.d.ts.map +1 -1
  346. package/dist/shared/reasoning-effort.js +18 -0
  347. package/dist/shared/reasoning-effort.js.map +1 -1
  348. package/dist/sharing/actions/list-resource-shares.js +30 -1
  349. package/dist/sharing/actions/list-resource-shares.js.map +1 -1
  350. package/dist/sharing/actions/share-resource.js +6 -0
  351. package/dist/sharing/actions/share-resource.js.map +1 -1
  352. package/dist/templates/workspace-core/.agents/skills/agent-native-toolkit/SKILL.md +4 -2
  353. package/dist/templates/workspace-core/.agents/skills/changelog/SKILL.md +9 -6
  354. package/dist/vite/client.d.ts.map +1 -1
  355. package/dist/vite/client.js +192 -30
  356. package/dist/vite/client.js.map +1 -1
  357. package/docs/content/toolkit-settings.mdx +56 -3
  358. package/package.json +2 -1
  359. package/src/templates/workspace-core/.agents/skills/agent-native-toolkit/SKILL.md +4 -2
  360. package/src/templates/workspace-core/.agents/skills/changelog/SKILL.md +9 -6
@@ -0,0 +1,100 @@
1
+ import { AgentToggleButton, useT } from "@agent-native/core/client";
2
+ import { RunsTray } from "@agent-native/core/client/progress";
3
+ import { IconAlertTriangle, IconHeartbeat } from "@tabler/icons-react";
4
+ import { useSearchParams } from "react-router";
5
+
6
+ import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
7
+
8
+ import { ErrorsPanel } from "./ErrorsPanel";
9
+ import { UptimePanel } from "./UptimePanel";
10
+
11
+ type MonitoringView = "uptime" | "errors";
12
+
13
+ function isMonitoringView(value: string | null): value is MonitoringView {
14
+ return value === "uptime" || value === "errors";
15
+ }
16
+
17
+ /**
18
+ * Monitoring tab shell. Hosts two independently-owned panels:
19
+ * - Uptime (URL/status/text checks + alerting)
20
+ * - Errors (Sentry-style exception capture linked to session replays)
21
+ *
22
+ * The active panel is reflected in the `?view=` query param so links are
23
+ * shareable and the agent can deep-link a specific view via the navigate
24
+ * action. This shell is intentionally thin — panel content lives in the
25
+ * feature-owned UptimePanel / ErrorsPanel modules.
26
+ */
27
+ export default function MonitoringPage() {
28
+ const t = useT();
29
+ const [searchParams, setSearchParams] = useSearchParams();
30
+ const rawView = searchParams.get("view");
31
+ const view: MonitoringView = isMonitoringView(rawView) ? rawView : "uptime";
32
+
33
+ // A panel is in a sub-view (full-page form / detail / status-page config) when
34
+ // it has drilled in via its own query param. The section-switcher tabs only
35
+ // belong at the list level; inside a sub-view the panel's own "Back" header is
36
+ // the way out. Param names mirror UptimePanel (`monitor`, `statuspage`) and
37
+ // ErrorsPanel (`issue`); `monitor=new` / `statuspage=list` count as sub-views.
38
+ const inSubView =
39
+ (view === "uptime" &&
40
+ (searchParams.get("monitor") !== null ||
41
+ searchParams.get("statuspage") !== null)) ||
42
+ (view === "errors" && searchParams.get("issue") !== null);
43
+
44
+ const setView = (next: string) => {
45
+ setSearchParams(
46
+ (prev) => {
47
+ const params = new URLSearchParams(prev);
48
+ if (next === "uptime") params.delete("view");
49
+ else params.set("view", next);
50
+ return params;
51
+ },
52
+ { replace: true },
53
+ );
54
+ };
55
+
56
+ const toggles = (
57
+ <div className="flex shrink-0 items-center gap-2">
58
+ <RunsTray />
59
+ <AgentToggleButton />
60
+ </div>
61
+ );
62
+
63
+ return (
64
+ <div className="mx-auto max-w-6xl space-y-6">
65
+ <Tabs value={view} onValueChange={setView} className="space-y-6">
66
+ {/* List level: one header row with the section switcher on the left and
67
+ the relocated agent/chat toggle on the right (replacing the
68
+ suppressed framework Header). */}
69
+ {inSubView ? null : (
70
+ <div className="flex items-center justify-between gap-2">
71
+ <TabsList>
72
+ <TabsTrigger value="uptime" className="gap-2">
73
+ <IconHeartbeat className="h-4 w-4" />
74
+ {t("navigation.monitoringUptime")}
75
+ </TabsTrigger>
76
+ <TabsTrigger value="errors" className="gap-2">
77
+ <IconAlertTriangle className="h-4 w-4" />
78
+ {t("navigation.monitoringErrors")}
79
+ </TabsTrigger>
80
+ </TabsList>
81
+ {toggles}
82
+ </div>
83
+ )}
84
+ {/* Sub-view: overlay the toggle at the top-right so it sits on the same
85
+ row as the panel's own "Back" header instead of a lone row above. */}
86
+ <div className={inSubView ? "relative" : undefined}>
87
+ {inSubView ? (
88
+ <div className="absolute end-0 top-0 z-20">{toggles}</div>
89
+ ) : null}
90
+ <TabsContent value="uptime" className="focus-visible:outline-none">
91
+ <UptimePanel />
92
+ </TabsContent>
93
+ <TabsContent value="errors" className="focus-visible:outline-none">
94
+ <ErrorsPanel />
95
+ </TabsContent>
96
+ </div>
97
+ </Tabs>
98
+ </div>
99
+ );
100
+ }
@@ -0,0 +1,475 @@
1
+ /**
2
+ * Uptime monitoring panel — OWNED BY THE UPTIME MONITORING FEATURE.
3
+ *
4
+ * Swaps between three query-param-driven views (all under the Monitoring tab):
5
+ * - list: ?view=uptime
6
+ * - detail: ?view=uptime&monitor=<id>
7
+ * - create: ?view=uptime&monitor=new
8
+ * - edit: ?view=uptime&monitor=<id>&edit=1
9
+ * Everything is deep-linkable + back-button friendly and mirrored into
10
+ * `application_state` so the agent knows what the user views. Data flows through
11
+ * the monitor actions; `useChangeVersions(["monitors"])` keeps the UI fresh as
12
+ * background sweeps and agent edits land.
13
+ */
14
+ import {
15
+ setClientAppState,
16
+ useActionMutation,
17
+ useActionQuery,
18
+ useChangeVersions,
19
+ } from "@agent-native/core/client";
20
+ import {
21
+ IconLink,
22
+ IconPlus,
23
+ IconRefresh,
24
+ IconSearch,
25
+ } from "@tabler/icons-react";
26
+ import { useQueryClient } from "@tanstack/react-query";
27
+ import { useEffect, useMemo, useState } from "react";
28
+ import { useSearchParams } from "react-router";
29
+ import { toast } from "sonner";
30
+
31
+ import {
32
+ AlertDialog,
33
+ AlertDialogAction,
34
+ AlertDialogCancel,
35
+ AlertDialogContent,
36
+ AlertDialogDescription,
37
+ AlertDialogFooter,
38
+ AlertDialogHeader,
39
+ AlertDialogTitle,
40
+ } from "@/components/ui/alert-dialog";
41
+ import { Button } from "@/components/ui/button";
42
+ import { Input } from "@/components/ui/input";
43
+
44
+ import { fmt, useUptimeT } from "./uptime/i18n";
45
+ import { MonitorDetail } from "./uptime/MonitorDetail";
46
+ import { MonitorFormPage } from "./uptime/MonitorFormPage";
47
+ import { MonitorList } from "./uptime/MonitorList";
48
+ import { StatusPagesView } from "./uptime/status-pages/StatusPagesView";
49
+ import type {
50
+ CheckOutcome,
51
+ MonitorStats,
52
+ MonitorSummary,
53
+ SaveMonitorInput,
54
+ } from "./uptime/types";
55
+ import { hostFromUrl, statusLabel } from "./uptime/utils";
56
+
57
+ const LIST_KEY = ["action", "list-monitors", undefined];
58
+
59
+ function payloadFromMonitor(
60
+ monitor: MonitorSummary,
61
+ overrides: Partial<SaveMonitorInput> = {},
62
+ ): SaveMonitorInput {
63
+ return {
64
+ id: monitor.id,
65
+ name: monitor.name,
66
+ url: monitor.url,
67
+ method: monitor.method,
68
+ requestHeaders: monitor.requestHeaders,
69
+ requestBody: monitor.requestBody,
70
+ intervalSeconds: monitor.intervalSeconds,
71
+ timeoutMs: monitor.timeoutMs,
72
+ expectedStatus: monitor.expectedStatus,
73
+ assertions: monitor.assertions,
74
+ followRedirects: monitor.followRedirects,
75
+ severity: monitor.severity,
76
+ channels: monitor.channels,
77
+ emailRecipients: monitor.emailRecipients,
78
+ cooldownMinutes: monitor.cooldownMinutes,
79
+ enabled: monitor.enabled,
80
+ ...overrides,
81
+ };
82
+ }
83
+
84
+ export function UptimePanel() {
85
+ const t = useUptimeT();
86
+ const queryClient = useQueryClient();
87
+ const [searchParams, setSearchParams] = useSearchParams();
88
+ const monitorParam = searchParams.get("monitor");
89
+ const statusPageParam = searchParams.get("statuspage");
90
+ const isCreate = monitorParam === "new";
91
+ const selectedId = isCreate ? null : monitorParam;
92
+ const isEditing = !!selectedId && searchParams.get("edit") === "1";
93
+
94
+ const [search, setSearch] = useState("");
95
+ const [monitorToDelete, setMonitorToDelete] = useState<MonitorSummary | null>(
96
+ null,
97
+ );
98
+ const [runningId, setRunningId] = useState<string | null>(null);
99
+
100
+ const sync = useChangeVersions(["monitors", "action"]);
101
+
102
+ const { data, isLoading } = useActionQuery<MonitorSummary[]>(
103
+ "list-monitors",
104
+ undefined,
105
+ { staleTime: 10_000 },
106
+ );
107
+
108
+ // Aggregate stats for the whole list (status/uptime windows + 90-day timeline)
109
+ // power the list's per-row uptime bars and the "current status" overview.
110
+ const { data: statsList } = useActionQuery<MonitorStats[]>(
111
+ "get-monitor-stats",
112
+ { timelineDays: 90 },
113
+ { staleTime: 30_000 },
114
+ );
115
+
116
+ const saveMonitor = useActionMutation<MonitorSummary, SaveMonitorInput>(
117
+ "save-monitor",
118
+ );
119
+ const deleteMonitor = useActionMutation<
120
+ { ok: boolean; id: string },
121
+ { id: string }
122
+ >("delete-monitor");
123
+ const runCheck = useActionMutation<CheckOutcome, { id: string }>(
124
+ "run-monitor-check",
125
+ );
126
+
127
+ const monitors = useMemo(() => (Array.isArray(data) ? data : []), [data]);
128
+
129
+ const statsById = useMemo(() => {
130
+ const map = new Map<string, MonitorStats>();
131
+ for (const stat of statsList ?? []) map.set(stat.monitorId, stat);
132
+ return map;
133
+ }, [statsList]);
134
+
135
+ // Refresh list + detail when a background sweep or agent edit records a
136
+ // "monitors" change (useDbSync bumps the version this hook reads).
137
+ useEffect(() => {
138
+ queryClient.invalidateQueries({ queryKey: ["action", "list-monitors"] });
139
+ queryClient.invalidateQueries({ queryKey: ["action", "get-monitor"] });
140
+ queryClient.invalidateQueries({
141
+ queryKey: ["action", "get-monitor-stats"],
142
+ });
143
+ // eslint-disable-next-line react-hooks/exhaustive-deps
144
+ }, [sync]);
145
+
146
+ const selectedMonitor = useMemo(
147
+ () => monitors.find((m) => m.id === selectedId) ?? null,
148
+ [monitors, selectedId],
149
+ );
150
+
151
+ // Mirror the current selection / form mode into application_state.
152
+ useEffect(() => {
153
+ if (statusPageParam !== null) {
154
+ const spMode =
155
+ statusPageParam === "list"
156
+ ? "status-pages"
157
+ : statusPageParam === "new"
158
+ ? "status-page-create"
159
+ : "status-page-edit";
160
+ void setClientAppState("monitoring", {
161
+ view: "uptime",
162
+ mode: spMode,
163
+ ...(statusPageParam !== "list" && statusPageParam !== "new"
164
+ ? { statusPageId: statusPageParam }
165
+ : {}),
166
+ }).catch(() => {});
167
+ return;
168
+ }
169
+ const mode = isCreate ? "create" : isEditing ? "edit" : "view";
170
+ const value = selectedMonitor
171
+ ? {
172
+ view: "uptime",
173
+ mode,
174
+ monitorId: selectedMonitor.id,
175
+ monitorName: selectedMonitor.name,
176
+ url: selectedMonitor.url,
177
+ status: selectedMonitor.lastStatus,
178
+ }
179
+ : selectedId
180
+ ? { view: "uptime", mode, monitorId: selectedId }
181
+ : { view: "uptime", mode };
182
+ void setClientAppState("monitoring", value).catch(() => {});
183
+ }, [selectedMonitor, selectedId, isCreate, isEditing, statusPageParam]);
184
+
185
+ const updateParams = (
186
+ mutate: (params: URLSearchParams) => void,
187
+ options?: { replace?: boolean },
188
+ ) => {
189
+ setSearchParams(
190
+ (prev) => {
191
+ const params = new URLSearchParams(prev);
192
+ mutate(params);
193
+ return params;
194
+ },
195
+ { replace: options?.replace ?? false },
196
+ );
197
+ };
198
+
199
+ const showList = () =>
200
+ updateParams((params) => {
201
+ params.delete("monitor");
202
+ params.delete("edit");
203
+ });
204
+
205
+ const showDetail = (id: string, options?: { replace?: boolean }) =>
206
+ updateParams((params) => {
207
+ params.set("monitor", id);
208
+ params.delete("edit");
209
+ }, options);
210
+
211
+ const openCreate = () =>
212
+ updateParams((params) => {
213
+ params.set("monitor", "new");
214
+ params.delete("edit");
215
+ });
216
+
217
+ const openEdit = (monitor: MonitorSummary) =>
218
+ updateParams((params) => {
219
+ params.set("monitor", monitor.id);
220
+ params.set("edit", "1");
221
+ });
222
+
223
+ const openStatusPages = () =>
224
+ updateParams((params) => {
225
+ params.set("statuspage", "list");
226
+ params.delete("monitor");
227
+ params.delete("edit");
228
+ });
229
+
230
+ const handleSaved = (saved: MonitorSummary) => {
231
+ // Replace the form entry with the monitor's detail so Back skips the form.
232
+ showDetail(saved.id, { replace: true });
233
+ };
234
+
235
+ const handleFormCancel = () => {
236
+ if (selectedId) showDetail(selectedId, { replace: true });
237
+ else showList();
238
+ };
239
+
240
+ const handleToggle = async (monitor: MonitorSummary, enabled: boolean) => {
241
+ const previous =
242
+ queryClient.getQueryData<MonitorSummary[]>(LIST_KEY) ?? monitors;
243
+ queryClient.setQueryData<MonitorSummary[]>(LIST_KEY, (old) =>
244
+ (old ?? []).map((m) => (m.id === monitor.id ? { ...m, enabled } : m)),
245
+ );
246
+ try {
247
+ await saveMonitor.mutateAsync(payloadFromMonitor(monitor, { enabled }));
248
+ toast.success(enabled ? t.enabledToast : t.disabledToast);
249
+ } catch (err) {
250
+ queryClient.setQueryData<MonitorSummary[]>(LIST_KEY, previous);
251
+ toast.error(
252
+ fmt(t.saveFailed, {
253
+ message: err instanceof Error ? err.message : String(err),
254
+ }),
255
+ );
256
+ }
257
+ };
258
+
259
+ const handleRunCheck = async (monitor: MonitorSummary) => {
260
+ setRunningId(monitor.id);
261
+ queryClient.setQueryData<MonitorSummary[]>(LIST_KEY, (old) =>
262
+ (old ?? []).map((m) =>
263
+ m.id === monitor.id ? { ...m, lastStatus: "running" } : m,
264
+ ),
265
+ );
266
+ try {
267
+ const outcome = await runCheck.mutateAsync({ id: monitor.id });
268
+ if (outcome.ok) {
269
+ toast.success(
270
+ fmt(t.checkOk, {
271
+ name: monitor.name,
272
+ latency: outcome.latencyMs ?? 0,
273
+ }),
274
+ );
275
+ } else {
276
+ toast.error(
277
+ fmt(t.checkDown, {
278
+ name: monitor.name,
279
+ status: statusLabel(outcome.status, t).toLowerCase(),
280
+ }),
281
+ );
282
+ }
283
+ } catch (err) {
284
+ toast.error(
285
+ fmt(t.checkFailed, {
286
+ message: err instanceof Error ? err.message : String(err),
287
+ }),
288
+ );
289
+ } finally {
290
+ setRunningId(null);
291
+ }
292
+ };
293
+
294
+ const handleDelete = async () => {
295
+ if (!monitorToDelete) return;
296
+ const target = monitorToDelete;
297
+ setMonitorToDelete(null);
298
+ const previous =
299
+ queryClient.getQueryData<MonitorSummary[]>(LIST_KEY) ?? monitors;
300
+ queryClient.setQueryData<MonitorSummary[]>(LIST_KEY, (old) =>
301
+ (old ?? []).filter((m) => m.id !== target.id),
302
+ );
303
+ if (selectedId === target.id) showList();
304
+ try {
305
+ await deleteMonitor.mutateAsync({ id: target.id });
306
+ toast.success(t.deleted);
307
+ } catch (err) {
308
+ queryClient.setQueryData<MonitorSummary[]>(LIST_KEY, previous);
309
+ toast.error(
310
+ fmt(t.deleteFailed, {
311
+ message: err instanceof Error ? err.message : String(err),
312
+ }),
313
+ );
314
+ }
315
+ };
316
+
317
+ const refresh = () => {
318
+ queryClient.invalidateQueries({ queryKey: ["action", "list-monitors"] });
319
+ queryClient.invalidateQueries({ queryKey: ["action", "get-monitor"] });
320
+ queryClient.invalidateQueries({
321
+ queryKey: ["action", "get-monitor-stats"],
322
+ });
323
+ };
324
+
325
+ // Status pages — config sub-view (list / create / edit)
326
+ if (statusPageParam !== null) {
327
+ return <StatusPagesView />;
328
+ }
329
+
330
+ // Create / edit — full-page form
331
+ if (isCreate || isEditing) {
332
+ return (
333
+ <>
334
+ <MonitorFormPage
335
+ monitorId={isCreate ? null : selectedId}
336
+ initialMonitor={selectedMonitor}
337
+ onCancel={handleFormCancel}
338
+ onSaved={handleSaved}
339
+ />
340
+ <DeleteDialog
341
+ monitor={monitorToDelete}
342
+ onCancel={() => setMonitorToDelete(null)}
343
+ onConfirm={handleDelete}
344
+ pending={deleteMonitor.isPending}
345
+ />
346
+ </>
347
+ );
348
+ }
349
+
350
+ // Detail view
351
+ if (selectedId) {
352
+ return (
353
+ <>
354
+ <MonitorDetail
355
+ monitorId={selectedId}
356
+ fallback={selectedMonitor ?? undefined}
357
+ onBack={showList}
358
+ onEdit={openEdit}
359
+ onDelete={setMonitorToDelete}
360
+ onRunCheck={handleRunCheck}
361
+ running={runningId === selectedId}
362
+ />
363
+ <DeleteDialog
364
+ monitor={monitorToDelete}
365
+ onCancel={() => setMonitorToDelete(null)}
366
+ onConfirm={handleDelete}
367
+ pending={deleteMonitor.isPending}
368
+ />
369
+ </>
370
+ );
371
+ }
372
+
373
+ const filtered = search.trim()
374
+ ? monitors.filter((m) => {
375
+ const q = search.toLowerCase();
376
+ return (
377
+ m.name.toLowerCase().includes(q) ||
378
+ m.url.toLowerCase().includes(q) ||
379
+ hostFromUrl(m.url).toLowerCase().includes(q)
380
+ );
381
+ })
382
+ : monitors;
383
+
384
+ return (
385
+ <>
386
+ <div className="space-y-4">
387
+ <div className="flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between">
388
+ <div className="relative sm:w-72">
389
+ <IconSearch className="pointer-events-none absolute start-2.5 top-1/2 size-4 -translate-y-1/2 text-muted-foreground/60" />
390
+ <Input
391
+ type="search"
392
+ value={search}
393
+ onChange={(e) => setSearch(e.target.value)}
394
+ placeholder={t.searchPlaceholder}
395
+ className="ps-8"
396
+ />
397
+ </div>
398
+ <div className="flex items-center gap-2">
399
+ <Button
400
+ variant="outline"
401
+ size="sm"
402
+ onClick={refresh}
403
+ aria-label={t.refresh}
404
+ >
405
+ <IconRefresh className="size-3.5" />
406
+ </Button>
407
+ <Button variant="outline" size="sm" onClick={openStatusPages}>
408
+ <IconLink className="size-3.5" />
409
+ {t.statusPagesButton}
410
+ </Button>
411
+ <Button size="sm" onClick={openCreate}>
412
+ <IconPlus className="size-3.5" />
413
+ {t.addMonitor}
414
+ </Button>
415
+ </div>
416
+ </div>
417
+
418
+ <MonitorList
419
+ monitors={filtered}
420
+ statsById={statsById}
421
+ isLoading={isLoading}
422
+ hasSearch={search.trim().length > 0}
423
+ runningId={runningId}
424
+ onSelect={(m) => showDetail(m.id)}
425
+ onToggle={handleToggle}
426
+ onRunCheck={handleRunCheck}
427
+ onCreate={openCreate}
428
+ />
429
+ </div>
430
+
431
+ <DeleteDialog
432
+ monitor={monitorToDelete}
433
+ onCancel={() => setMonitorToDelete(null)}
434
+ onConfirm={handleDelete}
435
+ pending={deleteMonitor.isPending}
436
+ />
437
+ </>
438
+ );
439
+ }
440
+
441
+ function DeleteDialog({
442
+ monitor,
443
+ onCancel,
444
+ onConfirm,
445
+ pending,
446
+ }: {
447
+ monitor: MonitorSummary | null;
448
+ onCancel: () => void;
449
+ onConfirm: () => void;
450
+ pending: boolean;
451
+ }) {
452
+ const t = useUptimeT();
453
+ return (
454
+ <AlertDialog open={!!monitor} onOpenChange={(open) => !open && onCancel()}>
455
+ <AlertDialogContent>
456
+ <AlertDialogHeader>
457
+ <AlertDialogTitle>{t.deleteTitle}</AlertDialogTitle>
458
+ <AlertDialogDescription>
459
+ {fmt(t.deleteDescription, { name: monitor?.name ?? "" })}
460
+ </AlertDialogDescription>
461
+ </AlertDialogHeader>
462
+ <AlertDialogFooter>
463
+ <AlertDialogCancel>{t.cancel}</AlertDialogCancel>
464
+ <AlertDialogAction
465
+ onClick={onConfirm}
466
+ disabled={pending}
467
+ className="bg-destructive text-destructive-foreground hover:bg-destructive/90"
468
+ >
469
+ {t.deleteConfirm}
470
+ </AlertDialogAction>
471
+ </AlertDialogFooter>
472
+ </AlertDialogContent>
473
+ </AlertDialog>
474
+ );
475
+ }