From 756ae33d056af50d52739a9456d5e026789c30f9 Mon Sep 17 00:00:00 2001 From: mono Date: Fri, 16 Oct 2026 12:02:48 +0000 Subject: [PATCH] chore: import clean Agent Desk snapshot (6/7) --- screenshots/en/5.png | Bin 0 -> 95876 bytes scripts/cloudflare-email-worker/package.json | 17 + .../cloudflare-email-worker/pnpm-lock.yaml | 984 +++++++++++ scripts/cloudflare-email-worker/src/index.ts | 58 + scripts/cloudflare-email-worker/wrangler.toml | 8 + scripts/i18n_untranslated.py | 169 ++ web/.env.example | 1 + web/.gitignore | 42 + web/README.md | 36 + web/app/(dashboard)/dashboard.css | 368 ++++ .../dashboard/_components/alert-list.tsx | 74 + .../dashboard/_components/dashboard-home.tsx | 169 ++ .../_components/setup-readiness-banner.tsx | 173 ++ .../dashboard/_components/summary-cards.tsx | 108 ++ .../dashboard/_components/team-load-panel.tsx | 112 ++ .../dashboard/_components/trend-panel.tsx | 141 ++ .../(dashboard)/dashboard/agent-runs/page.tsx | 163 ++ .../_components/batch-schedule-dialog.tsx | 547 ++++++ .../_components/calendar-date-range.test.mjs | 19 + .../_components/calendar-date-range.ts | 72 + .../_components/calendar-time-layout.test.mjs | 59 + .../_components/calendar-time-layout.ts | 87 + .../_components/calendar.tsx | 603 +++++++ .../agent-team-schedules/_components/edit.tsx | 321 ++++ .../dashboard/agent-team-schedules/page.tsx | 494 ++++++ .../dashboard/agents/_components/edit.tsx | 659 +++++++ .../agents/_components/team-edit.tsx | 361 ++++ .../agents/_components/team-sidebar.tsx | 291 ++++ web/app/(dashboard)/dashboard/agents/page.tsx | 299 ++++ .../config-workbench-copy.test.mjs | 82 + .../_components/config-workbench.tsx | 1177 +++++++++++++ .../(dashboard)/dashboard/ai-agents/page.tsx | 337 ++++ .../dashboard/ai-configs/_components/edit.tsx | 479 ++++++ .../(dashboard)/dashboard/ai-configs/page.tsx | 299 ++++ .../_components/workflow-run-audit-graph.tsx | 115 ++ .../dashboard/ai-workflow-runs/page.tsx | 523 ++++++ .../_components/official-workflow-editor.tsx | 99 ++ .../_components/workflow-usage-dialog.tsx | 84 + .../_components/workflow-versions-dialog.tsx | 116 ++ .../_components/workflow-workbench.tsx | 436 +++++ .../dashboard/ai-workflows/page.tsx | 168 ++ .../dashboard/channels/_components/edit.tsx | 1514 +++++++++++++++++ .../_components/test-email-connection.tsx | 69 + .../(dashboard)/dashboard/channels/page.tsx | 228 +++ .../(dashboard)/dashboard/companies/page.tsx | 211 +++ .../_components/detail.tsx | 539 ++++++ .../dashboard/conversation-monitor/page.tsx | 927 ++++++++++ .../_components/agent-message-editor.tsx | 117 ++ .../conversations/_components/chat-panel.tsx | 1056 ++++++++++++ .../_components/conversation-info-panel.tsx | 1085 ++++++++++++ .../_components/conversation-list.tsx | 102 ++ .../conversation-summary-dialog.tsx | 147 ++ .../_components/conversation-tag-picker.tsx | 125 ++ .../_components/conversation-workbench.tsx | 561 ++++++ .../dashboard/conversations/page.tsx | 12 + .../dashboard/customers/_components/edit.tsx | 4 + .../(dashboard)/dashboard/customers/page.tsx | 266 +++ web/app/(dashboard)/dashboard/docs/page.tsx | 21 + .../knowledge/_components/debug-panel.tsx | 232 +++ .../knowledge/_components/document-edit.tsx | 314 ++++ .../knowledge/_components/document-list.tsx | 814 +++++++++ .../knowledge/_components/faq-edit.tsx | 289 ++++ .../_components/faq-import-dialog.tsx | 255 +++ .../knowledge/_components/faq-list.tsx | 653 +++++++ .../_components/knowledge-base-edit.tsx | 492 ++++++ .../knowledge-bulk-move-dialog.tsx | 106 ++ .../_components/knowledge-content-detail.tsx | 213 +++ .../_components/knowledge-directory-panel.tsx | 765 +++++++++ .../knowledge-directory-sort.test.mjs | 120 ++ .../_components/knowledge-directory-sort.ts | 233 +++ .../_components/retrieve-log-detail.tsx | 282 +++ .../_components/retrieve-log-list.tsx | 301 ++++ .../_components/selection-checkbox.tsx | 26 + .../dashboard/knowledge/detail/page.tsx | 163 ++ .../(dashboard)/dashboard/knowledge/page.tsx | 170 ++ web/app/(dashboard)/dashboard/layout.tsx | 75 + .../dashboard/login/oidc/callback/page.tsx | 67 + web/app/(dashboard)/dashboard/login/page.tsx | 14 + web/app/(dashboard)/dashboard/mcp/page.tsx | 382 +++++ .../dashboard/notifications/page.tsx | 128 ++ web/app/(dashboard)/dashboard/page.tsx | 5 + .../dashboard/permissions/page.tsx | 169 ++ .../dashboard/quick-replies/page.tsx | 244 +++ .../roles/_components/assign-permissions.tsx | 292 ++++ .../dashboard/roles/_components/create.tsx | 192 +++ web/app/(dashboard)/dashboard/roles/page.tsx | 427 +++++ .../(dashboard)/dashboard/settings/page.tsx | 156 ++ .../setup/_components/setup-wizard-view.tsx | 751 ++++++++ web/app/(dashboard)/dashboard/setup/page.tsx | 5 + .../_components/debug-dialog.tsx | 529 ++++++ .../skill-definition/_components/edit.tsx | 396 +++++ .../dashboard/skill-definition/page.tsx | 254 +++ .../support/_components/help-workbench.tsx | 608 +++++++ .../support/_components/support-admin.tsx | 210 +++ .../_components/support-config-panel.tsx | 385 +++++ .../support/community-categories/page.tsx | 5 + .../dashboard/support/community/page.tsx | 5 + .../dashboard/support/config/page.tsx | 5 + .../dashboard/support/docs/page.tsx | 5 + .../(dashboard)/dashboard/support/page.tsx | 5 + .../dashboard/tags/_components/edit.tsx | 259 +++ web/app/(dashboard)/dashboard/tags/page.tsx | 656 +++++++ ...create-ticket-from-conversation-dialog.tsx | 66 + .../dashboard/tickets/_components/edit.tsx | 342 ++++ .../_components/ticket-assign-dialog.tsx | 226 +++ .../_components/ticket-detail-dialog.tsx | 639 +++++++ .../_components/ticket-status-badge.tsx | 30 + .../(dashboard)/dashboard/tickets/page.tsx | 426 +++++ .../users/_components/assign-roles.tsx | 345 ++++ .../dashboard/users/_components/create.tsx | 390 +++++ .../dashboard/users/_components/edit.tsx | 281 +++ .../_components/initial-password-dialog.tsx | 80 + .../users/_components/reset-password.tsx | 106 ++ web/app/(dashboard)/dashboard/users/page.tsx | 534 ++++++ web/app/(dashboard)/layout.tsx | 59 + web/app/(dashboard)/legal/privacy/page.tsx | 5 + web/app/(dashboard)/legal/terms/page.tsx | 5 + web/app/(dashboard)/page.tsx | 9 + web/app/(dashboard)/workbench/layout.tsx | 69 + web/app/(dashboard)/workbench/page.tsx | 5 + .../(dashboard)/workbench/tickets/page.tsx | 3 + web/app/(support)/layout.tsx | 47 + web/app/(support)/support.css | 118 ++ .../_components/community-category-nav.tsx | 66 + .../support/_components/community-frame.tsx | 64 + .../_components/community-post-list.tsx | 49 + .../_components/post-article-content.tsx | 74 + .../_components/support-article-content.tsx | 311 ++++ .../_components/support-article-toc.tsx | 123 ++ .../_components/support-auth-provider.tsx | 35 + .../_components/support-community-route.ts | 89 + .../support/_components/support-header.tsx | 275 +++ .../_components/support-help-navigation.tsx | 90 + .../_components/support-mobile-menu.tsx | 144 ++ .../_components/support-page-shell.tsx | 18 + .../support/_components/support-ui.tsx | 67 + .../_components/use-support-help-reader.ts | 102 ++ .../(support)/support/chat/closed/page.tsx | 25 + web/app/(support)/support/chat/page.tsx | 43 + .../support/community/categories/page.tsx | 5 + web/app/(support)/support/community/page.tsx | 5 + .../community/posts/_components/post-list.tsx | 80 + .../community/posts/_components/post-ui.tsx | 98 ++ .../posts/detail/_components/comment-item.tsx | 197 +++ .../posts/detail/_components/post-detail.tsx | 218 +++ .../support/community/posts/detail/page.tsx | 5 + .../posts/new/_components/create-post.tsx | 177 ++ .../support/community/posts/new/page.tsx | 5 + .../support/community/posts/page.tsx | 5 + web/app/(support)/support/demo/page.tsx | 5 + .../support/docs/_components/help-reader.tsx | 392 +++++ web/app/(support)/support/docs/page.tsx | 5 + .../support/login/_components/login-page.tsx | 172 ++ web/app/(support)/support/login/page.tsx | 5 + web/app/(support)/support/page-client.tsx | 110 ++ web/app/(support)/support/page.tsx | 5 + .../profile/_components/profile-page.tsx | 94 + .../edit/_components/profile-edit-page.tsx | 98 ++ .../(support)/support/profile/edit/page.tsx | 5 + web/app/(support)/support/profile/page.tsx | 5 + web/app/(support)/typeset.css | 297 ++++ web/app/favicon.ico | Bin 0 -> 17548 bytes web/components.json | 25 + .../agent-realtime-provider.test.mjs | 38 + web/components/agent-realtime-provider.tsx | 9 + web/components/api-error-provider.tsx | 45 + web/components/app-sidebar.tsx | 77 + web/components/auth-provider.test.mjs | 15 + web/components/auth-provider.tsx | 76 + web/components/change-password-dialog.tsx | 155 ++ web/components/chart-area-interactive.tsx | 159 ++ web/components/chat/agent-activity-bubble.tsx | 54 + .../chat/conversation-message-bubble.tsx | 64 + .../chat/conversation-message-row.tsx | 109 ++ .../chat/conversation-message-scroller.tsx | 151 ++ web/components/chat/shared-message-editor.tsx | 729 ++++++++ web/components/company-picker.tsx | 289 ++++ web/components/confirm-provider.tsx | 122 ++ web/components/content-editor/convert.ts | 26 + .../content-editor/editor-mode-switch.tsx | 73 + web/components/content-editor/html-editor.tsx | 376 ++++ web/components/content-editor/index.tsx | 195 +++ .../content-editor/markdown-editor.css | 48 + .../content-editor/markdown-editor.tsx | 179 ++ web/components/content-editor/toolbar.css | 20 + web/components/content-editor/toolbar.tsx | 142 ++ web/components/content-editor/types.ts | 44 + .../conversation-actions/close-dialog.tsx | 205 +++ .../conversation-actions/transfer-dialog.tsx | 254 +++ web/components/customer-form-dialog.tsx | 90 + web/components/customer-form.tsx | 490 ++++++ .../customer-link-or-create-dialog.tsx | 279 +++ web/components/dashboard-page.tsx | 100 ++ web/components/dashboard-placeholder.tsx | 73 + .../crud/dashboard-crud-field-control.tsx | 321 ++++ .../crud/dashboard-crud-form-dialog.tsx | 295 ++++ .../dashboard/crud/dashboard-crud-page.tsx | 741 ++++++++ .../dashboard/crud/dashboard-crud-presets.tsx | 130 ++ .../crud/dashboard-crud-utils.test.mjs | 250 +++ .../dashboard/crud/dashboard-crud-utils.ts | 262 +++ web/components/dashboard/crud/index.ts | 30 + .../crud/use-dashboard-crud-filters.ts | 65 + .../dashboard/list/dashboard-list-page.tsx | 290 ++++ web/components/dashboard/list/index.ts | 12 + .../list/use-dashboard-paged-list.ts | 136 ++ web/components/data-table.tsx | 146 ++ web/components/editor/DESIGN.md | 235 +++ web/components/editor/html.tsx | 150 ++ web/components/editor/index.tsx | 49 + web/components/editor/markdown.tsx | 172 ++ web/components/editor/toolbar.tsx | 63 + web/components/editor/types.ts | 21 + web/components/im-message-html.tsx | 86 + web/components/image-input.tsx | 153 ++ web/components/image-lightbox.tsx | 521 ++++++ web/components/json-code-editor.tsx | 77 + web/components/json-tree-viewer.tsx | 70 + web/components/json-viewer.tsx | 79 + web/components/legal-document-page.tsx | 110 ++ web/components/list-pagination.tsx | 90 + web/components/load-more.tsx | 234 +++ web/components/login-form.tsx | 279 +++ web/components/nav-documents.tsx | 97 ++ web/components/nav-main.test.mjs | 20 + web/components/nav-main.tsx | 160 ++ web/components/nav-secondary.tsx | 53 + web/components/nav-user.tsx | 155 ++ web/components/notification-provider.tsx | 164 ++ .../operator-readiness-indicator.tsx | 283 +++ web/components/option-combobox.tsx | 192 +++ web/components/palette-toggle.test.mjs | 28 + web/components/palette-toggle.tsx | 113 ++ web/components/project-dialog.tsx | 178 ++ web/components/realtime-connection-status.tsx | 64 + web/components/safe-rich-html.tsx | 183 ++ web/components/section-cards.tsx | 111 ++ web/components/session-provider.tsx | 110 ++ web/components/site-header.test.mjs | 14 + web/components/site-header.tsx | 88 + .../support-chat/chat-error-boundary.tsx | 51 + web/components/support-chat/chat-shell.tsx | 439 +++++ .../support-chat/close-navigation.test.mjs | 29 + .../support-chat/close-navigation.ts | 5 + .../support-chat/connection-status.tsx | 38 + .../conversation-switcher.test.mjs | 21 + .../support-chat/conversation-switcher.tsx | 262 +++ web/components/support-chat/csat-card.tsx | 228 +++ .../support-chat/customer-message-editor.tsx | 34 + .../support-chat/demo-navigation.test.mjs | 29 + .../support-chat/demo-navigation.ts | 5 + web/components/support-chat/message-list.tsx | 335 ++++ .../support-chat/new-request-dialog.tsx | 171 ++ .../support-chat/prompt-starters.tsx | 51 + web/components/support-chat/widget-demo.tsx | 466 +++++ web/components/tag-selector.tsx | 355 ++++ web/components/theme-provider.tsx | 17 + web/components/theme-toggle.tsx | 95 ++ web/components/ui/avatar.tsx | 109 ++ web/components/ui/badge.tsx | 52 + web/components/ui/breadcrumb.tsx | 125 ++ web/components/ui/bubble.tsx | 128 ++ web/components/ui/button-group.tsx | 87 + web/components/ui/button.tsx | 60 + web/components/ui/calendar.tsx | 221 +++ web/components/ui/card.tsx | 103 ++ web/components/ui/chart.tsx | 356 ++++ web/components/ui/checkbox.tsx | 29 + web/components/ui/collapsible.tsx | 21 + web/components/ui/combobox.tsx | 297 ++++ web/components/ui/command.tsx | 196 +++ web/components/ui/context-menu.tsx | 271 +++ web/components/ui/dialog.tsx | 157 ++ web/components/ui/drawer.tsx | 131 ++ web/components/ui/dropdown-menu.tsx | 268 +++ web/components/ui/field.tsx | 238 +++ web/components/ui/input-group.tsx | 158 ++ web/components/ui/input.tsx | 20 + web/components/ui/label.tsx | 20 + 278 files changed, 53808 insertions(+) create mode 100644 screenshots/en/5.png create mode 100644 scripts/cloudflare-email-worker/package.json create mode 100644 scripts/cloudflare-email-worker/pnpm-lock.yaml create mode 100644 scripts/cloudflare-email-worker/src/index.ts create mode 100644 scripts/cloudflare-email-worker/wrangler.toml create mode 100644 scripts/i18n_untranslated.py create mode 100644 web/.env.example create mode 100644 web/.gitignore create mode 100644 web/README.md create mode 100644 web/app/(dashboard)/dashboard.css create mode 100644 web/app/(dashboard)/dashboard/_components/alert-list.tsx create mode 100644 web/app/(dashboard)/dashboard/_components/dashboard-home.tsx create mode 100644 web/app/(dashboard)/dashboard/_components/setup-readiness-banner.tsx create mode 100644 web/app/(dashboard)/dashboard/_components/summary-cards.tsx create mode 100644 web/app/(dashboard)/dashboard/_components/team-load-panel.tsx create mode 100644 web/app/(dashboard)/dashboard/_components/trend-panel.tsx create mode 100644 web/app/(dashboard)/dashboard/agent-runs/page.tsx create mode 100644 web/app/(dashboard)/dashboard/agent-team-schedules/_components/batch-schedule-dialog.tsx create mode 100644 web/app/(dashboard)/dashboard/agent-team-schedules/_components/calendar-date-range.test.mjs create mode 100644 web/app/(dashboard)/dashboard/agent-team-schedules/_components/calendar-date-range.ts create mode 100644 web/app/(dashboard)/dashboard/agent-team-schedules/_components/calendar-time-layout.test.mjs create mode 100644 web/app/(dashboard)/dashboard/agent-team-schedules/_components/calendar-time-layout.ts create mode 100644 web/app/(dashboard)/dashboard/agent-team-schedules/_components/calendar.tsx create mode 100644 web/app/(dashboard)/dashboard/agent-team-schedules/_components/edit.tsx create mode 100644 web/app/(dashboard)/dashboard/agent-team-schedules/page.tsx create mode 100644 web/app/(dashboard)/dashboard/agents/_components/edit.tsx create mode 100644 web/app/(dashboard)/dashboard/agents/_components/team-edit.tsx create mode 100644 web/app/(dashboard)/dashboard/agents/_components/team-sidebar.tsx create mode 100644 web/app/(dashboard)/dashboard/agents/page.tsx create mode 100644 web/app/(dashboard)/dashboard/ai-agents/_components/config-workbench-copy.test.mjs create mode 100644 web/app/(dashboard)/dashboard/ai-agents/_components/config-workbench.tsx create mode 100644 web/app/(dashboard)/dashboard/ai-agents/page.tsx create mode 100644 web/app/(dashboard)/dashboard/ai-configs/_components/edit.tsx create mode 100644 web/app/(dashboard)/dashboard/ai-configs/page.tsx create mode 100644 web/app/(dashboard)/dashboard/ai-workflow-runs/_components/workflow-run-audit-graph.tsx create mode 100644 web/app/(dashboard)/dashboard/ai-workflow-runs/page.tsx create mode 100644 web/app/(dashboard)/dashboard/ai-workflows/_components/official-workflow-editor.tsx create mode 100644 web/app/(dashboard)/dashboard/ai-workflows/_components/workflow-usage-dialog.tsx create mode 100644 web/app/(dashboard)/dashboard/ai-workflows/_components/workflow-versions-dialog.tsx create mode 100644 web/app/(dashboard)/dashboard/ai-workflows/_components/workflow-workbench.tsx create mode 100644 web/app/(dashboard)/dashboard/ai-workflows/page.tsx create mode 100644 web/app/(dashboard)/dashboard/channels/_components/edit.tsx create mode 100644 web/app/(dashboard)/dashboard/channels/_components/test-email-connection.tsx create mode 100644 web/app/(dashboard)/dashboard/channels/page.tsx create mode 100644 web/app/(dashboard)/dashboard/companies/page.tsx create mode 100644 web/app/(dashboard)/dashboard/conversation-monitor/_components/detail.tsx create mode 100644 web/app/(dashboard)/dashboard/conversation-monitor/page.tsx create mode 100644 web/app/(dashboard)/dashboard/conversations/_components/agent-message-editor.tsx create mode 100644 web/app/(dashboard)/dashboard/conversations/_components/chat-panel.tsx create mode 100644 web/app/(dashboard)/dashboard/conversations/_components/conversation-info-panel.tsx create mode 100644 web/app/(dashboard)/dashboard/conversations/_components/conversation-list.tsx create mode 100644 web/app/(dashboard)/dashboard/conversations/_components/conversation-summary-dialog.tsx create mode 100644 web/app/(dashboard)/dashboard/conversations/_components/conversation-tag-picker.tsx create mode 100644 web/app/(dashboard)/dashboard/conversations/_components/conversation-workbench.tsx create mode 100644 web/app/(dashboard)/dashboard/conversations/page.tsx create mode 100644 web/app/(dashboard)/dashboard/customers/_components/edit.tsx create mode 100644 web/app/(dashboard)/dashboard/customers/page.tsx create mode 100644 web/app/(dashboard)/dashboard/docs/page.tsx create mode 100644 web/app/(dashboard)/dashboard/knowledge/_components/debug-panel.tsx create mode 100644 web/app/(dashboard)/dashboard/knowledge/_components/document-edit.tsx create mode 100644 web/app/(dashboard)/dashboard/knowledge/_components/document-list.tsx create mode 100644 web/app/(dashboard)/dashboard/knowledge/_components/faq-edit.tsx create mode 100644 web/app/(dashboard)/dashboard/knowledge/_components/faq-import-dialog.tsx create mode 100644 web/app/(dashboard)/dashboard/knowledge/_components/faq-list.tsx create mode 100644 web/app/(dashboard)/dashboard/knowledge/_components/knowledge-base-edit.tsx create mode 100644 web/app/(dashboard)/dashboard/knowledge/_components/knowledge-bulk-move-dialog.tsx create mode 100644 web/app/(dashboard)/dashboard/knowledge/_components/knowledge-content-detail.tsx create mode 100644 web/app/(dashboard)/dashboard/knowledge/_components/knowledge-directory-panel.tsx create mode 100644 web/app/(dashboard)/dashboard/knowledge/_components/knowledge-directory-sort.test.mjs create mode 100644 web/app/(dashboard)/dashboard/knowledge/_components/knowledge-directory-sort.ts create mode 100644 web/app/(dashboard)/dashboard/knowledge/_components/retrieve-log-detail.tsx create mode 100644 web/app/(dashboard)/dashboard/knowledge/_components/retrieve-log-list.tsx create mode 100644 web/app/(dashboard)/dashboard/knowledge/_components/selection-checkbox.tsx create mode 100644 web/app/(dashboard)/dashboard/knowledge/detail/page.tsx create mode 100644 web/app/(dashboard)/dashboard/knowledge/page.tsx create mode 100644 web/app/(dashboard)/dashboard/layout.tsx create mode 100644 web/app/(dashboard)/dashboard/login/oidc/callback/page.tsx create mode 100644 web/app/(dashboard)/dashboard/login/page.tsx create mode 100644 web/app/(dashboard)/dashboard/mcp/page.tsx create mode 100644 web/app/(dashboard)/dashboard/notifications/page.tsx create mode 100644 web/app/(dashboard)/dashboard/page.tsx create mode 100644 web/app/(dashboard)/dashboard/permissions/page.tsx create mode 100644 web/app/(dashboard)/dashboard/quick-replies/page.tsx create mode 100644 web/app/(dashboard)/dashboard/roles/_components/assign-permissions.tsx create mode 100644 web/app/(dashboard)/dashboard/roles/_components/create.tsx create mode 100644 web/app/(dashboard)/dashboard/roles/page.tsx create mode 100644 web/app/(dashboard)/dashboard/settings/page.tsx create mode 100644 web/app/(dashboard)/dashboard/setup/_components/setup-wizard-view.tsx create mode 100644 web/app/(dashboard)/dashboard/setup/page.tsx create mode 100644 web/app/(dashboard)/dashboard/skill-definition/_components/debug-dialog.tsx create mode 100644 web/app/(dashboard)/dashboard/skill-definition/_components/edit.tsx create mode 100644 web/app/(dashboard)/dashboard/skill-definition/page.tsx create mode 100644 web/app/(dashboard)/dashboard/support/_components/help-workbench.tsx create mode 100644 web/app/(dashboard)/dashboard/support/_components/support-admin.tsx create mode 100644 web/app/(dashboard)/dashboard/support/_components/support-config-panel.tsx create mode 100644 web/app/(dashboard)/dashboard/support/community-categories/page.tsx create mode 100644 web/app/(dashboard)/dashboard/support/community/page.tsx create mode 100644 web/app/(dashboard)/dashboard/support/config/page.tsx create mode 100644 web/app/(dashboard)/dashboard/support/docs/page.tsx create mode 100644 web/app/(dashboard)/dashboard/support/page.tsx create mode 100644 web/app/(dashboard)/dashboard/tags/_components/edit.tsx create mode 100644 web/app/(dashboard)/dashboard/tags/page.tsx create mode 100644 web/app/(dashboard)/dashboard/tickets/_components/create-ticket-from-conversation-dialog.tsx create mode 100644 web/app/(dashboard)/dashboard/tickets/_components/edit.tsx create mode 100644 web/app/(dashboard)/dashboard/tickets/_components/ticket-assign-dialog.tsx create mode 100644 web/app/(dashboard)/dashboard/tickets/_components/ticket-detail-dialog.tsx create mode 100644 web/app/(dashboard)/dashboard/tickets/_components/ticket-status-badge.tsx create mode 100644 web/app/(dashboard)/dashboard/tickets/page.tsx create mode 100644 web/app/(dashboard)/dashboard/users/_components/assign-roles.tsx create mode 100644 web/app/(dashboard)/dashboard/users/_components/create.tsx create mode 100644 web/app/(dashboard)/dashboard/users/_components/edit.tsx create mode 100644 web/app/(dashboard)/dashboard/users/_components/initial-password-dialog.tsx create mode 100644 web/app/(dashboard)/dashboard/users/_components/reset-password.tsx create mode 100644 web/app/(dashboard)/dashboard/users/page.tsx create mode 100644 web/app/(dashboard)/layout.tsx create mode 100644 web/app/(dashboard)/legal/privacy/page.tsx create mode 100644 web/app/(dashboard)/legal/terms/page.tsx create mode 100644 web/app/(dashboard)/page.tsx create mode 100644 web/app/(dashboard)/workbench/layout.tsx create mode 100644 web/app/(dashboard)/workbench/page.tsx create mode 100644 web/app/(dashboard)/workbench/tickets/page.tsx create mode 100644 web/app/(support)/layout.tsx create mode 100644 web/app/(support)/support.css create mode 100644 web/app/(support)/support/_components/community-category-nav.tsx create mode 100644 web/app/(support)/support/_components/community-frame.tsx create mode 100644 web/app/(support)/support/_components/community-post-list.tsx create mode 100644 web/app/(support)/support/_components/post-article-content.tsx create mode 100644 web/app/(support)/support/_components/support-article-content.tsx create mode 100644 web/app/(support)/support/_components/support-article-toc.tsx create mode 100644 web/app/(support)/support/_components/support-auth-provider.tsx create mode 100644 web/app/(support)/support/_components/support-community-route.ts create mode 100644 web/app/(support)/support/_components/support-header.tsx create mode 100644 web/app/(support)/support/_components/support-help-navigation.tsx create mode 100644 web/app/(support)/support/_components/support-mobile-menu.tsx create mode 100644 web/app/(support)/support/_components/support-page-shell.tsx create mode 100644 web/app/(support)/support/_components/support-ui.tsx create mode 100644 web/app/(support)/support/_components/use-support-help-reader.ts create mode 100644 web/app/(support)/support/chat/closed/page.tsx create mode 100644 web/app/(support)/support/chat/page.tsx create mode 100644 web/app/(support)/support/community/categories/page.tsx create mode 100644 web/app/(support)/support/community/page.tsx create mode 100644 web/app/(support)/support/community/posts/_components/post-list.tsx create mode 100644 web/app/(support)/support/community/posts/_components/post-ui.tsx create mode 100644 web/app/(support)/support/community/posts/detail/_components/comment-item.tsx create mode 100644 web/app/(support)/support/community/posts/detail/_components/post-detail.tsx create mode 100644 web/app/(support)/support/community/posts/detail/page.tsx create mode 100644 web/app/(support)/support/community/posts/new/_components/create-post.tsx create mode 100644 web/app/(support)/support/community/posts/new/page.tsx create mode 100644 web/app/(support)/support/community/posts/page.tsx create mode 100644 web/app/(support)/support/demo/page.tsx create mode 100644 web/app/(support)/support/docs/_components/help-reader.tsx create mode 100644 web/app/(support)/support/docs/page.tsx create mode 100644 web/app/(support)/support/login/_components/login-page.tsx create mode 100644 web/app/(support)/support/login/page.tsx create mode 100644 web/app/(support)/support/page-client.tsx create mode 100644 web/app/(support)/support/page.tsx create mode 100644 web/app/(support)/support/profile/_components/profile-page.tsx create mode 100644 web/app/(support)/support/profile/edit/_components/profile-edit-page.tsx create mode 100644 web/app/(support)/support/profile/edit/page.tsx create mode 100644 web/app/(support)/support/profile/page.tsx create mode 100644 web/app/(support)/typeset.css create mode 100644 web/app/favicon.ico create mode 100644 web/components.json create mode 100644 web/components/agent-realtime-provider.test.mjs create mode 100644 web/components/agent-realtime-provider.tsx create mode 100644 web/components/api-error-provider.tsx create mode 100644 web/components/app-sidebar.tsx create mode 100644 web/components/auth-provider.test.mjs create mode 100644 web/components/auth-provider.tsx create mode 100644 web/components/change-password-dialog.tsx create mode 100644 web/components/chart-area-interactive.tsx create mode 100644 web/components/chat/agent-activity-bubble.tsx create mode 100644 web/components/chat/conversation-message-bubble.tsx create mode 100644 web/components/chat/conversation-message-row.tsx create mode 100644 web/components/chat/conversation-message-scroller.tsx create mode 100644 web/components/chat/shared-message-editor.tsx create mode 100644 web/components/company-picker.tsx create mode 100644 web/components/confirm-provider.tsx create mode 100644 web/components/content-editor/convert.ts create mode 100644 web/components/content-editor/editor-mode-switch.tsx create mode 100644 web/components/content-editor/html-editor.tsx create mode 100644 web/components/content-editor/index.tsx create mode 100644 web/components/content-editor/markdown-editor.css create mode 100644 web/components/content-editor/markdown-editor.tsx create mode 100644 web/components/content-editor/toolbar.css create mode 100644 web/components/content-editor/toolbar.tsx create mode 100644 web/components/content-editor/types.ts create mode 100644 web/components/conversation-actions/close-dialog.tsx create mode 100644 web/components/conversation-actions/transfer-dialog.tsx create mode 100644 web/components/customer-form-dialog.tsx create mode 100644 web/components/customer-form.tsx create mode 100644 web/components/customer-link-or-create-dialog.tsx create mode 100644 web/components/dashboard-page.tsx create mode 100644 web/components/dashboard-placeholder.tsx create mode 100644 web/components/dashboard/crud/dashboard-crud-field-control.tsx create mode 100644 web/components/dashboard/crud/dashboard-crud-form-dialog.tsx create mode 100644 web/components/dashboard/crud/dashboard-crud-page.tsx create mode 100644 web/components/dashboard/crud/dashboard-crud-presets.tsx create mode 100644 web/components/dashboard/crud/dashboard-crud-utils.test.mjs create mode 100644 web/components/dashboard/crud/dashboard-crud-utils.ts create mode 100644 web/components/dashboard/crud/index.ts create mode 100644 web/components/dashboard/crud/use-dashboard-crud-filters.ts create mode 100644 web/components/dashboard/list/dashboard-list-page.tsx create mode 100644 web/components/dashboard/list/index.ts create mode 100644 web/components/dashboard/list/use-dashboard-paged-list.ts create mode 100644 web/components/data-table.tsx create mode 100644 web/components/editor/DESIGN.md create mode 100644 web/components/editor/html.tsx create mode 100644 web/components/editor/index.tsx create mode 100644 web/components/editor/markdown.tsx create mode 100644 web/components/editor/toolbar.tsx create mode 100644 web/components/editor/types.ts create mode 100644 web/components/im-message-html.tsx create mode 100644 web/components/image-input.tsx create mode 100644 web/components/image-lightbox.tsx create mode 100644 web/components/json-code-editor.tsx create mode 100644 web/components/json-tree-viewer.tsx create mode 100644 web/components/json-viewer.tsx create mode 100644 web/components/legal-document-page.tsx create mode 100644 web/components/list-pagination.tsx create mode 100644 web/components/load-more.tsx create mode 100644 web/components/login-form.tsx create mode 100644 web/components/nav-documents.tsx create mode 100644 web/components/nav-main.test.mjs create mode 100644 web/components/nav-main.tsx create mode 100644 web/components/nav-secondary.tsx create mode 100644 web/components/nav-user.tsx create mode 100644 web/components/notification-provider.tsx create mode 100644 web/components/operator-readiness-indicator.tsx create mode 100644 web/components/option-combobox.tsx create mode 100644 web/components/palette-toggle.test.mjs create mode 100644 web/components/palette-toggle.tsx create mode 100644 web/components/project-dialog.tsx create mode 100644 web/components/realtime-connection-status.tsx create mode 100644 web/components/safe-rich-html.tsx create mode 100644 web/components/section-cards.tsx create mode 100644 web/components/session-provider.tsx create mode 100644 web/components/site-header.test.mjs create mode 100644 web/components/site-header.tsx create mode 100644 web/components/support-chat/chat-error-boundary.tsx create mode 100644 web/components/support-chat/chat-shell.tsx create mode 100644 web/components/support-chat/close-navigation.test.mjs create mode 100644 web/components/support-chat/close-navigation.ts create mode 100644 web/components/support-chat/connection-status.tsx create mode 100644 web/components/support-chat/conversation-switcher.test.mjs create mode 100644 web/components/support-chat/conversation-switcher.tsx create mode 100644 web/components/support-chat/csat-card.tsx create mode 100644 web/components/support-chat/customer-message-editor.tsx create mode 100644 web/components/support-chat/demo-navigation.test.mjs create mode 100644 web/components/support-chat/demo-navigation.ts create mode 100644 web/components/support-chat/message-list.tsx create mode 100644 web/components/support-chat/new-request-dialog.tsx create mode 100644 web/components/support-chat/prompt-starters.tsx create mode 100644 web/components/support-chat/widget-demo.tsx create mode 100644 web/components/tag-selector.tsx create mode 100644 web/components/theme-provider.tsx create mode 100644 web/components/theme-toggle.tsx create mode 100644 web/components/ui/avatar.tsx create mode 100644 web/components/ui/badge.tsx create mode 100644 web/components/ui/breadcrumb.tsx create mode 100644 web/components/ui/bubble.tsx create mode 100644 web/components/ui/button-group.tsx create mode 100644 web/components/ui/button.tsx create mode 100644 web/components/ui/calendar.tsx create mode 100644 web/components/ui/card.tsx create mode 100644 web/components/ui/chart.tsx create mode 100644 web/components/ui/checkbox.tsx create mode 100644 web/components/ui/collapsible.tsx create mode 100644 web/components/ui/combobox.tsx create mode 100644 web/components/ui/command.tsx create mode 100644 web/components/ui/context-menu.tsx create mode 100644 web/components/ui/dialog.tsx create mode 100644 web/components/ui/drawer.tsx create mode 100644 web/components/ui/dropdown-menu.tsx create mode 100644 web/components/ui/field.tsx create mode 100644 web/components/ui/input-group.tsx create mode 100644 web/components/ui/input.tsx create mode 100644 web/components/ui/label.tsx diff --git a/screenshots/en/5.png b/screenshots/en/5.png new file mode 100644 index 0000000000000000000000000000000000000000..e5b7a040602fd9fc0d0ba04169c1845c10e4337d GIT binary patch literal 95876 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

_pcLyC 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�O0B+v>1lUG`?A;@`J4H}%%aG0I}`2j}o6vY5pu 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

FZkQ|pwa1J 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

8n%vY<8587~jrg^y<`squvY;unS(`=Lrk( z>DPI4BL&CXCmG8L8{hNgn`IKD$d}Eb#R!jgh}f&$Qzc1EOtc&*v?}RGEEHxcU!o1U zB9O6%=*)C~zqM9mv=60yZ*T8)u~HJE_m_A~hxSh45rqk=m^E@1EhQy>qovYzSploB z%v`BzD~pU7SOnZ6B(y|q^lnc_+Kg|g79cwL?-uSZDZ||lg8iDE zxZ~yk{dqzh^BLa8>s~APiOZ;0Bvlj6C7KpDUU7NXjsx|k)OjOJRmbHzzfbkk<}icO zy@vT=sBjkh?8Xo9R!6V*tL1GIN`wfl-<^N3@Dh5A-x1U)KxkKclLAs;pD77dwTg<0 zv-1wwuANA1|GPTPT;t+plxPUd&;Or&eRcJm?dvb~`+j~qKHuk6-5tZqot4|~8*1z+ z-Jaa{>--;RCuaZD|I@|)>nClzajaK*yIjovx>{htdTOe6_@{MeA0|I}_Uzg7=j}7U zUYiO``?`v?Y0pLf?QXZ9^kIKc3TQ=@YUOjVTOV8x3kaAn4Y&tjd-RiCp4`6=U5nm7 zQC|ks_?V#y+_aImD>5tVRDaXi>^Z`R+PRfa7|i4A-u_NT>@?&$x-zAcG3imud}g}* z+T+R)o3}YaN6hU^r@4R{myl$Mg|@BjU-iRJT^b>aL=v7)dZNp>Xm)ERbf$IPsiq`w zm|^xW;bXAy^=8C$Ezi8y6zcr*K~`T!qX#^0e&F2V1q&YR7rg&pz3N%H*i9X&PVr+9 zlQtN40#|d@^>wrcIlK zHs0H|=(&eYUUO_+dgs)it*x!Vo~Px`%840XGYvZR!powwzk(8A!~HmkM^Aw=16.13'} + + '@cloudflare/unenv-preset@2.0.2': + resolution: {integrity: sha512-nyzYnlZjjV5xT3LizahG1Iu6mnrCaxglJ04rZLpDwlDVDZ7v46lNsfxhV3A/xtfgQuSHmLnc6SVI+KwBpc3Lwg==} + peerDependencies: + unenv: 2.0.0-rc.14 + workerd: ^1.20250124.0 + peerDependenciesMeta: + workerd: + optional: true + + '@cloudflare/workerd-darwin-64@1.20250718.0': + resolution: {integrity: sha512-FHf4t7zbVN8yyXgQ/r/GqLPaYZSGUVzeR7RnL28Mwj2djyw2ZergvytVc7fdGcczl6PQh+VKGfZCfUqpJlbi9g==} + engines: {node: '>=16'} + cpu: [x64] + os: [darwin] + + '@cloudflare/workerd-darwin-arm64@1.20250718.0': + resolution: {integrity: sha512-fUiyUJYyqqp4NqJ0YgGtp4WJh/II/YZsUnEb6vVy5Oeas8lUOxnN+ZOJ8N/6/5LQCVAtYCChRiIrBbfhTn5Z8Q==} + engines: {node: '>=16'} + cpu: [arm64] + os: [darwin] + + '@cloudflare/workerd-linux-64@1.20250718.0': + resolution: {integrity: sha512-5+eb3rtJMiEwp08Kryqzzu8d1rUcK+gdE442auo5eniMpT170Dz0QxBrqkg2Z48SFUPYbj+6uknuA5tzdRSUSg==} + engines: {node: '>=16'} + cpu: [x64] + os: [linux] + + '@cloudflare/workerd-linux-arm64@1.20250718.0': + resolution: {integrity: sha512-Aa2M/DVBEBQDdATMbn217zCSFKE+ud/teS+fFS+OQqKABLn0azO2qq6ANAHYOIE6Q3Sq4CxDIQr8lGdaJHwUog==} + engines: {node: '>=16'} + cpu: [arm64] + os: [linux] + + '@cloudflare/workerd-windows-64@1.20250718.0': + resolution: {integrity: sha512-dY16RXKffmugnc67LTbyjdDHZn5NoTF1yHEf2fN4+OaOnoGSp3N1x77QubTDwqZ9zECWxgQfDLjddcH8dWeFhg==} + engines: {node: '>=16'} + cpu: [x64] + os: [win32] + + '@cloudflare/workers-types@4.20260702.1': + resolution: {integrity: sha512-mOhf5TUEB1m2vPrxtqoIGfz0fUC9xyxRDx5gWHy5s+OCo6dcV+g7wI1R7gYCMFohhqF/2y2xeKVwMwCJjfn/WA==} + + '@cspotcode/source-map-support@0.8.1': + resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} + engines: {node: '>=12'} + + '@emnapi/runtime@1.11.3': + resolution: {integrity: sha512-Xz4Tpyki7XyrpbUK1jR1AhdAdaXyhhY4lZ3neLodmhpuWfy2PAQN5B46sAiU4liOXGLkHypn/qU+jvfWSCYYLA==} + + '@esbuild-plugins/node-globals-polyfill@0.2.3': + resolution: {integrity: sha512-r3MIryXDeXDOZh7ih1l/yE9ZLORCd5e8vWg02azWRGj5SPTuoh69A2AIyn0Z31V/kHBfZ4HgWJ+OK3GTTwLmnw==} + peerDependencies: + esbuild: '*' + + '@esbuild-plugins/node-modules-polyfill@0.2.2': + resolution: {integrity: sha512-LXV7QsWJxRuMYvKbiznh+U1ilIop3g2TeKRzUxOG5X3YITc8JyyTa90BmLwqqv0YnX4v32CSlG+vsziZp9dMvA==} + peerDependencies: + esbuild: '*' + + '@esbuild/android-arm64@0.17.19': + resolution: {integrity: sha512-KBMWvEZooR7+kzY0BtbTQn0OAYY7CsiydT63pVEaPtVYF0hXbUaOyZog37DKxK7NF3XacBJOpYT4adIJh+avxA==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.17.19': + resolution: {integrity: sha512-rIKddzqhmav7MSmoFCmDIb6e2W57geRsM94gV2l38fzhXMwq7hZoClug9USI2pFRGL06f4IOPHHpFNOkWieR8A==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.17.19': + resolution: {integrity: sha512-uUTTc4xGNDT7YSArp/zbtmbhO0uEEK9/ETW29Wk1thYUJBz3IVnvgEiEwEa9IeLyvnpKrWK64Utw2bgUmDveww==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.17.19': + resolution: {integrity: sha512-80wEoCfF/hFKM6WE1FyBHc9SfUblloAWx6FJkFWTWiCoht9Mc0ARGEM47e67W9rI09YoUxJL68WHfDRYEAvOhg==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.17.19': + resolution: {integrity: sha512-IJM4JJsLhRYr9xdtLytPLSH9k/oxR3boaUIYiHkAawtwNOXKE8KoU8tMvryogdcT8AU+Bflmh81Xn6Q0vTZbQw==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.17.19': + resolution: {integrity: sha512-pBwbc7DufluUeGdjSU5Si+P3SoMF5DQ/F/UmTSb8HXO80ZEAJmrykPyzo1IfNbAoaqw48YRpv8shwd1NoI0jcQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.17.19': + resolution: {integrity: sha512-4lu+n8Wk0XlajEhbEffdy2xy53dpR06SlzvhGByyg36qJw6Kpfk7cp45DR/62aPH9mtJRmIyrXAS5UWBrJT6TQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.17.19': + resolution: {integrity: sha512-ct1Tg3WGwd3P+oZYqic+YZF4snNl2bsnMKRkb3ozHmnM0dGWuxcPTTntAF6bOP0Sp4x0PjSF+4uHQ1xvxfRKqg==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.17.19': + resolution: {integrity: sha512-cdmT3KxjlOQ/gZ2cjfrQOtmhG4HJs6hhvm3mWSRDPtZ/lP5oe8FWceS10JaSJC13GBd4eH/haHnqf7hhGNLerA==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.17.19': + resolution: {integrity: sha512-w4IRhSy1VbsNxHRQpeGCHEmibqdTUx61Vc38APcsRbuVgK0OPEnQ0YD39Brymn96mOx48Y2laBQGqgZ0j9w6SQ==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.17.19': + resolution: {integrity: sha512-2iAngUbBPMq439a+z//gE+9WBldoMp1s5GWsUSgqHLzLJ9WoZLZhpwWuym0u0u/4XmZ3gpHmzV84PonE+9IIdQ==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.17.19': + resolution: {integrity: sha512-LKJltc4LVdMKHsrFe4MGNPp0hqDFA1Wpt3jE1gEyM3nKUvOiO//9PheZZHfYRfYl6AwdTH4aTcXSqBerX0ml4A==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.17.19': + resolution: {integrity: sha512-/c/DGybs95WXNS8y3Ti/ytqETiW7EU44MEKuCAcpPto3YjQbyK3IQVKfF6nbghD7EcLUGl0NbiL5Rt5DMhn5tg==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.17.19': + resolution: {integrity: sha512-FC3nUAWhvFoutlhAkgHf8f5HwFWUL6bYdvLc/TTuxKlvLi3+pPzdZiFKSWz/PF30TB1K19SuCxDTI5KcqASJqA==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.17.19': + resolution: {integrity: sha512-IbFsFbxMWLuKEbH+7sTkKzL6NJmG2vRyy6K7JJo55w+8xDk7RElYn6xvXtDW8HCfoKBFK69f3pgBJSUSQPr+4Q==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.17.19': + resolution: {integrity: sha512-68ngA9lg2H6zkZcyp22tsVt38mlhWde8l3eJLWkyLrp4HwMUr3c1s/M2t7+kHIhvMjglIBrFpncX1SzMckomGw==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-x64@0.17.19': + resolution: {integrity: sha512-CwFq42rXCR8TYIjIfpXCbRX0rp1jo6cPIUPSaWwzbVI4aOfX96OXY8M6KNmtPcg7QjYeDmN+DD0Wp3LaBOLf4Q==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-x64@0.17.19': + resolution: {integrity: sha512-cnq5brJYrSZ2CF6c35eCmviIN3k3RczmHz8eYaVlNasVqsNY+JKohZU5MKmaOI+KkllCdzOKKdPs762VCPC20g==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + + '@esbuild/sunos-x64@0.17.19': + resolution: {integrity: sha512-vCRT7yP3zX+bKWFeP/zdS6SqdWB8OIpaRq/mbXQxTGHnIxspRtigpkUcDMlSCOejlHowLqII7K2JKevwyRP2rg==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.17.19': + resolution: {integrity: sha512-yYx+8jwowUstVdorcMdNlzklLYhPxjniHWFKgRqH7IFlUEa0Umu3KuYplf1HUZZ422e3NU9F4LGb+4O0Kdcaag==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.17.19': + resolution: {integrity: sha512-eggDKanJszUtCdlVs0RB+h35wNlb5v4TWEkq4vZcmVt5u/HiDZrTXe2bWFQUez3RgNHwx/x4sk5++4NSSicKkw==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.17.19': + resolution: {integrity: sha512-lAhycmKnVOuRYNtRtatQR1LPQf2oYCkRGkSFnseDAKPl8lu5SOsK/e1sXe5a0Pc5kHIHe6P2I/ilntNv2xf3cA==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + + '@fastify/busboy@2.1.1': + resolution: {integrity: sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==} + engines: {node: '>=14'} + + '@img/sharp-darwin-arm64@0.33.5': + resolution: {integrity: sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [darwin] + + '@img/sharp-darwin-x64@0.33.5': + resolution: {integrity: sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [darwin] + + '@img/sharp-libvips-darwin-arm64@1.0.4': + resolution: {integrity: sha512-XblONe153h0O2zuFfTAbQYAX2JhYmDHeWikp1LM9Hul9gVPjFY427k6dFEcOL72O01QxQsWi761svJ/ev9xEDg==} + cpu: [arm64] + os: [darwin] + + '@img/sharp-libvips-darwin-x64@1.0.4': + resolution: {integrity: sha512-xnGR8YuZYfJGmWPvmlunFaWJsb9T/AO2ykoP3Fz/0X5XV2aoYBPkX6xqCQvUTKKiLddarLaxpzNe+b1hjeWHAQ==} + cpu: [x64] + os: [darwin] + + '@img/sharp-libvips-linux-arm64@1.0.4': + resolution: {integrity: sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA==} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linux-arm@1.0.5': + resolution: {integrity: sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g==} + cpu: [arm] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linux-s390x@1.0.4': + resolution: {integrity: sha512-u7Wz6ntiSSgGSGcjZ55im6uvTrOxSIS8/dgoVMoiGE9I6JAfU50yH5BoDlYA1tcuGS7g/QNtetJnxA6QEsCVTA==} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linux-x64@1.0.4': + resolution: {integrity: sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw==} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linuxmusl-arm64@1.0.4': + resolution: {integrity: sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA==} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@img/sharp-libvips-linuxmusl-x64@1.0.4': + resolution: {integrity: sha512-viYN1KX9m+/hGkJtvYYp+CCLgnJXwiQB39damAO7WMdKWlIhmYTfHjwSbQeUK/20vY154mwezd9HflVFM1wVSw==} + cpu: [x64] + os: [linux] + libc: [musl] + + '@img/sharp-linux-arm64@0.33.5': + resolution: {integrity: sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@img/sharp-linux-arm@0.33.5': + resolution: {integrity: sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm] + os: [linux] + libc: [glibc] + + '@img/sharp-linux-s390x@0.33.5': + resolution: {integrity: sha512-y/5PCd+mP4CA/sPDKl2961b+C9d+vPAveS33s6Z3zfASk2j5upL6fXVPZi7ztePZ5CuH+1kW8JtvxgbuXHRa4Q==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@img/sharp-linux-x64@0.33.5': + resolution: {integrity: sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@img/sharp-linuxmusl-arm64@0.33.5': + resolution: {integrity: sha512-XrHMZwGQGvJg2V/oRSUfSAfjfPxO+4DkiRh6p2AFjLQztWUuY/o8Mq0eMQVIY7HJ1CDQUJlxGGZRw1a5bqmd1g==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@img/sharp-linuxmusl-x64@0.33.5': + resolution: {integrity: sha512-WT+d/cgqKkkKySYmqoZ8y3pxx7lx9vVejxW/W4DOFMYVSkErR+w7mf2u8m/y4+xHe7yY9DAXQMWQhpnMuFfScw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [linux] + libc: [musl] + + '@img/sharp-wasm32@0.33.5': + resolution: {integrity: sha512-ykUW4LVGaMcU9lu9thv85CbRMAwfeadCJHRsg2GmeRa/cJxsVY9Rbd57JcMxBkKHag5U/x7TSBpScF4U8ElVzg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [wasm32] + + '@img/sharp-win32-ia32@0.33.5': + resolution: {integrity: sha512-T36PblLaTwuVJ/zw/LaH0PdZkRz5rd3SmMHX8GSmR7vtNSP5Z6bQkExdSK7xGWyxLw4sUknBuugTelgw2faBbQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [ia32] + os: [win32] + + '@img/sharp-win32-x64@0.33.5': + resolution: {integrity: sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [win32] + + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/sourcemap-codec@1.6.0': + resolution: {integrity: sha512-T7jf+5zgsZHwNJ4lvQ7/aezbyk0nNX+zJVWpmHA7VYsEx7a7qr5Rg5IbtJFqkgze5Y2sruq1RUY8Q837Od7iFw==} + + '@jridgewell/trace-mapping@0.3.9': + resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} + + acorn-walk@8.3.2: + resolution: {integrity: sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==} + engines: {node: '>=0.4.0'} + + acorn@8.14.0: + resolution: {integrity: sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==} + engines: {node: '>=0.4.0'} + hasBin: true + + as-table@1.0.55: + resolution: {integrity: sha512-xvsWESUJn0JN421Xb9MQw6AsMHRCUknCe0Wjlxvjud80mU4E6hQf1A6NzQKcYNmYw62MfzEtXc+badstZP3JpQ==} + + blake3-wasm@2.1.5: + resolution: {integrity: sha512-F1+K8EbfOZE49dtoPtmxUQrpXaBIl3ICvasLh+nJta0xkz+9kF/7uet9fLnwKqhDrmj6g+6K3Tw9yQPUg2ka5g==} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + color-string@1.9.1: + resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==} + + color@4.2.3: + resolution: {integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==} + engines: {node: '>=12.5.0'} + + cookie@0.7.2: + resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==} + engines: {node: '>= 0.6'} + + data-uri-to-buffer@2.0.2: + resolution: {integrity: sha512-ND9qDTLc6diwj+Xe5cdAgVTbLVdXbtxTJRXRhli8Mowuaan+0EJOtdqJ0QCHNSSPyoXGx9HX2/VMnKeC34AChA==} + + defu@6.1.7: + resolution: {integrity: sha512-7z22QmUWiQ/2d0KkdYmANbRUVABpZ9SNYyH5vx6PZ+nE5bcC0l7uFvEfHlyld/HcGBFTL536ClDt3DEcSlEJAQ==} + + detect-libc@2.1.2: + resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} + engines: {node: '>=8'} + + esbuild@0.17.19: + resolution: {integrity: sha512-XQ0jAPFkK/u3LcVRcvVHQcTIqD6E2H1fvZMA5dQPSOWb3suUbWbfbRf94pjc0bNzRYLfIrDRQXr7X+LHIm5oHw==} + engines: {node: '>=12'} + hasBin: true + + escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + + estree-walker@0.6.1: + resolution: {integrity: sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==} + + exit-hook@2.2.1: + resolution: {integrity: sha512-eNTPlAD67BmP31LDINZ3U7HSF8l57TxOY2PmBJ1shpCvpnxBF93mWCE8YHBnXs8qiUZJc9WDcWIeC3a2HIAMfw==} + engines: {node: '>=6'} + + exsolve@1.1.1: + resolution: {integrity: sha512-9U/jZUgjnSGyntRr6y5Muu1MJcwFl6kPu7k8qLF0IMNfLqvw0NZ4nnVDq0RVoZ0RvCyumib4Ez3KYrVfilrw+g==} + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + get-source@2.0.12: + resolution: {integrity: sha512-X5+4+iD+HoSeEED+uwrQ07BOQr0kEDFMVqqpBuI+RaZBpBpHCuXxo70bjar6f0b0u/DQJsJ7ssurpP0V60Az+w==} + + glob-to-regexp@0.4.1: + resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==} + + is-arrayish@0.3.4: + resolution: {integrity: sha512-m6UrgzFVUYawGBh1dUsWR5M2Clqic9RVXC/9f8ceNlv2IcO9j9J/z8UoCLPqtsPBFNzEpfR3xftohbfqDx8EQA==} + + magic-string@0.25.9: + resolution: {integrity: sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==} + + mime@3.0.0: + resolution: {integrity: sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==} + engines: {node: '>=10.0.0'} + hasBin: true + + miniflare@3.20250718.3: + resolution: {integrity: sha512-JuPrDJhwLrNLEJiNLWO7ZzJrv/Vv9kZuwMYCfv0LskQDM6Eonw4OvywO3CH/wCGjgHzha/qyjUh8JQ068TjDgQ==} + engines: {node: '>=16.13'} + hasBin: true + + mustache@4.2.0: + resolution: {integrity: sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==} + hasBin: true + + ohash@2.0.12: + resolution: {integrity: sha512-65S/5gk9YSsaRjcyf7Nfa6h/d3E8/1gslpXfI4W7Dxn/oap8IKRuNT5VXkLQ1YFKIEg4apRY4Pj6aiwFzrDdmw==} + + path-to-regexp@6.3.0: + resolution: {integrity: sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==} + + pathe@2.0.3: + resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} + + postal-mime@2.7.6: + resolution: {integrity: sha512-UUlyE2KlxmvwMGq060onF/VWU3zD6dVW31FwokQ5v26jWd35fbs2MoTFzh+jXnPwAyV2MULMKXcBInGOl5TO6Q==} + + printable-characters@1.0.42: + resolution: {integrity: sha512-dKp+C4iXWK4vVYZmYSd0KBH5F/h1HoZRsbJ82AVKRO3PEo8L4lBS/vLwhVtpwwuYcoIsVY+1JYKR268yn480uQ==} + + rollup-plugin-inject@3.0.2: + resolution: {integrity: sha512-ptg9PQwzs3orn4jkgXJ74bfs5vYz1NCZlSQMBUA0wKcGp5i5pA1AO3fOUEte8enhGUC+iapTCzEWw2jEFFUO/w==} + deprecated: This package has been deprecated and is no longer maintained. Please use @rollup/plugin-inject. + + rollup-plugin-node-polyfills@0.2.1: + resolution: {integrity: sha512-4kCrKPTJ6sK4/gLL/U5QzVT8cxJcofO0OU74tnB19F40cmuAKSzH5/siithxlofFEjwvw1YAhPmbvGNA6jEroA==} + + rollup-pluginutils@2.8.2: + resolution: {integrity: sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==} + + semver@7.8.5: + resolution: {integrity: sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==} + engines: {node: '>=10'} + hasBin: true + + sharp@0.33.5: + resolution: {integrity: sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + + simple-swizzle@0.2.4: + resolution: {integrity: sha512-nAu1WFPQSMNr2Zn9PGSZK9AGn4t/y97lEm+MXTtUDwfP0ksAIX4nO+6ruD9Jwut4C49SB1Ws+fbXsm/yScWOHw==} + + source-map@0.6.1: + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + engines: {node: '>=0.10.0'} + + sourcemap-codec@1.4.8: + resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==} + deprecated: Please use @jridgewell/sourcemap-codec instead + + stacktracey@2.2.0: + resolution: {integrity: sha512-ETyQEz+CzXiLjEbyJqpbp+/T79RQD/6wqFucRBIlVNZfYq2Ay7wbretD4cxpbymZlaPWx58aIhPEY1Cr8DlVvg==} + + stoppable@1.1.0: + resolution: {integrity: sha512-KXDYZ9dszj6bzvnEMRYvxgeTHU74QBFL54XKtP3nyMuJ81CFYtABZ3bAzL2EdFUaEwJOBOgENyFj3R7oTzDyyw==} + engines: {node: '>=4', npm: '>=6'} + + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + + typescript@6.0.3: + resolution: {integrity: sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==} + engines: {node: '>=14.17'} + hasBin: true + + ufo@1.6.4: + resolution: {integrity: sha512-JFNbkD1Svwe0KvGi8GOeLcP4kAWQ609twvCdcHxq1oSL8svv39ZuSvajcD8B+5D0eL4+s1Is2D/O6KN3qcTeRA==} + + undici@5.29.0: + resolution: {integrity: sha512-raqeBD6NQK4SkWhQzeYKd1KmIG6dllBOTt55Rmkt4HtI9mwdWtJljnrXjAFUBLTSN67HWrOIZ3EPF4kjUw80Bg==} + engines: {node: '>=14.0'} + + unenv@2.0.0-rc.14: + resolution: {integrity: sha512-od496pShMen7nOy5VmVJCnq8rptd45vh6Nx/r2iPbrba6pa6p+tS2ywuIHRZ/OBvSbQZB0kWvpO9XBNVFXHD3Q==} + + workerd@1.20250718.0: + resolution: {integrity: sha512-kqkIJP/eOfDlUyBzU7joBg+tl8aB25gEAGqDap+nFWb+WHhnooxjGHgxPBy3ipw2hnShPFNOQt5lFRxbwALirg==} + engines: {node: '>=16'} + hasBin: true + + wrangler@3.114.17: + resolution: {integrity: sha512-tAvf7ly+tB+zwwrmjsCyJ2pJnnc7SZhbnNwXbH+OIdVas3zTSmjcZOjmLKcGGptssAA3RyTKhcF9BvKZzMUycA==} + engines: {node: '>=16.17.0'} + hasBin: true + peerDependencies: + '@cloudflare/workers-types': ^4.20250408.0 + peerDependenciesMeta: + '@cloudflare/workers-types': + optional: true + + ws@8.18.0: + resolution: {integrity: sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + youch@3.3.4: + resolution: {integrity: sha512-UeVBXie8cA35DS6+nBkls68xaBBXCye0CNznrhszZjTbRVnJKQuNsyLKBTTL4ln1o1rh2PKtv35twV7irj5SEg==} + + zod@3.22.3: + resolution: {integrity: sha512-EjIevzuJRiRPbVH4mGc8nApb/lVLKVpmUhAaR5R5doKGfAnGJ6Gr3CViAVjP+4FWSxCsybeWQdcgCtbX+7oZug==} + +snapshots: + + '@cloudflare/kv-asset-handler@0.3.4': + dependencies: + mime: 3.0.0 + + '@cloudflare/unenv-preset@2.0.2(unenv@2.0.0-rc.14)(workerd@1.20250718.0)': + dependencies: + unenv: 2.0.0-rc.14 + optionalDependencies: + workerd: 1.20250718.0 + + '@cloudflare/workerd-darwin-64@1.20250718.0': + optional: true + + '@cloudflare/workerd-darwin-arm64@1.20250718.0': + optional: true + + '@cloudflare/workerd-linux-64@1.20250718.0': + optional: true + + '@cloudflare/workerd-linux-arm64@1.20250718.0': + optional: true + + '@cloudflare/workerd-windows-64@1.20250718.0': + optional: true + + '@cloudflare/workers-types@4.20260702.1': {} + + '@cspotcode/source-map-support@0.8.1': + dependencies: + '@jridgewell/trace-mapping': 0.3.9 + + '@emnapi/runtime@1.11.3': + dependencies: + tslib: 2.8.1 + optional: true + + '@esbuild-plugins/node-globals-polyfill@0.2.3(esbuild@0.17.19)': + dependencies: + esbuild: 0.17.19 + + '@esbuild-plugins/node-modules-polyfill@0.2.2(esbuild@0.17.19)': + dependencies: + esbuild: 0.17.19 + escape-string-regexp: 4.0.0 + rollup-plugin-node-polyfills: 0.2.1 + + '@esbuild/android-arm64@0.17.19': + optional: true + + '@esbuild/android-arm@0.17.19': + optional: true + + '@esbuild/android-x64@0.17.19': + optional: true + + '@esbuild/darwin-arm64@0.17.19': + optional: true + + '@esbuild/darwin-x64@0.17.19': + optional: true + + '@esbuild/freebsd-arm64@0.17.19': + optional: true + + '@esbuild/freebsd-x64@0.17.19': + optional: true + + '@esbuild/linux-arm64@0.17.19': + optional: true + + '@esbuild/linux-arm@0.17.19': + optional: true + + '@esbuild/linux-ia32@0.17.19': + optional: true + + '@esbuild/linux-loong64@0.17.19': + optional: true + + '@esbuild/linux-mips64el@0.17.19': + optional: true + + '@esbuild/linux-ppc64@0.17.19': + optional: true + + '@esbuild/linux-riscv64@0.17.19': + optional: true + + '@esbuild/linux-s390x@0.17.19': + optional: true + + '@esbuild/linux-x64@0.17.19': + optional: true + + '@esbuild/netbsd-x64@0.17.19': + optional: true + + '@esbuild/openbsd-x64@0.17.19': + optional: true + + '@esbuild/sunos-x64@0.17.19': + optional: true + + '@esbuild/win32-arm64@0.17.19': + optional: true + + '@esbuild/win32-ia32@0.17.19': + optional: true + + '@esbuild/win32-x64@0.17.19': + optional: true + + '@fastify/busboy@2.1.1': {} + + '@img/sharp-darwin-arm64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-darwin-arm64': 1.0.4 + optional: true + + '@img/sharp-darwin-x64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-darwin-x64': 1.0.4 + optional: true + + '@img/sharp-libvips-darwin-arm64@1.0.4': + optional: true + + '@img/sharp-libvips-darwin-x64@1.0.4': + optional: true + + '@img/sharp-libvips-linux-arm64@1.0.4': + optional: true + + '@img/sharp-libvips-linux-arm@1.0.5': + optional: true + + '@img/sharp-libvips-linux-s390x@1.0.4': + optional: true + + '@img/sharp-libvips-linux-x64@1.0.4': + optional: true + + '@img/sharp-libvips-linuxmusl-arm64@1.0.4': + optional: true + + '@img/sharp-libvips-linuxmusl-x64@1.0.4': + optional: true + + '@img/sharp-linux-arm64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linux-arm64': 1.0.4 + optional: true + + '@img/sharp-linux-arm@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linux-arm': 1.0.5 + optional: true + + '@img/sharp-linux-s390x@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linux-s390x': 1.0.4 + optional: true + + '@img/sharp-linux-x64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linux-x64': 1.0.4 + optional: true + + '@img/sharp-linuxmusl-arm64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-arm64': 1.0.4 + optional: true + + '@img/sharp-linuxmusl-x64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-x64': 1.0.4 + optional: true + + '@img/sharp-wasm32@0.33.5': + dependencies: + '@emnapi/runtime': 1.11.3 + optional: true + + '@img/sharp-win32-ia32@0.33.5': + optional: true + + '@img/sharp-win32-x64@0.33.5': + optional: true + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/sourcemap-codec@1.6.0': {} + + '@jridgewell/trace-mapping@0.3.9': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.6.0 + + acorn-walk@8.3.2: {} + + acorn@8.14.0: {} + + as-table@1.0.55: + dependencies: + printable-characters: 1.0.42 + + blake3-wasm@2.1.5: {} + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + optional: true + + color-name@1.1.4: + optional: true + + color-string@1.9.1: + dependencies: + color-name: 1.1.4 + simple-swizzle: 0.2.4 + optional: true + + color@4.2.3: + dependencies: + color-convert: 2.0.1 + color-string: 1.9.1 + optional: true + + cookie@0.7.2: {} + + data-uri-to-buffer@2.0.2: {} + + defu@6.1.7: {} + + detect-libc@2.1.2: + optional: true + + esbuild@0.17.19: + optionalDependencies: + '@esbuild/android-arm': 0.17.19 + '@esbuild/android-arm64': 0.17.19 + '@esbuild/android-x64': 0.17.19 + '@esbuild/darwin-arm64': 0.17.19 + '@esbuild/darwin-x64': 0.17.19 + '@esbuild/freebsd-arm64': 0.17.19 + '@esbuild/freebsd-x64': 0.17.19 + '@esbuild/linux-arm': 0.17.19 + '@esbuild/linux-arm64': 0.17.19 + '@esbuild/linux-ia32': 0.17.19 + '@esbuild/linux-loong64': 0.17.19 + '@esbuild/linux-mips64el': 0.17.19 + '@esbuild/linux-ppc64': 0.17.19 + '@esbuild/linux-riscv64': 0.17.19 + '@esbuild/linux-s390x': 0.17.19 + '@esbuild/linux-x64': 0.17.19 + '@esbuild/netbsd-x64': 0.17.19 + '@esbuild/openbsd-x64': 0.17.19 + '@esbuild/sunos-x64': 0.17.19 + '@esbuild/win32-arm64': 0.17.19 + '@esbuild/win32-ia32': 0.17.19 + '@esbuild/win32-x64': 0.17.19 + + escape-string-regexp@4.0.0: {} + + estree-walker@0.6.1: {} + + exit-hook@2.2.1: {} + + exsolve@1.1.1: {} + + fsevents@2.3.3: + optional: true + + get-source@2.0.12: + dependencies: + data-uri-to-buffer: 2.0.2 + source-map: 0.6.1 + + glob-to-regexp@0.4.1: {} + + is-arrayish@0.3.4: + optional: true + + magic-string@0.25.9: + dependencies: + sourcemap-codec: 1.4.8 + + mime@3.0.0: {} + + miniflare@3.20250718.3: + dependencies: + '@cspotcode/source-map-support': 0.8.1 + acorn: 8.14.0 + acorn-walk: 8.3.2 + exit-hook: 2.2.1 + glob-to-regexp: 0.4.1 + stoppable: 1.1.0 + undici: 5.29.0 + workerd: 1.20250718.0 + ws: 8.18.0 + youch: 3.3.4 + zod: 3.22.3 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + mustache@4.2.0: {} + + ohash@2.0.12: {} + + path-to-regexp@6.3.0: {} + + pathe@2.0.3: {} + + postal-mime@2.7.6: {} + + printable-characters@1.0.42: {} + + rollup-plugin-inject@3.0.2: + dependencies: + estree-walker: 0.6.1 + magic-string: 0.25.9 + rollup-pluginutils: 2.8.2 + + rollup-plugin-node-polyfills@0.2.1: + dependencies: + rollup-plugin-inject: 3.0.2 + + rollup-pluginutils@2.8.2: + dependencies: + estree-walker: 0.6.1 + + semver@7.8.5: + optional: true + + sharp@0.33.5: + dependencies: + color: 4.2.3 + detect-libc: 2.1.2 + semver: 7.8.5 + optionalDependencies: + '@img/sharp-darwin-arm64': 0.33.5 + '@img/sharp-darwin-x64': 0.33.5 + '@img/sharp-libvips-darwin-arm64': 1.0.4 + '@img/sharp-libvips-darwin-x64': 1.0.4 + '@img/sharp-libvips-linux-arm': 1.0.5 + '@img/sharp-libvips-linux-arm64': 1.0.4 + '@img/sharp-libvips-linux-s390x': 1.0.4 + '@img/sharp-libvips-linux-x64': 1.0.4 + '@img/sharp-libvips-linuxmusl-arm64': 1.0.4 + '@img/sharp-libvips-linuxmusl-x64': 1.0.4 + '@img/sharp-linux-arm': 0.33.5 + '@img/sharp-linux-arm64': 0.33.5 + '@img/sharp-linux-s390x': 0.33.5 + '@img/sharp-linux-x64': 0.33.5 + '@img/sharp-linuxmusl-arm64': 0.33.5 + '@img/sharp-linuxmusl-x64': 0.33.5 + '@img/sharp-wasm32': 0.33.5 + '@img/sharp-win32-ia32': 0.33.5 + '@img/sharp-win32-x64': 0.33.5 + optional: true + + simple-swizzle@0.2.4: + dependencies: + is-arrayish: 0.3.4 + optional: true + + source-map@0.6.1: {} + + sourcemap-codec@1.4.8: {} + + stacktracey@2.2.0: + dependencies: + as-table: 1.0.55 + get-source: 2.0.12 + + stoppable@1.1.0: {} + + tslib@2.8.1: + optional: true + + typescript@6.0.3: {} + + ufo@1.6.4: {} + + undici@5.29.0: + dependencies: + '@fastify/busboy': 2.1.1 + + unenv@2.0.0-rc.14: + dependencies: + defu: 6.1.7 + exsolve: 1.1.1 + ohash: 2.0.12 + pathe: 2.0.3 + ufo: 1.6.4 + + workerd@1.20250718.0: + optionalDependencies: + '@cloudflare/workerd-darwin-64': 1.20250718.0 + '@cloudflare/workerd-darwin-arm64': 1.20250718.0 + '@cloudflare/workerd-linux-64': 1.20250718.0 + '@cloudflare/workerd-linux-arm64': 1.20250718.0 + '@cloudflare/workerd-windows-64': 1.20250718.0 + + wrangler@3.114.17(@cloudflare/workers-types@4.20260702.1): + dependencies: + '@cloudflare/kv-asset-handler': 0.3.4 + '@cloudflare/unenv-preset': 2.0.2(unenv@2.0.0-rc.14)(workerd@1.20250718.0) + '@esbuild-plugins/node-globals-polyfill': 0.2.3(esbuild@0.17.19) + '@esbuild-plugins/node-modules-polyfill': 0.2.2(esbuild@0.17.19) + blake3-wasm: 2.1.5 + esbuild: 0.17.19 + miniflare: 3.20250718.3 + path-to-regexp: 6.3.0 + unenv: 2.0.0-rc.14 + workerd: 1.20250718.0 + optionalDependencies: + '@cloudflare/workers-types': 4.20260702.1 + fsevents: 2.3.3 + sharp: 0.33.5 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + ws@8.18.0: {} + + youch@3.3.4: + dependencies: + cookie: 0.7.2 + mustache: 4.2.0 + stacktracey: 2.2.0 + + zod@3.22.3: {} diff --git a/scripts/cloudflare-email-worker/src/index.ts b/scripts/cloudflare-email-worker/src/index.ts new file mode 100644 index 0000000..9814233 --- /dev/null +++ b/scripts/cloudflare-email-worker/src/index.ts @@ -0,0 +1,58 @@ +import PostalMime from 'postal-mime'; + +export interface Env { + DESK_WEBHOOK_URL: string; + DESK_WEBHOOK_SECRET: string; +} + +export default { + async email(message: ForwardableEmailMessage, env: Env, ctx: ExecutionContext): Promise { + try { + const rawEmail = await new Response(message.raw).arrayBuffer(); + const parser = new PostalMime(); + const parsed = await parser.parse(rawEmail); + + const fromEmail = message.from || parsed.from?.address || ''; + const fromName = parsed.from?.name || ''; + const toEmail = message.to || (parsed.to && parsed.to[0]?.address) || ''; + const toName = (parsed.to && parsed.to[0]?.name) || ''; + const subject = message.headers.get('subject') || parsed.subject || ''; + const messageId = message.headers.get('message-id') || parsed.messageId || ''; + const inReplyTo = message.headers.get('in-reply-to') || parsed.inReplyTo || ''; + const references = message.headers.get('references') || (Array.isArray(parsed.references) ? parsed.references.join(' ') : parsed.references) || ''; + + const payload = { + from: fromEmail, + from_name: fromName, + to: toEmail, + to_name: toName, + subject: subject, + text: parsed.text || '', + html: parsed.html || '', + message_id: messageId, + in_reply_to: inReplyTo, + references: references, + }; + + const webhookUrl = env.DESK_WEBHOOK_URL || ''; + const webhookSecret = env.DESK_WEBHOOK_SECRET || ''; + + const response = await fetch(webhookUrl, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'X-Webhook-Secret': webhookSecret, + }, + body: JSON.stringify(payload), + }); + + if (!response.ok) { + console.error(`Failed to forward email to webhook: ${response.status} ${response.statusText}`); + } else { + console.log(`Successfully forwarded email from ${fromEmail} to Agent Desk`); + } + } catch (error) { + console.error('Error processing inbound email in worker:', error); + } + }, +}; diff --git a/scripts/cloudflare-email-worker/wrangler.toml b/scripts/cloudflare-email-worker/wrangler.toml new file mode 100644 index 0000000..1c041e0 --- /dev/null +++ b/scripts/cloudflare-email-worker/wrangler.toml @@ -0,0 +1,8 @@ +name = "agent-desk-email-inbound-worker" +main = "src/index.ts" +compatibility_date = "2024-11-05" +account_id = "5f2a58925e790423dfafa0e6bee46b28" + +[vars] +DESK_WEBHOOK_URL = "https://your-desk.example.com/api/third/email/webhook" +DESK_WEBHOOK_SECRET = "replace-with-your-email-inbound-secret" diff --git a/scripts/i18n_untranslated.py b/scripts/i18n_untranslated.py new file mode 100644 index 0000000..cf3ba55 --- /dev/null +++ b/scripts/i18n_untranslated.py @@ -0,0 +1,169 @@ +#!/usr/bin/env python3 +"""Report i18n values that still hold the source language instead of a translation. + +Key parity is already enforced by the test suite +(web/i18n/message-integrity.test.mjs and +internal/pkg/i18nx/locale_parity_test.go), so this exists for the gap those +tests cannot see: a key can be present in every locale and still carry the +Chinese string, which is how Chinese kept showing up in an otherwise translated +UI. + +Usage: + python scripts/i18n_untranslated.py + + is the source language, the one being audited. Values in +containing CJK are listed. Those byte-identical to are reported as +untranslated; the rest are left to judgement, since product names and sample +data legitimately keep CJK. + +Exit code: 0 when the child has no untranslated values, 1 when it does, +2 on usage errors. +""" + +from __future__ import annotations + +import json +import re +import sys +from pathlib import Path +from typing import Any + +# Hangul and Kana are deliberately excluded: this looks for Chinese script, +# which is what leaked into the UI, not for non-ASCII text in general. +CJK = re.compile(r"[\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff]") + +USAGE = "Usage: python scripts/i18n_untranslated.py \n" + + +def flatten_json(value: Any, prefix: str = "", out: dict[str, Any] | None = None) -> dict[str, Any]: + if out is None: + out = {} + if isinstance(value, dict): + for key, child in value.items(): + flatten_json(child, f"{prefix}.{key}" if prefix else str(key), out) + return out + out[prefix] = value + return out + + +def _indent_of(line: str) -> int: + return len(line) - len(line.lstrip()) + + +def parse_flat_yaml(text: str) -> dict[str, Any]: + """Parse the locale YAML dialect: flat top-level keys, one nested level, block scalars.""" + lines = text.splitlines() + out: dict[str, Any] = {} + index = 0 + + while index < len(lines): + raw = lines[index] + index += 1 + + if not raw.strip() or raw.lstrip().startswith("#"): + continue + + indent = _indent_of(raw) + if indent != 0: + continue + + head = raw.strip() + if ":" not in head: + continue + key, _, rest = head.partition(":") + key = key.strip().strip("\"'") + value = rest.strip() + + if value in ("|", ">", "|-", ">-", "|+", ">+"): + block: list[str] = [] + block_indent: int | None = None + while index < len(lines): + line = lines[index] + if line.strip() and _indent_of(line) <= indent: + break + line_indent = _indent_of(line) + block_indent = line_indent if block_indent is None else block_indent + block.append(line[min(block_indent, line_indent):]) + index += 1 + out[key] = "\n".join(block).strip() + elif not value: + # A key with no inline value opens one nested level. + while index < len(lines): + line = lines[index] + if line.strip() and _indent_of(line) <= indent: + break + stripped = line.strip() + index += 1 + if ":" in stripped: + nested_key, _, nested_value = stripped.partition(":") + out[f"{key}.{nested_key.strip()}"] = nested_value.strip().strip("\"'") + continue + else: + out[key] = value.strip().strip("\"'") + + return out + + +def load_values(file: str) -> dict[str, Any]: + suffix = Path(file).suffix.lower() + # utf-8-sig tolerates a BOM and a plain utf-8 file equally; a BOM is common + # in locale files authored on Windows and would otherwise abort the run. + text = Path(file).read_text(encoding="utf-8-sig") + if suffix == ".json": + return flatten_json(json.loads(text)) + if suffix in (".yml", ".yaml"): + return parse_flat_yaml(text) + raise ValueError(f"Unsupported file format: {file}") + + +def main(argv: list[str]) -> int: + args = [arg for arg in argv if not arg.startswith("-")] + if len(args) != 2: + sys.stderr.write(USAGE) + return 2 + + base_file, child_file = args + try: + base = load_values(base_file) + child = load_values(child_file) + except (OSError, ValueError, json.JSONDecodeError) as error: + sys.stderr.write(f"Failed to read bundle: {error}\n") + return 2 + + untranslated: list[tuple[str, str]] = [] + review: list[tuple[str, str]] = [] + for key, value in child.items(): + if not isinstance(value, str) or not CJK.search(value): + continue + base_value = base.get(key) + if isinstance(base_value, str) and base_value.strip() == value.strip(): + untranslated.append((key, value)) + else: + review.append((key, value)) + + print( + f"child {child_file}: {len(child)} values, " + f"{len(untranslated) + len(review)} with CJK " + f"({len(untranslated)} untranslated, {len(review)} to review)" + ) + + if untranslated: + print(f"\nuntranslated, identical to base ({len(untranslated)}):") + for key, value in untranslated: + print(f" - {key} = {value}") + + if review: + print(f"\nCJK but differs from base ({len(review)}):") + for key, value in review: + print(f" ? {key} = {value}") + + if not untranslated and not review: + print("OK: no CJK left in child values") + return 0 + return 1 + + +if __name__ == "__main__": + # Do not litter the repo with __pycache__ when this is run from tooling. + sys.dont_write_bytecode = True + raise SystemExit(main(sys.argv[1:])) \ No newline at end of file diff --git a/web/.env.example b/web/.env.example new file mode 100644 index 0000000..1464741 --- /dev/null +++ b/web/.env.example @@ -0,0 +1 @@ +NEXT_PUBLIC_API_BASE_URL=http://localhost:8083 \ No newline at end of file diff --git a/web/.gitignore b/web/.gitignore new file mode 100644 index 0000000..7b8da95 --- /dev/null +++ b/web/.gitignore @@ -0,0 +1,42 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.* +.yarn/* +!.yarn/patches +!.yarn/plugins +!.yarn/releases +!.yarn/versions + +# testing +/coverage + +# next.js +/.next/ +/out/ + +# production +/build + +# misc +.DS_Store +*.pem + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* +.pnpm-debug.log* + +# env files (can opt-in for committing if needed) +.env* +!.env.example + +# vercel +.vercel + +# typescript +*.tsbuildinfo +next-env.d.ts diff --git a/web/README.md b/web/README.md new file mode 100644 index 0000000..c6f6f47 --- /dev/null +++ b/web/README.md @@ -0,0 +1,36 @@ +This is a [Next.js](https://nextjs.org) project bootstrapped with [`create-next-app`](https://nextjs.org/docs/app/api-reference/cli/create-next-app). + +## Getting Started + +First, run the development server: + +```bash +npm run dev +# or +yarn dev +# or +pnpm dev +# or +bun dev +``` + +Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. + +You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file. + +This project uses [`next/font`](https://nextjs.org/docs/app/building-your-application/optimizing/fonts) to self-host [Inter](https://rsms.me/inter/) for UI text and [IBM Plex Mono](https://www.ibm.com/plex/mono/) for monospace text, both declared once in `lib/fonts.ts` and wired into the design tokens through `--font-app-sans` / `--font-app-mono`. Latin and Cyrillic subsets are included so the `zh-CN`, `en-US`, and `ru-RU` locales all render from the same font files. + +## Learn More + +To learn more about Next.js, take a look at the following resources: + +- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API. +- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial. + +You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js) - your feedback and contributions are welcome! + +## Deploy on Vercel + +The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js. + +Check out our [Next.js deployment documentation](https://nextjs.org/docs/app/building-your-application/deploying) for more details. diff --git a/web/app/(dashboard)/dashboard.css b/web/app/(dashboard)/dashboard.css new file mode 100644 index 0000000..f63b522 --- /dev/null +++ b/web/app/(dashboard)/dashboard.css @@ -0,0 +1,368 @@ +@import "tailwindcss"; +@import "tw-animate-css"; +@import "shadcn/tailwind.css"; + +@custom-variant dark (&:is(.dark *)); + +@theme inline { + --color-background: var(--background); + --color-foreground: var(--foreground); + --font-sans: var(--font-app-sans), -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif; + --font-mono: var(--font-app-mono), ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace; + --color-sidebar-ring: var(--sidebar-ring); + --color-sidebar-border: var(--sidebar-border); + --color-sidebar-accent-foreground: var(--sidebar-accent-foreground); + --color-sidebar-accent: var(--sidebar-accent); + --color-sidebar-primary-foreground: var(--sidebar-primary-foreground); + --color-sidebar-primary: var(--sidebar-primary); + --color-sidebar-foreground: var(--sidebar-foreground); + --color-sidebar: var(--sidebar); + --color-chart-5: var(--chart-5); + --color-chart-4: var(--chart-4); + --color-chart-3: var(--chart-3); + --color-chart-2: var(--chart-2); + --color-chart-1: var(--chart-1); + --color-ring: var(--ring); + --color-input: var(--input); + --color-border: var(--border); + --color-destructive: var(--destructive); + --color-accent-foreground: var(--accent-foreground); + --color-accent: var(--accent); + --color-muted-foreground: var(--muted-foreground); + --color-muted: var(--muted); + --color-secondary-foreground: var(--secondary-foreground); + --color-secondary: var(--secondary); + --color-primary-foreground: var(--primary-foreground); + --color-primary: var(--primary); + --color-popover-foreground: var(--popover-foreground); + --color-popover: var(--popover); + --color-card-foreground: var(--card-foreground); + --color-card: var(--card); + --radius-sm: calc(var(--radius) - 4px); + --radius-md: calc(var(--radius) - 2px); + --radius-lg: var(--radius); + --radius-xl: calc(var(--radius) + 4px); + --radius-2xl: calc(var(--radius) + 8px); + --radius-3xl: calc(var(--radius) + 12px); + --radius-4xl: calc(var(--radius) + 16px); +} + +:root, +:root[data-palette="plain"] { + --radius: 0.5rem; + --background: #f9f9f9; + --foreground: #151923; + --card: #ffffff; + --card-foreground: #151923; + --popover: #ffffff; + --popover-foreground: #151923; + --primary: #2475fc; + --primary-foreground: #ffffff; + --secondary: #e6efff; + --secondary-foreground: #155be8; + --muted: #f4f7fc; + --muted-foreground: #667085; + --accent: #e6efff; + --accent-foreground: #155be8; + --destructive: oklch(0.59 0.225 25); + --border: #dfe7f3; + --input: #dfe7f3; + --ring: #2475fc; + --chart-1: #2475fc; + --chart-2: #14b8a6; + --chart-3: #f59e0b; + --chart-4: #ec4899; + --chart-5: #8b5cf6; + --sidebar: #ffffff; + --sidebar-foreground: #273142; + --sidebar-primary: #2475fc; + --sidebar-primary-foreground: #ffffff; + --sidebar-accent: #e6efff; + --sidebar-accent-foreground: #155be8; + --sidebar-border: #dfe7f3; + --sidebar-ring: #2475fc; +} + +.dark[data-palette="plain"] { + --background: #111827; + --foreground: #f9fafb; + --card: #182235; + --card-foreground: #f9fafb; + --popover: #182235; + --popover-foreground: #f9fafb; + --primary: #6da2ff; + --primary-foreground: #0f172a; + --secondary: #1f3354; + --secondary-foreground: #dbe8ff; + --muted: #1f2937; + --muted-foreground: #9ca3af; + --accent: #1f3354; + --accent-foreground: #dbe8ff; + --destructive: oklch(0.68 0.19 25); + --border: oklch(1 0 0 / 10%); + --input: oklch(1 0 0 / 14%); + --ring: #6da2ff; + --chart-1: #6da2ff; + --chart-2: #2dd4bf; + --chart-3: #fbbf24; + --chart-4: #f472b6; + --chart-5: #a78bfa; + --sidebar: #111827; + --sidebar-foreground: #f3f4f6; + --sidebar-primary: #6da2ff; + --sidebar-primary-foreground: #0f172a; + --sidebar-accent: #1f3354; + --sidebar-accent-foreground: #dbe8ff; + --sidebar-border: oklch(1 0 0 / 9%); + --sidebar-ring: #6da2ff; +} + +:root[data-palette="green"] { + --background: oklch(0.973 0.011 112); + --foreground: oklch(0.22 0.021 210); + --card: oklch(0.996 0.004 105); + --card-foreground: oklch(0.22 0.021 210); + --popover: oklch(0.996 0.004 105); + --popover-foreground: oklch(0.22 0.021 210); + --primary: oklch(0.475 0.118 178); + --primary-foreground: oklch(0.985 0.012 170); + --secondary: oklch(0.94 0.018 124); + --secondary-foreground: oklch(0.255 0.035 178); + --muted: oklch(0.942 0.012 115); + --muted-foreground: oklch(0.49 0.026 205); + --accent: oklch(0.91 0.028 169); + --accent-foreground: oklch(0.245 0.045 178); + --destructive: oklch(0.59 0.225 25); + --border: oklch(0.872 0.018 116); + --input: oklch(0.872 0.018 116); + --ring: oklch(0.56 0.115 178); + --chart-1: oklch(0.52 0.13 178); + --chart-2: oklch(0.61 0.14 220); + --chart-3: oklch(0.72 0.15 78); + --chart-4: oklch(0.62 0.15 330); + --chart-5: oklch(0.58 0.12 262); + --sidebar: oklch(0.925 0.018 118); + --sidebar-foreground: oklch(0.245 0.03 190); + --sidebar-primary: oklch(0.475 0.118 178); + --sidebar-primary-foreground: oklch(0.985 0.012 170); + --sidebar-accent: oklch(0.89 0.032 156); + --sidebar-accent-foreground: oklch(0.235 0.048 178); + --sidebar-border: oklch(0.835 0.022 118); + --sidebar-ring: oklch(0.56 0.115 178); +} + +:root[data-palette="blue"] { + --background: oklch(0.982 0.007 250); + --foreground: oklch(0.205 0.018 255); + --card: oklch(0.998 0.002 250); + --card-foreground: oklch(0.205 0.018 255); + --popover: oklch(0.998 0.002 250); + --popover-foreground: oklch(0.205 0.018 255); + --primary: oklch(0.548 0.19 257); + --primary-foreground: oklch(0.985 0.006 248); + --secondary: oklch(0.948 0.013 250); + --secondary-foreground: oklch(0.245 0.02 252); + --muted: oklch(0.95 0.01 250); + --muted-foreground: oklch(0.49 0.024 245); + --accent: oklch(0.922 0.026 255); + --accent-foreground: oklch(0.255 0.044 254); + --destructive: oklch(0.59 0.225 25); + --border: oklch(0.888 0.014 250); + --input: oklch(0.888 0.014 250); + --ring: oklch(0.61 0.15 252); + --chart-1: oklch(0.59 0.18 255); + --chart-2: oklch(0.62 0.13 178); + --chart-3: oklch(0.72 0.16 82); + --chart-4: oklch(0.61 0.17 333); + --chart-5: oklch(0.56 0.13 285); + --sidebar: oklch(0.94 0.016 250); + --sidebar-foreground: oklch(0.245 0.024 252); + --sidebar-primary: oklch(0.548 0.19 257); + --sidebar-primary-foreground: oklch(0.985 0.006 248); + --sidebar-accent: oklch(0.908 0.025 252); + --sidebar-accent-foreground: oklch(0.245 0.038 254); + --sidebar-border: oklch(0.858 0.018 250); + --sidebar-ring: oklch(0.61 0.15 252); +} + +:root[data-palette="gray"] { + --background: oklch(0.974 0.006 170); + --foreground: oklch(0.205 0.018 255); + --card: oklch(0.998 0.001 106); + --card-foreground: oklch(0.205 0.018 255); + --popover: oklch(0.998 0.001 106); + --popover-foreground: oklch(0.205 0.018 255); + --primary: oklch(0.538 0.183 257); + --primary-foreground: oklch(0.985 0.006 248); + --secondary: oklch(0.944 0.011 175); + --secondary-foreground: oklch(0.245 0.018 250); + --muted: oklch(0.948 0.008 180); + --muted-foreground: oklch(0.49 0.024 245); + --accent: oklch(0.925 0.018 218); + --accent-foreground: oklch(0.255 0.033 250); + --destructive: oklch(0.59 0.225 25); + --border: oklch(0.886 0.012 178); + --input: oklch(0.886 0.012 178); + --ring: oklch(0.61 0.15 252); + --chart-1: oklch(0.59 0.18 255); + --chart-2: oklch(0.62 0.13 178); + --chart-3: oklch(0.72 0.16 82); + --chart-4: oklch(0.61 0.17 333); + --chart-5: oklch(0.56 0.13 285); + --sidebar: oklch(0.94 0.011 170); + --sidebar-foreground: oklch(0.255 0.022 250); + --sidebar-primary: oklch(0.538 0.183 257); + --sidebar-primary-foreground: oklch(0.985 0.006 248); + --sidebar-accent: oklch(0.904 0.017 190); + --sidebar-accent-foreground: oklch(0.245 0.028 250); + --sidebar-border: oklch(0.86 0.014 176); + --sidebar-ring: oklch(0.61 0.15 252); +} + +.dark { + --background: oklch(0.18 0 0); + --foreground: oklch(0.94 0 0); + --card: oklch(0.225 0 0); + --card-foreground: oklch(0.94 0 0); + --popover: oklch(0.225 0 0); + --popover-foreground: oklch(0.94 0 0); + --primary: oklch(0.82 0 0); + --primary-foreground: oklch(0.18 0 0); + --secondary: oklch(0.285 0 0); + --secondary-foreground: oklch(0.94 0 0); + --muted: oklch(0.285 0 0); + --muted-foreground: oklch(0.7 0 0); + --accent: oklch(0.32 0 0); + --accent-foreground: oklch(0.94 0 0); + --destructive: oklch(0.68 0.19 25); + --border: oklch(1 0 0 / 10%); + --input: oklch(1 0 0 / 14%); + --ring: oklch(0.62 0 0); + --chart-1: oklch(0.82 0 0); + --chart-2: oklch(0.72 0 0); + --chart-3: oklch(0.62 0 0); + --chart-4: oklch(0.52 0 0); + --chart-5: oklch(0.42 0 0); + --sidebar: oklch(0.16 0 0); + --sidebar-foreground: oklch(0.93 0 0); + --sidebar-primary: oklch(0.82 0 0); + --sidebar-primary-foreground: oklch(0.18 0 0); + --sidebar-accent: oklch(0.27 0 0); + --sidebar-accent-foreground: oklch(0.94 0 0); + --sidebar-border: oklch(1 0 0 / 9%); + --sidebar-ring: oklch(0.62 0 0); +} + +.dark[data-palette="green"] { + --background: oklch(0.18 0.016 190); + --foreground: oklch(0.94 0.009 155); + --card: oklch(0.225 0.018 190); + --card-foreground: oklch(0.94 0.009 155); + --popover: oklch(0.225 0.018 190); + --popover-foreground: oklch(0.94 0.009 155); + --primary: oklch(0.67 0.13 174); + --primary-foreground: oklch(0.16 0.024 185); + --secondary: oklch(0.285 0.019 185); + --secondary-foreground: oklch(0.94 0.009 155); + --muted: oklch(0.285 0.019 185); + --muted-foreground: oklch(0.72 0.02 165); + --accent: oklch(0.33 0.032 174); + --accent-foreground: oklch(0.955 0.011 155); + --destructive: oklch(0.68 0.19 25); + --border: oklch(1 0 0 / 10%); + --input: oklch(1 0 0 / 14%); + --ring: oklch(0.67 0.13 174); + --chart-1: oklch(0.68 0.13 174); + --chart-2: oklch(0.68 0.13 220); + --chart-3: oklch(0.75 0.15 78); + --chart-4: oklch(0.68 0.16 333); + --chart-5: oklch(0.67 0.13 262); + --sidebar: oklch(0.16 0.019 185); + --sidebar-foreground: oklch(0.93 0.01 155); + --sidebar-primary: oklch(0.67 0.13 174); + --sidebar-primary-foreground: oklch(0.16 0.024 185); + --sidebar-accent: oklch(0.27 0.028 178); + --sidebar-accent-foreground: oklch(0.955 0.011 155); + --sidebar-border: oklch(1 0 0 / 9%); + --sidebar-ring: oklch(0.67 0.13 174); +} + +.dark[data-palette="blue"] { + --background: oklch(0.178 0.012 245); + --foreground: oklch(0.948 0.006 230); + --card: oklch(0.226 0.014 245); + --card-foreground: oklch(0.948 0.006 230); + --popover: oklch(0.226 0.014 245); + --popover-foreground: oklch(0.948 0.006 230); + --primary: oklch(0.66 0.16 252); + --primary-foreground: oklch(0.168 0.015 250); + --secondary: oklch(0.285 0.014 245); + --secondary-foreground: oklch(0.94 0.006 230); + --muted: oklch(0.285 0.014 245); + --muted-foreground: oklch(0.72 0.015 238); + --accent: oklch(0.32 0.022 225); + --accent-foreground: oklch(0.955 0.006 230); + --destructive: oklch(0.68 0.19 25); + --border: oklch(1 0 0 / 10%); + --input: oklch(1 0 0 / 14%); + --ring: oklch(0.66 0.16 252); + --chart-1: oklch(0.69 0.15 252); + --chart-2: oklch(0.68 0.12 178); + --chart-3: oklch(0.75 0.15 82); + --chart-4: oklch(0.68 0.16 333); + --chart-5: oklch(0.67 0.13 285); + --sidebar: oklch(0.158 0.012 248); + --sidebar-foreground: oklch(0.93 0.006 230); + --sidebar-primary: oklch(0.66 0.16 252); + --sidebar-primary-foreground: oklch(0.168 0.015 250); + --sidebar-accent: oklch(0.255 0.017 245); + --sidebar-accent-foreground: oklch(0.955 0.006 230); + --sidebar-border: oklch(1 0 0 / 9%); + --sidebar-ring: oklch(0.66 0.16 252); +} + +.dark[data-palette="gray"] { + --background: oklch(0.178 0.012 245); + --foreground: oklch(0.948 0.006 230); + --card: oklch(0.226 0.014 245); + --card-foreground: oklch(0.948 0.006 230); + --popover: oklch(0.226 0.014 245); + --popover-foreground: oklch(0.948 0.006 230); + --primary: oklch(0.66 0.16 252); + --primary-foreground: oklch(0.168 0.015 250); + --secondary: oklch(0.285 0.014 245); + --secondary-foreground: oklch(0.94 0.006 230); + --muted: oklch(0.285 0.014 245); + --muted-foreground: oklch(0.72 0.015 238); + --accent: oklch(0.32 0.022 225); + --accent-foreground: oklch(0.955 0.006 230); + --destructive: oklch(0.68 0.19 25); + --border: oklch(1 0 0 / 10%); + --input: oklch(1 0 0 / 14%); + --ring: oklch(0.66 0.16 252); + --chart-1: oklch(0.69 0.15 252); + --chart-2: oklch(0.68 0.12 178); + --chart-3: oklch(0.75 0.15 82); + --chart-4: oklch(0.68 0.16 333); + --chart-5: oklch(0.67 0.13 285); + --sidebar: oklch(0.158 0.012 248); + --sidebar-foreground: oklch(0.93 0.006 230); + --sidebar-primary: oklch(0.66 0.16 252); + --sidebar-primary-foreground: oklch(0.168 0.015 250); + --sidebar-accent: oklch(0.255 0.017 245); + --sidebar-accent-foreground: oklch(0.955 0.006 230); + --sidebar-border: oklch(1 0 0 / 9%); + --sidebar-ring: oklch(0.66 0.16 252); +} + +@layer base { + * { + @apply border-border outline-ring/50; + } + body { + @apply bg-background text-foreground; + } + html { + @apply font-sans; + } +} diff --git a/web/app/(dashboard)/dashboard/_components/alert-list.tsx b/web/app/(dashboard)/dashboard/_components/alert-list.tsx new file mode 100644 index 0000000..fffd391 --- /dev/null +++ b/web/app/(dashboard)/dashboard/_components/alert-list.tsx @@ -0,0 +1,74 @@ +"use client" + +import Link from "next/link" +import { ArrowRightIcon, ShieldAlertIcon } from "lucide-react" + +import type { DashboardAlert } from "@/lib/api/dashboard" +import { Badge } from "@/components/ui/badge" +import { useI18n } from "@/i18n/provider" +import { + Card, + CardContent, + CardDescription, + CardHeader, + CardTitle, +} from "@/components/ui/card" + +type AlertListProps = { + alerts: DashboardAlert[] +} + +function getAlertBadgeVariant(level: DashboardAlert["level"]) { + if (level === "error") { + return "destructive" as const + } + if (level === "warning") { + return "secondary" as const + } + return "outline" as const +} + +export function AlertList({ alerts }: AlertListProps) { + const t = useI18n() + + return ( + + + {t("dashboardHome.riskAlerts")} + {t("dashboardHome.riskAlertsDescription")} + + + {alerts.length === 0 ? ( +

+ +
{t("dashboardHome.noRiskTitle")}
+
+ {t("dashboardHome.noRiskDescription")} +
+
+ ) : ( + alerts.map((item) => ( + +
+
+
+
+
{item.title}
+ + {item.count} + +
+
+ {item.description} +
+
+ +
+
+ + )) + )} + + + ) +} diff --git a/web/app/(dashboard)/dashboard/_components/dashboard-home.tsx b/web/app/(dashboard)/dashboard/_components/dashboard-home.tsx new file mode 100644 index 0000000..6118efa --- /dev/null +++ b/web/app/(dashboard)/dashboard/_components/dashboard-home.tsx @@ -0,0 +1,169 @@ +"use client" + +import { useCallback, useEffect, useState } from "react" +import { RefreshCwIcon } from "lucide-react" +import { toast } from "sonner" + +import { Button } from "@/components/ui/button" +import { Skeleton } from "@/components/ui/skeleton" +import { Card, CardContent } from "@/components/ui/card" +import { useI18n } from "@/i18n/provider" +import { + fetchDashboardOverview, + type DashboardOverview, + type DashboardRange, +} from "@/lib/api/dashboard" +import { SummaryCards } from "./summary-cards" +import { TrendPanel } from "./trend-panel" +import { TeamLoadPanel } from "./team-load-panel" +import { AlertList } from "./alert-list" +import { SetupReadinessBanner } from "./setup-readiness-banner" + +function LoadingCards() { + return ( +
+ {Array.from({ length: 6 }).map((_, index) => ( + + + + + + + + ))} +
+ ) +} + +export function DashboardHome() { + const t = useI18n() + const [range, setRange] = useState("7d") + const [data, setData] = useState(null) + const [loading, setLoading] = useState(true) + const [refreshing, setRefreshing] = useState(false) + + const loadData = useCallback( + async (nextRange: DashboardRange, showRefreshing = false) => { + if (showRefreshing) { + setRefreshing(true) + } else { + setLoading(true) + } + try { + const result = await fetchDashboardOverview(nextRange) + setData(result) + } catch (error) { + toast.error(error instanceof Error ? error.message : t("dashboardHome.loadFailed")) + } finally { + setLoading(false) + setRefreshing(false) + } + }, + [t] + ) + + useEffect(() => { + void loadData(range) + }, [loadData, range]) + + const rangeOptions: Array<{ value: DashboardRange; label: string }> = [ + { value: "today", label: t("dashboardHome.rangeToday") }, + { value: "7d", label: t("dashboardHome.range7d") }, + { value: "30d", label: t("dashboardHome.range30d") }, + ] + + return ( +
+ void loadData(range, true)} /> +
+
+
+ {rangeOptions.map((item) => ( + + ))} +
+ +
+
+ + {loading && !data ? ( + + ) : data ? ( + <> + + + + +
+ + + + +
+
{t("dashboardHome.enabledAiAgents")}
+
{data.aiStats.enabledAiAgents}
+
+
+
{t("dashboardHome.enabledChannels")}
+
{data.aiStats.enabledChannels}
+
+
+
{t("dashboardHome.todayKnowledgeRetrieves")}
+
+ {data.aiStats.todayKnowledgeRetrieves} +
+
+
+
{t("dashboardHome.todayKnowledgeRetrieveFailRate")}
+
+ {data.aiStats.todayKnowledgeRetrieveFailRate.toFixed(1)}% +
+
+
+
{t("dashboardHome.todayAgentRunFailCount")}
+
+ {data.aiStats.todayAgentRunFailCount} +
+
+
+
{t("dashboardHome.todayAiHandoffCount")}
+
+ {data.aiStats.todayAiHandoffCount} +
+
+
+
+
+ + + + ) : ( + + + {t("dashboardHome.empty")} + + + )} +
+ ) +} diff --git a/web/app/(dashboard)/dashboard/_components/setup-readiness-banner.tsx b/web/app/(dashboard)/dashboard/_components/setup-readiness-banner.tsx new file mode 100644 index 0000000..0d485db --- /dev/null +++ b/web/app/(dashboard)/dashboard/_components/setup-readiness-banner.tsx @@ -0,0 +1,173 @@ +"use client" + +import { + AlertTriangleIcon, + ArrowRightIcon, + CheckCircle2Icon, + Loader2Icon, + SparklesIcon, +} from "lucide-react" +import Link from "next/link" +import { useCallback, useEffect, useState } from "react" +import { toast } from "sonner" + +import { + notifySetupReadinessUpdated, + SETUP_READINESS_UPDATED_EVENT, +} from "@/components/operator-readiness-indicator" +import { Badge } from "@/components/ui/badge" +import { Button } from "@/components/ui/button" +import { useI18n } from "@/i18n/provider" +import { + applySetupQuickFix, + fetchSetupReadiness, + type SetupReadinessResponse, +} from "@/lib/api/setup-readiness" + +export function SetupReadinessBanner({ + onUpdated, +}: { + onUpdated?: () => void +}) { + const t = useI18n() + const [readiness, setReadiness] = useState(null) + const [fixing, setFixing] = useState(false) + + const loadReadiness = useCallback(async () => { + try { + const data = await fetchSetupReadiness() + setReadiness(data) + } catch { + // Ignore in banner if failed + } + }, []) + + useEffect(() => { + void loadReadiness() + const handleUpdated = () => { + void loadReadiness() + } + window.addEventListener(SETUP_READINESS_UPDATED_EVENT, handleUpdated) + return () => { + window.removeEventListener(SETUP_READINESS_UPDATED_EVENT, handleUpdated) + } + }, [loadReadiness]) + + async function handleQuickSetupAll() { + setFixing(true) + try { + const res = await applySetupQuickFix({ action: "quick_setup_all" }) + setReadiness(res.readiness) + notifySetupReadinessUpdated() + onUpdated?.() + toast.success(t("setupWizard.quickFixSuccess")) + } catch (error) { + toast.error( + error instanceof Error ? error.message : t("common.operationFailed"), + ) + } finally { + setFixing(false) + } + } + + if (!readiness) { + return null + } + + const allReady = + readiness.can_receive_requests_now && + readiness.current_operator.can_receive_now && + readiness.overall_status === "ok" + + if (allReady) { + return null + } + + const canQuickSetupAll = readiness.steps.some((s) => + s.quick_fix_actions.includes("quick_setup_all"), + ) + + const incompleteSteps = readiness.steps.filter((s) => s.status !== "ok") + + return ( +
+
+
+
+ +

+ {t("setupWizard.banner.title")} +

+ + {t("setupWizard.stepsProgress", { + ready: readiness.ready_steps, + total: readiness.total_steps, + })} + +
+

+ {t("setupWizard.banner.description")} +

+
+ {incompleteSteps.map((step) => ( + + {step.step_number}. {t(`setupWizard.steps.${step.key}.title`)} + + ))} + {!readiness.current_operator.can_receive_now + ? readiness.current_operator.blocker_codes.map((code) => ( + + {t(`setupWizard.operatorBlockers.${code}`)} + + )) + : null} +
+
+ +
+ {canQuickSetupAll ? ( + + ) : null} + +
+
+
+ ) +} + +export { CheckCircle2Icon } diff --git a/web/app/(dashboard)/dashboard/_components/summary-cards.tsx b/web/app/(dashboard)/dashboard/_components/summary-cards.tsx new file mode 100644 index 0000000..dd42612 --- /dev/null +++ b/web/app/(dashboard)/dashboard/_components/summary-cards.tsx @@ -0,0 +1,108 @@ +"use client" + +import Link from "next/link" +import { + BotMessageSquareIcon, + CircleDashedIcon, + HeadsetIcon, + SparklesIcon, + WavesIcon, +} from "lucide-react" + +import type { DashboardOverview } from "@/lib/api/dashboard" +import { + Card, + CardContent, + CardDescription, + CardHeader, + CardTitle, +} from "@/components/ui/card" +import { useI18n } from "@/i18n/provider" + +type SummaryCardsProps = { + summary: DashboardOverview["summary"] +} + +type SummaryCardItem = { + key: keyof DashboardOverview["summary"] + titleKey: string + descriptionKey: string + link: string + icon: typeof BotMessageSquareIcon + format?: (value: number) => string +} + +const cards: SummaryCardItem[] = [ + { + key: "todayNewConversations", + titleKey: "dashboardHome.summaryTodayNewConversations", + descriptionKey: "dashboardHome.summaryTodayNewConversationsDescription", + link: "/dashboard/conversations", + icon: BotMessageSquareIcon, + }, + { + key: "processingConversations", + titleKey: "dashboardHome.summaryProcessingConversations", + descriptionKey: "dashboardHome.summaryProcessingConversationsDescription", + link: "/dashboard/conversations", + icon: WavesIcon, + }, + { + key: "pendingDispatchConversations", + titleKey: "dashboardHome.summaryPendingDispatchConversations", + descriptionKey: "dashboardHome.summaryPendingDispatchConversationsDescription", + link: "/dashboard/conversations", + icon: CircleDashedIcon, + }, + { + key: "onlineAgents", + titleKey: "dashboardHome.summaryOnlineAgents", + descriptionKey: "dashboardHome.summaryOnlineAgentsDescription", + link: "/dashboard/agents", + icon: HeadsetIcon, + }, + { + key: "aiServiceRate", + titleKey: "dashboardHome.summaryAiServiceRate", + descriptionKey: "dashboardHome.summaryAiServiceRateDescription", + link: "/dashboard/ai-agents", + icon: SparklesIcon, + format: (value: number) => `${value.toFixed(1)}%`, + }, +] + +export function SummaryCards({ summary }: SummaryCardsProps) { + const t = useI18n() + + return ( +
+ {cards.map((item) => { + const Icon = item.icon + const rawValue = summary[item.key] + const value = + typeof item.format === "function" + ? item.format(Number(rawValue)) + : Number(rawValue).toLocaleString() + + return ( + + + +
+ {t(item.titleKey)} + {t(item.descriptionKey)} +
+
+ +
+
+ +
{value}
+
+
+ + ) + })} +
+ ) +} diff --git a/web/app/(dashboard)/dashboard/_components/team-load-panel.tsx b/web/app/(dashboard)/dashboard/_components/team-load-panel.tsx new file mode 100644 index 0000000..ad2b8bf --- /dev/null +++ b/web/app/(dashboard)/dashboard/_components/team-load-panel.tsx @@ -0,0 +1,112 @@ +"use client" + +import { Badge } from "@/components/ui/badge" +import { useI18n } from "@/i18n/provider" +import { + Card, + CardContent, + CardDescription, + CardHeader, + CardTitle, +} from "@/components/ui/card" +import type { DashboardOverview } from "@/lib/api/dashboard" + +type TeamLoadPanelProps = { + agentStats: DashboardOverview["agentStats"] +} + +function getLoadTone(loadRate: number) { + if (loadRate >= 85) { + return "bg-red-500" + } + if (loadRate >= 60) { + return "bg-amber-500" + } + return "bg-emerald-500" +} + +export function TeamLoadPanel({ agentStats }: TeamLoadPanelProps) { + const t = useI18n() + + return ( + + + {t("dashboardHome.teamLoad")} + + {t("dashboardHome.teamLoadDescription", { + online: agentStats.onlineAgents, + busy: agentStats.busyAgents, + offline: agentStats.offlineAgents, + })} + + + + {agentStats.teamLoads.length === 0 ? ( +
+ {t("dashboardHome.noTeamData")} +
+ ) : ( + agentStats.teamLoads.map((item) => ( +
+
+
+
+
{item.teamName}
+ {item.hasScheduleNow ? ( + {t("dashboardHome.scheduled")} + ) : ( + {t("dashboardHome.notScheduled")} + )} +
+
+ {t("dashboardHome.teamStats", { + total: item.totalAgents, + online: item.onlineAgents, + busy: item.busyAgents, + offline: item.offlineAgents, + })} +
+
+
+
{item.loadRate.toFixed(1)}%
+
+ {t("dashboardHome.load", { + processing: item.processingConversations, + capacity: item.maxConcurrentCapacity || 0, + })} +
+
+
+ +
+
+
+ +
+
+
{t("dashboardHome.waiting")}
+
{item.waitingConversations}
+
+
+
{t("dashboardHome.processing")}
+
{item.processingConversations}
+
+
+
{t("dashboardHome.capacity")}
+
{item.maxConcurrentCapacity}
+
+
+
{t("dashboardHome.busyAgents")}
+
{item.busyAgents}
+
+
+
+ )) + )} + + + ) +} diff --git a/web/app/(dashboard)/dashboard/_components/trend-panel.tsx b/web/app/(dashboard)/dashboard/_components/trend-panel.tsx new file mode 100644 index 0000000..f18adfa --- /dev/null +++ b/web/app/(dashboard)/dashboard/_components/trend-panel.tsx @@ -0,0 +1,141 @@ +"use client" + +import { Area, AreaChart, Bar, BarChart, CartesianGrid, XAxis, YAxis } from "recharts" + +import type { DashboardStatusDistributionItem, DashboardTrendItem } from "@/lib/api/dashboard" +import { + Card, + CardContent, + CardDescription, + CardHeader, + CardTitle, +} from "@/components/ui/card" +import { + ChartContainer, + ChartTooltip, + ChartTooltipContent, + type ChartConfig, +} from "@/components/ui/chart" +import { useI18n } from "@/i18n/provider" + +type TrendPanelProps = { + title: string + description: string + trend: DashboardTrendItem[] + distribution: DashboardStatusDistributionItem[] +} + +export function TrendPanel({ + title, + description, + trend, + distribution, +}: TrendPanelProps) { + const t = useI18n() + const trendConfig = { + newCount: { + label: t("dashboardHome.chartNew"), + color: "hsl(24 95% 53%)", + }, + closedCount: { + label: t("dashboardHome.chartClosed"), + color: "hsl(190 95% 39%)", + }, + } satisfies ChartConfig + const distributionConfig = { + count: { + label: t("dashboardHome.chartCount"), + theme: { + light: "hsl(222 47% 11%)", + dark: "hsl(210 40% 98%)", + }, + }, + } satisfies ChartConfig + const localizedDistribution = distribution.map((item) => ({ + ...item, + label: getStatusLabel(item.status, item.label, t), + })) + + return ( +
+ + + {title} + {description} + + + + + + + } /> + + + + + + + + + + {t("dashboardHome.statusDistribution")} + {t("dashboardHome.statusDistributionDescription")} + + + + + + + + } /> + + + + + +
+ ) +} + +function getStatusLabel( + status: number, + fallback: string, + t: (key: string) => string +) { + switch (status) { + case 1: + return t("dashboardHome.statusAiServing") + case 2: + return t("dashboardHome.statusPending") + case 3: + return t("dashboardHome.statusActive") + case 4: + return t("dashboardHome.statusClosed") + default: + return fallback + } +} diff --git a/web/app/(dashboard)/dashboard/agent-runs/page.tsx b/web/app/(dashboard)/dashboard/agent-runs/page.tsx new file mode 100644 index 0000000..e54e6a7 --- /dev/null +++ b/web/app/(dashboard)/dashboard/agent-runs/page.tsx @@ -0,0 +1,163 @@ +"use client" + +import { useEffect, useState } from "react" +import { AlertTriangleIcon, BotMessageSquareIcon, Clock3Icon, WorkflowIcon, WrenchIcon } from "lucide-react" +import { toast } from "sonner" + +import { DashboardListPage } from "@/components/dashboard/list" +import { JsonTreeViewer } from "@/components/json-tree-viewer" +import { OptionCombobox } from "@/components/option-combobox" +import { ProjectDialog } from "@/components/project-dialog" +import { Badge } from "@/components/ui/badge" +import { Button } from "@/components/ui/button" +import { Textarea } from "@/components/ui/textarea" +import { fetchAgentRun, fetchAgentRunMetrics, fetchAgentRuns, fetchAIWorkflowRun, saveAgentRunQualityFeedback, type AgentRun, type AgentRunMetrics, type AgentStep, type AgentToolCall, type AIWorkflowRun } from "@/lib/api/admin" +import { formatDateTime } from "@/lib/utils" +import { useI18n } from "@/i18n/provider" +import { WorkflowRunAuditGraph } from "../ai-workflow-runs/_components/workflow-run-audit-graph" + +function statusVariant(status: string) { + if (status === "failed") return "destructive" as const + if (status === "interrupted") return "outline" as const + if (status === "completed") return "default" as const + return "secondary" as const +} + +export default function DashboardAgentRunsPage() { + const t = useI18n() + const [open, setOpen] = useState(false) + const [loading, setLoading] = useState(false) + const [run, setRun] = useState(null) + const [workflowAuditOpen, setWorkflowAuditOpen] = useState(false) + const [workflowAuditLoading, setWorkflowAuditLoading] = useState(false) + const [workflowRun, setWorkflowRun] = useState(null) + const [metrics, setMetrics] = useState(null) + + useEffect(() => { + void fetchAgentRunMetrics().then(setMetrics).catch(() => setMetrics(null)) + }, []) + + async function openDetail(id: number) { + setOpen(true) + setLoading(true) + try { + setRun(await fetchAgentRun(id)) + } catch (error) { + toast.error(error instanceof Error ? error.message : t("agentRun.loadDetailFailed")) + setOpen(false) + } finally { + setLoading(false) + } + } + + async function openWorkflowAudit(id: number) { + if (id <= 0) return + setWorkflowAuditOpen(true) + setWorkflowAuditLoading(true) + try { + setWorkflowRun(await fetchAIWorkflowRun(id)) + } catch (error) { + toast.error(error instanceof Error ? error.message : t("aiWorkflow.loadDetailFailed")) + setWorkflowAuditOpen(false) + } finally { + setWorkflowAuditLoading(false) + } + } + + return ( + <> + {metrics ?
+ + + + + + + + + + +
: null} + + filters={[ + { name: "conversationId", label: t("agentRun.conversation"), defaultValue: "", valueType: "number", className: "w-full sm:w-40" }, + { name: "aiAgentId", label: t("agentRun.agent"), defaultValue: "", valueType: "number", className: "w-full sm:w-40" }, + { name: "status", label: t("agentRun.status"), defaultValue: "", className: "w-full sm:w-40" }, + ]} + fetchList={fetchAgentRuns} + getItemId={(item) => item.id} + getRowClassName={() => "cursor-pointer"} + onRowClick={(item) => void openDetail(item.id)} + columns={[ + { key: "startedAt", label: t("agentRun.startedAt"), className: "w-42 text-xs text-muted-foreground", render: (item) => formatDateTime(item.startedAt || item.createdAt) }, + { key: "agent", label: t("agentRun.agent"), className: "w-28", render: (item) => `#${item.aiAgentId || "-"}` }, + { key: "conversation", label: t("agentRun.conversation"), className: "w-28", render: (item) => `#${item.conversationId || "-"}` }, + { key: "status", label: t("agentRun.status"), className: "w-30", render: (item) => {item.status || "-"} }, + { key: "duration", label: t("agentRun.duration"), className: "w-24 text-right", render: (item) => `${item.durationMs || 0} ms` }, + { key: "tokens", label: t("agentRun.tokens"), className: "w-28 text-right", render: (item) => `${item.promptTokens || 0}/${item.completionTokens || 0}` }, + { key: "error", label: t("agentRun.error"), className: "w-72 max-w-72", render: (item) => item.errorMessage ? {item.errorMessage} : "-" }, + ]} + labels={{ refresh: t("agentRun.refresh"), query: t("agentRun.query"), loading: t("agentRun.loading"), empty: t("agentRun.empty"), loadFailed: t("agentRun.loadFailed") }} + /> + void openDetail(id)} onOpenChange={(next) => { setOpen(next); if (!next) setRun(null) }} t={t} /> + { setWorkflowAuditOpen(next); if (!next) setWorkflowRun(null) }} /> + + ) +} + +function Metric({ label, value, detail }: { label: string; value: string; detail: string }) { return
{label}
{value}
{detail}
} + +function AgentRunDetailDialog({ open, loading, run, onOpenChange, onOpenWorkflowAudit, onQualityFeedbackSaved, t }: { open: boolean; loading: boolean; run: AgentRun | null; onOpenChange: (open: boolean) => void; onOpenWorkflowAudit: (workflowRunId: number) => void; onQualityFeedbackSaved: (agentRunId: number) => void; t: (key: string) => string }) { + return {t("agentRun.detailTitle")}} description={run ? `Run #${run.id}` : t("agentRun.detailDescription")} footer={}> + {loading ?
{t("agentRun.loadingDetail")}
: run ?
+
+ {run.workflowRunId > 0 ?
{t("agentRun.workflowAudit")}
Workflow Run #{run.workflowRunId}
: null} + + {run.errorMessage ?
{run.errorMessage}
: null} + +

{t("agentRun.steps")}

{(run.steps ?? []).map((step) => )}{!run.steps?.length ?

{t("agentRun.emptySteps")}

: null}
+

{t("agentRun.toolCalls")}

{(run.toolCalls ?? []).map((call) => )}{!run.toolCalls?.length ?

{t("agentRun.emptyToolCalls")}

: null}
+
:
{t("agentRun.notFound")}
} +
+} + +function QualityFeedbackPanel({ run, onSaved, t }: { run: AgentRun; onSaved: (agentRunId: number) => void; t: (key: string) => string }) { + const [resolutionStatus, setResolutionStatus] = useState<"unknown" | "resolved" | "unresolved">("unknown") + const [evidenceStatus, setEvidenceStatus] = useState<"unknown" | "supported" | "unsupported">("unknown") + const [comment, setComment] = useState("") + const [saving, setSaving] = useState(false) + + useEffect(() => { + setResolutionStatus(run.qualityFeedback?.resolutionStatus ?? "unknown") + setEvidenceStatus(run.qualityFeedback?.evidenceStatus ?? "unknown") + setComment(run.qualityFeedback?.comment ?? "") + }, [run.id, run.qualityFeedback]) + + async function save() { + setSaving(true) + try { + await saveAgentRunQualityFeedback({ agentRunId: run.id, resolutionStatus, evidenceStatus, comment }) + toast.success(t("agentRun.qualitySaved")) + onSaved(run.id) + } catch (error) { + toast.error(error instanceof Error ? error.message : "Save failed") + } finally { + setSaving(false) + } + } + + return

{t("agentRun.qualityTitle")}

{t("agentRun.qualityDescription")}

setResolutionStatus(value === "resolved" || value === "unresolved" ? value : "unknown")} /> setEvidenceStatus(value === "supported" || value === "unsupported" ? value : "unknown")} />