@sleep2agi/agent-network-dashboard 0.5.7-preview.7 → 0.5.7-preview.75
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.next/BUILD_ID +1 -1
- package/.next/app-path-routes-manifest.json +0 -1
- package/.next/build-manifest.json +3 -3
- package/.next/diagnostics/route-bundle-stats.json +65 -65
- package/.next/fallback-build-manifest.json +3 -3
- package/.next/prerender-manifest.json +3 -3
- package/.next/routes-manifest.json +0 -6
- package/.next/server/app/_global-error.html +1 -1
- package/.next/server/app/_global-error.rsc +1 -1
- package/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/_not-found/page/next-font-manifest.json +2 -1
- package/.next/server/app/_not-found/page.js +1 -1
- package/.next/server/app/_not-found/page.js.nft.json +1 -1
- package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/.next/server/app/_not-found.html +4 -4
- package/.next/server/app/_not-found.rsc +16 -16
- package/.next/server/app/_not-found.segments/_full.segment.rsc +16 -16
- package/.next/server/app/_not-found.segments/_head.segment.rsc +4 -4
- package/.next/server/app/_not-found.segments/_index.segment.rsc +9 -9
- package/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +2 -2
- package/.next/server/app/_not-found.segments/_not-found.segment.rsc +3 -3
- package/.next/server/app/_not-found.segments/_tree.segment.rsc +3 -3
- package/.next/server/app/admin/page/next-font-manifest.json +2 -1
- package/.next/server/app/admin/page.js +1 -1
- package/.next/server/app/admin/page.js.nft.json +1 -1
- package/.next/server/app/admin/page_client-reference-manifest.js +1 -1
- package/.next/server/app/admin.html +4 -4
- package/.next/server/app/admin.rsc +20 -19
- package/.next/server/app/admin.segments/_full.segment.rsc +20 -19
- package/.next/server/app/admin.segments/_head.segment.rsc +4 -4
- package/.next/server/app/admin.segments/_index.segment.rsc +9 -9
- package/.next/server/app/admin.segments/_tree.segment.rsc +5 -4
- package/.next/server/app/admin.segments/admin/__PAGE__.segment.rsc +4 -4
- package/.next/server/app/admin.segments/admin.segment.rsc +3 -3
- package/.next/server/app/index.html +4 -4
- package/.next/server/app/index.rsc +20 -19
- package/.next/server/app/index.segments/__PAGE__.segment.rsc +4 -4
- package/.next/server/app/index.segments/_full.segment.rsc +20 -19
- package/.next/server/app/index.segments/_head.segment.rsc +4 -4
- package/.next/server/app/index.segments/_index.segment.rsc +9 -9
- package/.next/server/app/index.segments/_tree.segment.rsc +5 -4
- package/.next/server/app/login/page/next-font-manifest.json +2 -1
- package/.next/server/app/login/page.js +1 -1
- package/.next/server/app/login/page.js.nft.json +1 -1
- package/.next/server/app/login/page_client-reference-manifest.js +1 -1
- package/.next/server/app/login.html +2 -2
- package/.next/server/app/login.rsc +20 -19
- package/.next/server/app/login.segments/_full.segment.rsc +20 -19
- package/.next/server/app/login.segments/_head.segment.rsc +4 -4
- package/.next/server/app/login.segments/_index.segment.rsc +9 -9
- package/.next/server/app/login.segments/_tree.segment.rsc +5 -4
- package/.next/server/app/login.segments/login/__PAGE__.segment.rsc +4 -4
- package/.next/server/app/login.segments/login.segment.rsc +3 -3
- package/.next/server/app/logs/page/next-font-manifest.json +2 -1
- package/.next/server/app/logs/page.js +1 -1
- package/.next/server/app/logs/page.js.nft.json +1 -1
- package/.next/server/app/logs/page_client-reference-manifest.js +1 -1
- package/.next/server/app/logs.html +4 -4
- package/.next/server/app/logs.rsc +20 -19
- package/.next/server/app/logs.segments/_full.segment.rsc +20 -19
- package/.next/server/app/logs.segments/_head.segment.rsc +4 -4
- package/.next/server/app/logs.segments/_index.segment.rsc +9 -9
- package/.next/server/app/logs.segments/_tree.segment.rsc +5 -4
- package/.next/server/app/logs.segments/logs/__PAGE__.segment.rsc +4 -4
- package/.next/server/app/logs.segments/logs.segment.rsc +3 -3
- package/.next/server/app/manifest.webmanifest.body +1 -1
- package/.next/server/app/messages/page/next-font-manifest.json +2 -1
- package/.next/server/app/messages/page.js +1 -1
- package/.next/server/app/messages/page.js.nft.json +1 -1
- package/.next/server/app/messages/page_client-reference-manifest.js +1 -1
- package/.next/server/app/messages.html +4 -4
- package/.next/server/app/messages.rsc +20 -19
- package/.next/server/app/messages.segments/_full.segment.rsc +20 -19
- package/.next/server/app/messages.segments/_head.segment.rsc +4 -4
- package/.next/server/app/messages.segments/_index.segment.rsc +9 -9
- package/.next/server/app/messages.segments/_tree.segment.rsc +5 -4
- package/.next/server/app/messages.segments/messages/__PAGE__.segment.rsc +4 -4
- package/.next/server/app/messages.segments/messages.segment.rsc +3 -3
- package/.next/server/app/node/page/next-font-manifest.json +2 -1
- package/.next/server/app/node/page.js +1 -1
- package/.next/server/app/node/page.js.nft.json +1 -1
- package/.next/server/app/node/page_client-reference-manifest.js +1 -1
- package/.next/server/app/node.html +4 -4
- package/.next/server/app/node.rsc +20 -19
- package/.next/server/app/node.segments/_full.segment.rsc +20 -19
- package/.next/server/app/node.segments/_head.segment.rsc +4 -4
- package/.next/server/app/node.segments/_index.segment.rsc +9 -9
- package/.next/server/app/node.segments/_tree.segment.rsc +5 -4
- package/.next/server/app/node.segments/node/__PAGE__.segment.rsc +4 -4
- package/.next/server/app/node.segments/node.segment.rsc +3 -3
- package/.next/server/app/nodes/page/next-font-manifest.json +2 -1
- package/.next/server/app/nodes/page.js +1 -1
- package/.next/server/app/nodes/page.js.nft.json +1 -1
- package/.next/server/app/nodes/page_client-reference-manifest.js +1 -1
- package/.next/server/app/nodes.html +4 -4
- package/.next/server/app/nodes.rsc +20 -19
- package/.next/server/app/nodes.segments/_full.segment.rsc +20 -19
- package/.next/server/app/nodes.segments/_head.segment.rsc +4 -4
- package/.next/server/app/nodes.segments/_index.segment.rsc +9 -9
- package/.next/server/app/nodes.segments/_tree.segment.rsc +5 -4
- package/.next/server/app/nodes.segments/nodes/__PAGE__.segment.rsc +4 -4
- package/.next/server/app/nodes.segments/nodes.segment.rsc +3 -3
- package/.next/server/app/page/next-font-manifest.json +2 -1
- package/.next/server/app/page.js +1 -1
- package/.next/server/app/page.js.nft.json +1 -1
- package/.next/server/app/page_client-reference-manifest.js +1 -1
- package/.next/server/app/server-logs/page/next-font-manifest.json +2 -1
- package/.next/server/app/server-logs/page.js +1 -1
- package/.next/server/app/server-logs/page.js.nft.json +1 -1
- package/.next/server/app/server-logs/page_client-reference-manifest.js +1 -1
- package/.next/server/app/server-logs.html +4 -4
- package/.next/server/app/server-logs.rsc +20 -19
- package/.next/server/app/server-logs.segments/_full.segment.rsc +20 -19
- package/.next/server/app/server-logs.segments/_head.segment.rsc +4 -4
- package/.next/server/app/server-logs.segments/_index.segment.rsc +9 -9
- package/.next/server/app/server-logs.segments/_tree.segment.rsc +5 -4
- package/.next/server/app/server-logs.segments/server-logs/__PAGE__.segment.rsc +4 -4
- package/.next/server/app/server-logs.segments/server-logs.segment.rsc +3 -3
- package/.next/server/app/servers/page/next-font-manifest.json +2 -1
- package/.next/server/app/servers/page.js +1 -1
- package/.next/server/app/servers/page.js.nft.json +1 -1
- package/.next/server/app/servers/page_client-reference-manifest.js +1 -1
- package/.next/server/app/servers.html +4 -4
- package/.next/server/app/servers.rsc +20 -19
- package/.next/server/app/servers.segments/_full.segment.rsc +20 -19
- package/.next/server/app/servers.segments/_head.segment.rsc +4 -4
- package/.next/server/app/servers.segments/_index.segment.rsc +9 -9
- package/.next/server/app/servers.segments/_tree.segment.rsc +5 -4
- package/.next/server/app/servers.segments/servers/__PAGE__.segment.rsc +4 -4
- package/.next/server/app/servers.segments/servers.segment.rsc +3 -3
- package/.next/server/app/settings/networks/page/next-font-manifest.json +2 -1
- package/.next/server/app/settings/networks/page.js +1 -1
- package/.next/server/app/settings/networks/page.js.nft.json +1 -1
- package/.next/server/app/settings/networks/page_client-reference-manifest.js +1 -1
- package/.next/server/app/settings/networks.html +4 -4
- package/.next/server/app/settings/networks.rsc +20 -19
- package/.next/server/app/settings/networks.segments/_full.segment.rsc +20 -19
- package/.next/server/app/settings/networks.segments/_head.segment.rsc +4 -4
- package/.next/server/app/settings/networks.segments/_index.segment.rsc +9 -9
- package/.next/server/app/settings/networks.segments/_tree.segment.rsc +5 -4
- package/.next/server/app/settings/networks.segments/settings/networks/__PAGE__.segment.rsc +4 -4
- package/.next/server/app/settings/networks.segments/settings/networks.segment.rsc +3 -3
- package/.next/server/app/settings/networks.segments/settings.segment.rsc +3 -3
- package/.next/server/app/settings/page/next-font-manifest.json +2 -1
- package/.next/server/app/settings/page.js +1 -1
- package/.next/server/app/settings/page.js.nft.json +1 -1
- package/.next/server/app/settings/page_client-reference-manifest.js +1 -1
- package/.next/server/app/settings/tokens/page/next-font-manifest.json +2 -1
- package/.next/server/app/settings/tokens/page.js +1 -1
- package/.next/server/app/settings/tokens/page.js.nft.json +1 -1
- package/.next/server/app/settings/tokens/page_client-reference-manifest.js +1 -1
- package/.next/server/app/settings/tokens.html +4 -4
- package/.next/server/app/settings/tokens.rsc +20 -19
- package/.next/server/app/settings/tokens.segments/_full.segment.rsc +20 -19
- package/.next/server/app/settings/tokens.segments/_head.segment.rsc +4 -4
- package/.next/server/app/settings/tokens.segments/_index.segment.rsc +9 -9
- package/.next/server/app/settings/tokens.segments/_tree.segment.rsc +5 -4
- package/.next/server/app/settings/tokens.segments/settings/tokens/__PAGE__.segment.rsc +4 -4
- package/.next/server/app/settings/tokens.segments/settings/tokens.segment.rsc +3 -3
- package/.next/server/app/settings/tokens.segments/settings.segment.rsc +3 -3
- package/.next/server/app/settings.html +4 -4
- package/.next/server/app/settings.rsc +20 -19
- package/.next/server/app/settings.segments/_full.segment.rsc +20 -19
- package/.next/server/app/settings.segments/_head.segment.rsc +4 -4
- package/.next/server/app/settings.segments/_index.segment.rsc +9 -9
- package/.next/server/app/settings.segments/_tree.segment.rsc +5 -4
- package/.next/server/app/settings.segments/settings/__PAGE__.segment.rsc +4 -4
- package/.next/server/app/settings.segments/settings.segment.rsc +3 -3
- package/.next/server/app/tasks/[id]/page/next-font-manifest.json +2 -1
- package/.next/server/app/tasks/[id]/page.js +1 -1
- package/.next/server/app/tasks/[id]/page.js.nft.json +1 -1
- package/.next/server/app/tasks/[id]/page_client-reference-manifest.js +1 -1
- package/.next/server/app/tasks/page/next-font-manifest.json +2 -1
- package/.next/server/app/tasks/page.js +1 -1
- package/.next/server/app/tasks/page.js.nft.json +1 -1
- package/.next/server/app/tasks/page_client-reference-manifest.js +1 -1
- package/.next/server/app/tasks.html +4 -4
- package/.next/server/app/tasks.rsc +20 -19
- package/.next/server/app/tasks.segments/_full.segment.rsc +20 -19
- package/.next/server/app/tasks.segments/_head.segment.rsc +4 -4
- package/.next/server/app/tasks.segments/_index.segment.rsc +9 -9
- package/.next/server/app/tasks.segments/_tree.segment.rsc +5 -4
- package/.next/server/app/tasks.segments/tasks/__PAGE__.segment.rsc +4 -4
- package/.next/server/app/tasks.segments/tasks.segment.rsc +3 -3
- package/.next/server/app-paths-manifest.json +0 -1
- package/.next/server/chunks/00jm_next_dist_0ju_ux9._.js +1 -1
- package/.next/server/chunks/00jm_next_dist_0ju_ux9._.js.map +1 -1
- package/.next/server/chunks/ssr/[root-of-the-server]__030vg4n._.js +2 -2
- package/.next/server/chunks/ssr/[root-of-the-server]__030vg4n._.js.map +1 -1
- package/.next/server/chunks/ssr/[root-of-the-server]__05kf31s._.js +3 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__05kf31s._.js.map +1 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__096ytyk._.js +3 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__096ytyk._.js.map +1 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__0fhoq8i._.js +1 -1
- package/.next/server/chunks/ssr/[root-of-the-server]__0fhoq8i._.js.map +1 -1
- package/.next/server/chunks/ssr/[root-of-the-server]__0nw1f-j._.js +3 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__0nw1f-j._.js.map +1 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__0u4-66w._.js +8 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__0u4-66w._.js.map +1 -0
- package/.next/server/chunks/ssr/agent-network-dashboard_09kk21a._.js +3 -3
- package/.next/server/chunks/ssr/agent-network-dashboard_09kk21a._.js.map +1 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_app_012oyw5._.js +3 -0
- package/.next/server/chunks/ssr/agent-network-dashboard_app_012oyw5._.js.map +1 -0
- package/.next/server/chunks/ssr/agent-network-dashboard_app_01jhlxz._.js +1 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_app_01jhlxz._.js.map +1 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_app_09d29my._.js +1 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_app_09d29my._.js.map +1 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_app_0_d45-d._.js +1 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_app_0_d45-d._.js.map +1 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_app_0fjlnh~._.js +3 -0
- package/.next/server/chunks/ssr/agent-network-dashboard_app_0fjlnh~._.js.map +1 -0
- package/.next/server/chunks/ssr/agent-network-dashboard_app_0gd.4pc._.js +9 -0
- package/.next/server/chunks/ssr/agent-network-dashboard_app_0gd.4pc._.js.map +1 -0
- package/.next/server/chunks/ssr/agent-network-dashboard_app_0wn4jc5._.js +3 -0
- package/.next/server/chunks/ssr/agent-network-dashboard_app_0wn4jc5._.js.map +1 -0
- package/.next/server/chunks/ssr/agent-network-dashboard_app_0xgney8._.js +1 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_app_0xgney8._.js.map +1 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_app_10hjgv4._.js +1 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_app_10hjgv4._.js.map +1 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_app_12l4oto._.js +1 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_app_12l4oto._.js.map +1 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_app_components_0r7kb.o._.js +9 -0
- package/.next/server/chunks/ssr/agent-network-dashboard_app_components_0r7kb.o._.js.map +1 -0
- package/.next/server/chunks/ssr/agent-network-dashboard_app_servers_page_tsx_0jib5qm._.js +1 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_app_servers_page_tsx_0jib5qm._.js.map +1 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_app_tasks_page_tsx_0mwxy4z._.js +1 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_app_tasks_page_tsx_0mwxy4z._.js.map +1 -1
- package/.next/server/middleware-build-manifest.js +3 -3
- package/.next/server/next-font-manifest.js +1 -1
- package/.next/server/next-font-manifest.json +30 -15
- package/.next/server/pages/404.html +4 -4
- package/.next/server/pages/500.html +1 -1
- package/.next/server/server-reference-manifest.js +1 -1
- package/.next/server/server-reference-manifest.json +1 -1
- package/.next/static/chunks/0.mh8n0itrii5.js +1 -0
- package/.next/static/chunks/049vx3qljs1tt.js +1 -0
- package/.next/static/chunks/04uju~n5s9g7..css +1 -0
- package/.next/static/chunks/066jf0nk75nic.css +2 -0
- package/.next/static/chunks/06vp7429lrzl7.js +1 -0
- package/.next/static/chunks/{0jp~cs9-zkmqa.js → 07h2umbpc5lqy.js} +2 -2
- package/.next/static/chunks/0_bn~gcrgo.4n.js +1 -0
- package/.next/static/chunks/0_cm~9rtqil56.js +1 -0
- package/.next/static/chunks/0cp0cz3mxejl~.js +4 -0
- package/.next/static/chunks/0g1o7c8fbafn7.js +1 -0
- package/.next/static/chunks/0g4d-_fi-d9hg.js +1 -0
- package/.next/static/chunks/0iv.0p9_5b36e.js +1 -0
- package/.next/static/chunks/0tor7h4q5_rz..js +1 -0
- package/.next/static/chunks/0vun~4ljcrj3p.js +7 -0
- package/.next/static/chunks/0wz0122ym_gr3.js +1 -0
- package/.next/static/chunks/0y5gol09tlu63.js +1 -0
- package/.next/static/chunks/114o05335p68v.js +1 -0
- package/.next/static/chunks/14141xj5.1t3t.js +1 -0
- package/.next/static/chunks/149a4l50_3vw-.js +7 -0
- package/.next/static/chunks/15hos-r_t7doi.js +1 -0
- package/.next/static/media/4fa387ec64143e14-s.0wkzw~je483f-.woff2 +0 -0
- package/.next/static/media/53b9e256198e5412-s.0-wfv7uh4i7h9.woff2 +0 -0
- package/.next/static/media/5ce348bf30bf5439-s.0zgw-jeven.3w.woff2 +0 -0
- package/.next/static/media/6306c77e7c8268e4-s.0rhz0arwfsn~5.woff2 +0 -0
- package/.next/static/media/7178b3e590c64307-s.0nx0ww8fni_q3.woff2 +0 -0
- package/.next/static/media/797e433ab948586e-s.p.08e28id.o-okb.woff2 +0 -0
- package/.next/static/media/7d817b4c03b0c5f1-s.0l76wvqk9d84w.woff2 +0 -0
- package/.next/static/media/8a480f0b521d4e75-s.0jzbimsg8vl84.woff2 +0 -0
- package/.next/static/media/bbc41e54d2fcbd21-s.0k4k9394f2q-k.woff2 +0 -0
- package/.next/static/media/caa3a2e1cccd8315-s.p.09~u27dqhyhd6.woff2 +0 -0
- package/.next/static/media/fef07dbb0973bf53-s.12tyk43_3sh9u.woff2 +0 -0
- package/.next/trace +2 -2
- package/.next/trace-build +1 -1
- package/.next/types/routes.d.ts +1 -2
- package/.next/types/validator.ts +0 -9
- package/app/admin/page.tsx +53 -38
- package/app/components/AgentCard.tsx +36 -20
- package/app/components/AppShell.tsx +7 -1
- package/app/components/ChatPopover.tsx +1 -1
- package/app/components/CollapsibleSearch.tsx +127 -0
- package/app/components/CommandCenter.tsx +14 -4
- package/app/components/CommandPalette.tsx +6 -6
- package/app/components/DispatchPanel.tsx +13 -10
- package/app/components/EmptyState.tsx +19 -4
- package/app/components/HealthBanner.tsx +28 -4
- package/app/components/HelpOverlay.tsx +4 -7
- package/app/components/LoadingSkeleton.tsx +31 -21
- package/app/components/MobileNav.tsx +28 -21
- package/app/components/Sidebar.tsx +30 -23
- package/app/components/StatsBar.tsx +69 -42
- package/app/components/TaskChatPanel.tsx +105 -12
- package/app/components/TaskDrawer.tsx +9 -7
- package/app/components/ThemeSwitcher.tsx +15 -79
- package/app/components/TopoGraph.tsx +31 -21
- package/app/components/UserBar.tsx +5 -5
- package/app/globals.css +1757 -1776
- package/app/layout.tsx +37 -4
- package/app/lib/hooks.ts +4 -6
- package/app/lib/status.ts +24 -17
- package/app/login/page.tsx +7 -7
- package/app/logs/page.tsx +12 -6
- package/app/manifest.ts +2 -2
- package/app/messages/page.tsx +108 -50
- package/app/node/page.tsx +27 -17
- package/app/nodes/page.tsx +62 -49
- package/app/page.tsx +60 -282
- package/app/server-logs/page.tsx +40 -14
- package/app/servers/page.tsx +33 -12
- package/app/settings/networks/page.tsx +17 -15
- package/app/settings/page.tsx +102 -96
- package/app/settings/tokens/page.tsx +5 -5
- package/app/tasks/[id]/page.tsx +10 -10
- package/app/tasks/page.tsx +58 -34
- package/bin/start.js +0 -0
- package/package.json +1 -1
- package/public/favicon.svg +1 -1
- package/public/manifest.webmanifest +24 -0
- package/public/robots.txt +7 -0
- package/.next/server/app/api/hub/license/route/app-paths-manifest.json +0 -3
- package/.next/server/app/api/hub/license/route/build-manifest.json +0 -9
- package/.next/server/app/api/hub/license/route/server-reference-manifest.json +0 -4
- package/.next/server/app/api/hub/license/route.js +0 -7
- package/.next/server/app/api/hub/license/route.js.map +0 -5
- package/.next/server/app/api/hub/license/route.js.nft.json +0 -1
- package/.next/server/app/api/hub/license/route_client-reference-manifest.js +0 -3
- package/.next/server/chunks/0ykm__next-internal_server_app_api_hub_license_route_actions_0a4.fuh.js +0 -3
- package/.next/server/chunks/0ykm__next-internal_server_app_api_hub_license_route_actions_0a4.fuh.js.map +0 -1
- package/.next/server/chunks/[root-of-the-server]__0rovr5-._.js +0 -3
- package/.next/server/chunks/[root-of-the-server]__0rovr5-._.js.map +0 -1
- package/.next/server/chunks/ssr/[root-of-the-server]__0lu1wok._.js +0 -8
- package/.next/server/chunks/ssr/[root-of-the-server]__0lu1wok._.js.map +0 -1
- package/.next/server/chunks/ssr/[root-of-the-server]__0nw~zhp._.js +0 -3
- package/.next/server/chunks/ssr/[root-of-the-server]__0nw~zhp._.js.map +0 -1
- package/.next/server/chunks/ssr/[root-of-the-server]__0sv~g.o._.js +0 -3
- package/.next/server/chunks/ssr/[root-of-the-server]__0sv~g.o._.js.map +0 -1
- package/.next/server/chunks/ssr/[root-of-the-server]__11fu-5m._.js +0 -3
- package/.next/server/chunks/ssr/[root-of-the-server]__11fu-5m._.js.map +0 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_app_057q.ne._.js +0 -3
- package/.next/server/chunks/ssr/agent-network-dashboard_app_057q.ne._.js.map +0 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_app_0i3759l._.js +0 -3
- package/.next/server/chunks/ssr/agent-network-dashboard_app_0i3759l._.js.map +0 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_app_1153xeb._.js +0 -9
- package/.next/server/chunks/ssr/agent-network-dashboard_app_1153xeb._.js.map +0 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_app_components_0s5uqlp._.js +0 -9
- package/.next/server/chunks/ssr/agent-network-dashboard_app_components_0s5uqlp._.js.map +0 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_app_server-logs_page_tsx_0dg.l_8._.js +0 -3
- package/.next/server/chunks/ssr/agent-network-dashboard_app_server-logs_page_tsx_0dg.l_8._.js.map +0 -1
- package/.next/static/chunks/0-mpa_947ipeq.js +0 -1
- package/.next/static/chunks/02to42x11p557.js +0 -7
- package/.next/static/chunks/03~5pxwbxxw-b.js +0 -1
- package/.next/static/chunks/04~fkia6-79k3.js +0 -1
- package/.next/static/chunks/0561vp5-q5.zp.js +0 -1
- package/.next/static/chunks/05uk96gc~9mni.js +0 -1
- package/.next/static/chunks/085rejlait1fs.js +0 -1
- package/.next/static/chunks/0a.9~-nf0gpec.js +0 -1
- package/.next/static/chunks/0im751o4n61c7.js +0 -1
- package/.next/static/chunks/0inql3s9ldyx5.js +0 -1
- package/.next/static/chunks/0ku0fjqlm9mca.js +0 -1
- package/.next/static/chunks/0mcamnu4w_x1r.js +0 -4
- package/.next/static/chunks/0ss8u23bnbyry.js +0 -1
- package/.next/static/chunks/0~rv5y.y5my9s.css +0 -1
- package/.next/static/chunks/13yktdzuatx3d.js +0 -1
- package/.next/static/chunks/15-ltfhot3b4n.js +0 -7
- package/.next/static/chunks/16ls93seuyj8a.js +0 -1
- package/.next/static/chunks/17sxlwlx5fhrp.css +0 -1
- package/.next/static/chunks/181u38qblp8lz.js +0 -1
- package/.next/static/media/4fa387ec64143e14-s.0.qu-9752pffj.woff2 +0 -0
- package/.next/static/media/5ce348bf30bf5439-s.0ee55_hj9qcer.woff2 +0 -0
- package/.next/static/media/6306c77e7c8268e4-s.0mao5jbfbduzp.woff2 +0 -0
- package/.next/static/media/797e433ab948586e-s.p.09zddjkbdep5a.woff2 +0 -0
- package/.next/static/media/7d817b4c03b0c5f1-s.0uzt.a6d44yda.woff2 +0 -0
- package/.next/static/media/bbc41e54d2fcbd21-s.0mvwgmnhv29no.woff2 +0 -0
- package/app/api/hub/license/route.ts +0 -33
- package/app/components/BroadcastBar.tsx +0 -84
- package/app/components/InboxPanel.tsx +0 -36
- /package/.next/static/{vv4Gz5yVhOzydMI2UlT1l → nPhsSMLrgn8H0RsXNP4ku}/_buildManifest.js +0 -0
- /package/.next/static/{vv4Gz5yVhOzydMI2UlT1l → nPhsSMLrgn8H0RsXNP4ku}/_clientMiddlewareManifest.js +0 -0
- /package/.next/static/{vv4Gz5yVhOzydMI2UlT1l → nPhsSMLrgn8H0RsXNP4ku}/_ssgManifest.js +0 -0
package/app/page.tsx
CHANGED
|
@@ -1,46 +1,33 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import { useState } from 'react';
|
|
4
4
|
import Link from 'next/link';
|
|
5
|
-
import { formatUptime, previewContent } from './components/utils';
|
|
6
5
|
import { StatsBar } from './components/StatsBar';
|
|
7
|
-
import { BroadcastBar } from './components/BroadcastBar';
|
|
8
6
|
import { TopoGraph } from './components/TopoGraph';
|
|
9
7
|
import { AgentCard } from './components/AgentCard';
|
|
10
|
-
import { InboxPanel } from './components/InboxPanel';
|
|
11
8
|
import { LoadingSkeleton } from './components/LoadingSkeleton';
|
|
12
9
|
import { NodesEmptyState as EmptyState } from './components/EmptyState';
|
|
13
|
-
import { AliasAvatar } from './components/AliasAvatar';
|
|
14
|
-
import { STATUS_DOT_HEX, STATUS_CHIP_CLASS } from './lib/status';
|
|
15
|
-
import { UserBar } from './components/UserBar';
|
|
16
10
|
import { CommandCenter, useCommandCenter } from './components/CommandCenter';
|
|
17
|
-
import {
|
|
18
|
-
import { useSessions, useHealth, useAnetConfig, useTasks, useStats } from './lib/hooks';
|
|
11
|
+
import { useSessions, useHealth, useTasks, useStats } from './lib/hooks';
|
|
19
12
|
import { useSSE } from './lib/useSSE';
|
|
20
|
-
import { InboxMessage } from './components/types';
|
|
21
13
|
import { useSWRConfig } from 'swr';
|
|
22
14
|
|
|
23
15
|
export default function Dashboard() {
|
|
24
|
-
//
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
}, []);
|
|
16
|
+
// #214 F1: the old "V3 auto-upgrade" guard here checked per-tab
|
|
17
|
+
// sessionStorage and, when empty (every new tab / browser restart /
|
|
18
|
+
// bookmark visit), logged out the *valid* cookie session and bounced
|
|
19
|
+
// to /login. Unauthenticated access is already handled server-side
|
|
20
|
+
// by proxy.ts (no cookie → /login); the sessionStorage blob is just
|
|
21
|
+
// a client cache that pages re-hydrate on demand. A genuinely stale
|
|
22
|
+
// pre-V3 cookie now surfaces as API 401s with the error banner
|
|
23
|
+
// instead of silent session destruction.
|
|
33
24
|
|
|
34
25
|
const { sessions, hint: sessHint, error: sessError, isLoading } = useSessions();
|
|
35
26
|
const { health } = useHealth();
|
|
36
|
-
const { config: anetConfig } = useAnetConfig();
|
|
37
27
|
const { tasks } = useTasks({ limit: '500' });
|
|
38
28
|
const { stats } = useStats();
|
|
39
29
|
const [showTopo, setShowTopo] = useState(typeof window !== 'undefined' && window.innerWidth >= 1024);
|
|
40
|
-
const [showConfig, setShowConfig] = useState(false);
|
|
41
30
|
const cmd = useCommandCenter();
|
|
42
|
-
const [showDispatch, setShowDispatch] = useState(false);
|
|
43
|
-
const [inbox, setInbox] = useState<InboxMessage[]>([]);
|
|
44
31
|
const [agentFilter, setAgentFilter] = useState<'all' | 'working' | 'idle' | 'offline'>('all');
|
|
45
32
|
// #84: last node.renamed event — passed to TopoGraph so an open chat
|
|
46
33
|
// popover follows the rename instead of pointing at a dead alias. `ts`
|
|
@@ -75,22 +62,6 @@ export default function Dashboard() {
|
|
|
75
62
|
},
|
|
76
63
|
});
|
|
77
64
|
|
|
78
|
-
// Fetch inbox (not in SWR since it accumulates)
|
|
79
|
-
useEffect(() => {
|
|
80
|
-
const fetchInbox = () => {
|
|
81
|
-
fetch('/api/hub/inbox').then(r => r.json()).then(data => {
|
|
82
|
-
if (data.messages?.length) setInbox(prev => {
|
|
83
|
-
const ids = new Set(prev.map(m => m.id));
|
|
84
|
-
const newMsgs = data.messages.filter((m: { id: string }) => !ids.has(m.id));
|
|
85
|
-
return [...newMsgs, ...prev].slice(0, 100);
|
|
86
|
-
});
|
|
87
|
-
}).catch(() => {});
|
|
88
|
-
};
|
|
89
|
-
fetchInbox();
|
|
90
|
-
const interval = setInterval(fetchInbox, 10000);
|
|
91
|
-
return () => clearInterval(interval);
|
|
92
|
-
}, []);
|
|
93
|
-
|
|
94
65
|
if (isLoading) return <LoadingSkeleton />;
|
|
95
66
|
|
|
96
67
|
const sseSessions = health?.sse_sessions || {};
|
|
@@ -98,19 +69,15 @@ export default function Dashboard() {
|
|
|
98
69
|
// Fall back to alias-only for legacy hubs.
|
|
99
70
|
const sseLookup = (s: { alias: string; network_id?: string }) =>
|
|
100
71
|
(s.network_id ? sseSessions[`${s.network_id}:${s.alias}`] : undefined) ?? sseSessions[s.alias];
|
|
101
|
-
//
|
|
102
|
-
|
|
72
|
+
// #214 F2: online = SSE-reachable ("can I talk to it right now").
|
|
73
|
+
// The old definition (status !== 'offline' OR sse) inflated the count
|
|
74
|
+
// with stale hub statuses and disagreed with /admin and /nodes, which
|
|
75
|
+
// both count pure SSE — and a "online" card you can't chat with
|
|
76
|
+
// contradicts the M2 tap-to-chat model. One definition everywhere.
|
|
77
|
+
const isOnline = (s: { alias: string; status: string; network_id?: string }) => !!sseLookup(s);
|
|
103
78
|
const online = sessions.filter(isOnline).length;
|
|
104
79
|
const total = sessions.length;
|
|
105
80
|
const working = sessions.filter(s => s.status === 'working').length;
|
|
106
|
-
const uptime = health ? formatUptime(health.uptime) : '--';
|
|
107
|
-
const version = health?.version || '--';
|
|
108
|
-
const configHealthy = Boolean(anetConfig?.hub && anetConfig.tokenConfigured);
|
|
109
|
-
const configSourceLabel =
|
|
110
|
-
anetConfig?.source === 'file' ? 'Local config'
|
|
111
|
-
: anetConfig?.source === 'runtime-env' ? 'Runtime env'
|
|
112
|
-
: 'Config missing';
|
|
113
|
-
|
|
114
81
|
// Task stats: prefer /api/stats, fallback to manual
|
|
115
82
|
const taskStats: Record<string, number> = {};
|
|
116
83
|
if (stats?.tasks?.by_status?.length) {
|
|
@@ -132,233 +99,37 @@ export default function Dashboard() {
|
|
|
132
99
|
return bWorking - aWorking;
|
|
133
100
|
});
|
|
134
101
|
|
|
135
|
-
/** Round 70: when the fleet is empty, the Overview reorders to lead with
|
|
136
|
-
* the "Spin up your first agent" CTA and hides the Quick Navigation /
|
|
137
|
-
* Nav rail / Broadcast bar that would otherwise occupy prime real estate
|
|
138
|
-
* with zeros and dead-end links. Computed once, used as a gate below. */
|
|
139
|
-
const fleetEmpty = sessions.length === 0 && !sessError;
|
|
140
|
-
|
|
141
102
|
return (
|
|
142
|
-
<div className="min-h-screen bg-[#
|
|
143
|
-
<
|
|
144
|
-
<StatsBar online={online} working={working} total={total} version={version} uptime={uptime} />
|
|
145
|
-
</div>
|
|
103
|
+
<div className="min-h-screen bg-[#0b0b0d] text-gray-100 p-4 sm:p-6">
|
|
104
|
+
<StatsBar online={online} working={working} total={total} />
|
|
146
105
|
|
|
147
|
-
{/*
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
className="px-4 py-2 bg-gradient-to-r from-cyan-600 to-blue-600 hover:from-cyan-500 hover:to-blue-500 text-white text-sm font-medium rounded-xl shadow-lg shadow-cyan-500/10 transition-all active:scale-95 shrink-0">
|
|
153
|
-
⚡ Dispatch
|
|
154
|
-
</button>
|
|
155
|
-
)}
|
|
156
|
-
<div className="flex-1"><UserBar /></div>
|
|
157
|
-
</div>
|
|
106
|
+
{/* #217 S5 (Vincent: "极简极简,这些都可以放到设置里面去"): the
|
|
107
|
+
Dispatch button and UserBar row are gone from Overview.
|
|
108
|
+
Dispatch lives in /admin (Send Task panel); sign-out lives in
|
|
109
|
+
Settings and the sidebar; network switching lives in the
|
|
110
|
+
sidebar. */}
|
|
158
111
|
|
|
159
|
-
{/*
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
<span className="uppercase text-gray-600">Config</span>
|
|
164
|
-
<span className={`w-2 h-2 rounded-full ${configHealthy ? 'bg-green-400' : 'bg-red-400'}`} />
|
|
165
|
-
<span className="text-gray-500">{configSourceLabel}</span>
|
|
166
|
-
</div>
|
|
167
|
-
<svg className={`w-4 h-4 text-gray-600 transition-transform ${showConfig ? 'rotate-180' : ''}`} fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
|
|
168
|
-
<path strokeLinecap="round" strokeLinejoin="round" d="M19 9l-7 7-7-7" />
|
|
169
|
-
</svg>
|
|
170
|
-
</button>
|
|
171
|
-
{showConfig && (
|
|
172
|
-
<div className="mt-3 pt-3 border-t border-[#2a2a4a]">
|
|
173
|
-
<div className="flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between">
|
|
174
|
-
<div className="min-w-0">
|
|
175
|
-
<div className="text-gray-100 truncate text-sm" title={anetConfig?.hub || undefined}>
|
|
176
|
-
Hub: <span className={anetConfig?.hub ? 'text-cyan-300' : 'text-red-300'}>{anetConfig?.hub?.trim() || 'not configured'}</span>
|
|
177
|
-
</div>
|
|
178
|
-
</div>
|
|
179
|
-
<div className="flex flex-wrap gap-2 text-xs">
|
|
180
|
-
<span className={`px-2.5 py-1 rounded-md border ${anetConfig?.tokenConfigured ? 'bg-blue-500/5 text-blue-300 border-blue-500/20' : 'bg-gray-500/5 text-gray-400 border-gray-500/20'}`}>
|
|
181
|
-
Token: {anetConfig?.tokenPreview || 'not configured'}
|
|
182
|
-
</span>
|
|
183
|
-
</div>
|
|
184
|
-
</div>
|
|
185
|
-
{anetConfig?.error && <div className="mt-2 text-xs text-gray-600">{anetConfig.error}</div>}
|
|
186
|
-
</div>
|
|
187
|
-
)}
|
|
188
|
-
</section>
|
|
189
|
-
|
|
190
|
-
{/* Task Status Stats */}
|
|
112
|
+
{/* Task summary. #217 S5 (Vincent: "乱七八糟的东西太多"): the
|
|
113
|
+
9-status colored chip wall is now a single quiet line — the
|
|
114
|
+
only two numbers that drive action are running and failed;
|
|
115
|
+
everything else lives on /tasks. */}
|
|
191
116
|
{Object.keys(taskStats).length > 0 && (
|
|
192
|
-
<section className="mb-6 rounded-lg border border-[#
|
|
193
|
-
<div className="
|
|
194
|
-
<
|
|
195
|
-
<
|
|
196
|
-
|
|
197
|
-
<div className="flex flex-wrap gap-2">
|
|
198
|
-
{/* Round 69: order is "hot first" — active flow before terminal
|
|
199
|
-
states — intentionally different from the lifecycle order on
|
|
200
|
-
/tasks. Colors come from shared STATUS_CHIP_CLASS so a
|
|
201
|
-
palette tweak in app/lib/status.ts updates here too.
|
|
202
|
-
'created' added in r69 (was missing — enum-coverage bug). */}
|
|
203
|
-
{(['running', 'delivered', 'acked', 'replied', 'created', 'failed', 'cancelled', 'expired', 'closed'] as const)
|
|
204
|
-
.filter((key) => taskStats[key])
|
|
205
|
-
.map((key) => (
|
|
206
|
-
<Link key={key} href={`/tasks?status=${key}`} prefetch={false} className={`px-2.5 py-1 rounded-md border text-xs ${STATUS_CHIP_CLASS[key]} hover:opacity-80 transition-opacity`}>
|
|
207
|
-
{key}: {taskStats[key]}
|
|
208
|
-
</Link>
|
|
209
|
-
))}
|
|
117
|
+
<section className="mb-4 sm:mb-6 flex items-center justify-between rounded-lg border border-[#26262b] bg-[#161618] px-4 py-2.5 text-xs">
|
|
118
|
+
<div className="text-gray-400 tabular-nums">
|
|
119
|
+
<span className={taskStats['running'] ? 'text-green-400' : 'text-gray-500'}>{taskStats['running'] || 0} running</span>
|
|
120
|
+
<span className="text-gray-600"> · </span>
|
|
121
|
+
<span className={taskStats['failed'] ? 'text-red-400' : 'text-gray-500'}>{taskStats['failed'] || 0} failed</span>
|
|
210
122
|
</div>
|
|
123
|
+
<Link href="/tasks" prefetch={false} className="text-cyan-400 hover:text-cyan-300">View all →</Link>
|
|
211
124
|
</section>
|
|
212
125
|
)}
|
|
213
126
|
|
|
214
|
-
{/*
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
Activity block is hidden when the fleet is empty so the
|
|
221
|
-
onboarding CTA gets the page above the fold. */}
|
|
222
|
-
{!fleetEmpty && <>
|
|
223
|
-
<div className="text-[10px] uppercase tracking-[0.12em] text-gray-600 mb-2">Quick navigation</div>
|
|
224
|
-
<section className="mb-3 grid grid-cols-3 gap-2 sm:gap-3">
|
|
225
|
-
{(() => {
|
|
226
|
-
// Build breakdown popover content per card. Pure data — pure CSS
|
|
227
|
-
// popover (no JS state) wires the hover-show transition below.
|
|
228
|
-
const idleCount = sessions.filter(s => isOnline(s) && s.status !== 'working').length;
|
|
229
|
-
const offlineCount = total - online;
|
|
230
|
-
const orderedStatuses = ['running', 'replied', 'failed', 'cancelled', 'expired', 'closed', 'created', 'delivered', 'acked'];
|
|
231
|
-
const failedRecent = tasks.filter((t: { status: string }) => t.status === 'failed').length;
|
|
232
|
-
|
|
233
|
-
const cards = [
|
|
234
|
-
{
|
|
235
|
-
href: '/nodes', label: 'Nodes',
|
|
236
|
-
value: `${online}/${total}`,
|
|
237
|
-
sub: `${total > 0 ? Math.round((online / total) * 100) : 0}% online`,
|
|
238
|
-
color: 'text-green-400 border-green-500/20',
|
|
239
|
-
popover: total === 0 ? null : [
|
|
240
|
-
{ k: 'working', v: working, dot: '', color: '#4ade80' },
|
|
241
|
-
{ k: 'idle', v: idleCount, dot: '', color: '#22d3ee' },
|
|
242
|
-
{ k: 'offline', v: offlineCount, dot: '', color: '#9ca3af' },
|
|
243
|
-
],
|
|
244
|
-
},
|
|
245
|
-
{
|
|
246
|
-
href: '/tasks', label: 'Tasks',
|
|
247
|
-
value: String(Object.values(taskStats).reduce((a, b) => a + b, 0) || 0),
|
|
248
|
-
sub: 'all-time',
|
|
249
|
-
color: 'text-cyan-400 border-cyan-500/20',
|
|
250
|
-
popover: Object.keys(taskStats).length === 0 ? null
|
|
251
|
-
: orderedStatuses
|
|
252
|
-
.filter(s => taskStats[s])
|
|
253
|
-
.map(s => {
|
|
254
|
-
// Inline hex avoids Tailwind purging dynamic
|
|
255
|
-
// `bg-${color}-400` class names.
|
|
256
|
-
const hex = ({
|
|
257
|
-
running: '#4ade80', replied: '#a78bfa', failed: '#f87171',
|
|
258
|
-
cancelled: '#facc15', expired: '#fb923c', closed: '#9ca3af',
|
|
259
|
-
created: '#9ca3af', delivered: '#60a5fa', acked: '#22d3ee',
|
|
260
|
-
} as Record<string, string>)[s] || '#9ca3af';
|
|
261
|
-
return { k: s, v: taskStats[s], dot: '', color: hex };
|
|
262
|
-
}),
|
|
263
|
-
},
|
|
264
|
-
{
|
|
265
|
-
href: '/tasks?status=failed', label: 'Failed',
|
|
266
|
-
value: String(taskStats['failed'] || 0),
|
|
267
|
-
sub: taskStats['failed'] ? 'needs review' : 'none',
|
|
268
|
-
color: taskStats['failed'] ? 'text-red-400 border-red-500/25' : 'text-gray-500 border-gray-700/30',
|
|
269
|
-
popover: !failedRecent ? [{ k: 'no failures yet', v: '', dot: '', color: '#4b5563' }]
|
|
270
|
-
: [{ k: `${failedRecent} in current view`, v: '', dot: '', color: '#f87171' }],
|
|
271
|
-
},
|
|
272
|
-
];
|
|
273
|
-
|
|
274
|
-
return cards.map(a => (
|
|
275
|
-
<Link
|
|
276
|
-
key={a.href}
|
|
277
|
-
href={a.href}
|
|
278
|
-
prefetch={false}
|
|
279
|
-
className={`anet-stat-link group relative rounded-xl border ${a.color} bg-[#111128] px-3 py-3 transition-all hover:-translate-y-px`}
|
|
280
|
-
>
|
|
281
|
-
<div className="flex items-baseline justify-between">
|
|
282
|
-
<div className={`text-xl font-semibold tabular-nums ${a.color.split(' ')[0]}`}>{a.value}</div>
|
|
283
|
-
<div className="hidden sm:block text-[10px] text-gray-600 group-hover:text-gray-400 transition-colors">View →</div>
|
|
284
|
-
</div>
|
|
285
|
-
<div className="text-[11px] text-gray-400 mt-0.5">{a.label}</div>
|
|
286
|
-
<div className="text-[10px] text-gray-600 mt-px">{a.sub}</div>
|
|
287
|
-
|
|
288
|
-
{/* Hover popover — CSS-only, restrained. Hidden on touch
|
|
289
|
-
(no :hover) so mobile is unaffected. Positioned just
|
|
290
|
-
below the card so it doesn't fight nav rail. */}
|
|
291
|
-
{a.popover && a.popover.length > 0 && (
|
|
292
|
-
<div className="anet-stat-popover hidden md:block pointer-events-none absolute left-2 right-2 top-full mt-1 z-20 rounded-lg border border-[#2a2a4a] bg-[#0d0d1a] shadow-lg shadow-black/30 px-3 py-2 opacity-0 translate-y-[-2px] group-hover:opacity-100 group-hover:translate-y-0 transition-all duration-150 delay-100">
|
|
293
|
-
<div className="text-[10px] text-gray-600 uppercase tracking-wider mb-1.5">Breakdown</div>
|
|
294
|
-
<ul className="space-y-1">
|
|
295
|
-
{a.popover.map(row => (
|
|
296
|
-
<li key={row.k} className="flex items-center gap-2 text-[11px]">
|
|
297
|
-
<span
|
|
298
|
-
className="inline-block w-1.5 h-1.5 rounded-full shrink-0"
|
|
299
|
-
style={{ backgroundColor: row.color }}
|
|
300
|
-
aria-hidden
|
|
301
|
-
/>
|
|
302
|
-
<span className="text-gray-400 capitalize">{row.k}</span>
|
|
303
|
-
{row.v !== '' && <span className="ml-auto text-gray-300 tabular-nums font-medium">{row.v}</span>}
|
|
304
|
-
</li>
|
|
305
|
-
))}
|
|
306
|
-
</ul>
|
|
307
|
-
</div>
|
|
308
|
-
)}
|
|
309
|
-
</Link>
|
|
310
|
-
));
|
|
311
|
-
})()}
|
|
312
|
-
</section>
|
|
313
|
-
|
|
314
|
-
{/* Nav rail — pure navigation, icon + label, no data */}
|
|
315
|
-
<section className="mb-6 grid grid-cols-3 gap-2 sm:gap-3">
|
|
316
|
-
{[
|
|
317
|
-
{ href: '/messages', label: 'Messages', icon: 'M21 11.5a8.38 8.38 0 0 1-.9 3.8 8.5 8.5 0 0 1-7.6 4.7 8.38 8.38 0 0 1-3.8-.9L3 21l1.9-5.7a8.38 8.38 0 0 1-.9-3.8 8.5 8.5 0 0 1 4.7-7.6 8.38 8.38 0 0 1 3.8-.9h.5a8.48 8.48 0 0 1 8 8v.5z' },
|
|
318
|
-
{ href: '/logs', label: 'Audit log', icon: 'M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z M14 2v6h6 M16 13H8 M16 17H8 M10 9H8' },
|
|
319
|
-
{ href: '/admin', label: 'Admin', icon: 'M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4z M6 21v-2a4 4 0 0 1 4-4h4a4 4 0 0 1 4 4v2' },
|
|
320
|
-
].map(a => (
|
|
321
|
-
<Link key={a.href} href={a.href} prefetch={false}
|
|
322
|
-
className="anet-nav-tile flex items-center justify-center gap-2 rounded-xl border border-[#2a2a4a] bg-[#111128] px-3 py-2.5 text-[12px] text-gray-400 hover:text-gray-200 transition-colors">
|
|
323
|
-
<svg className="w-4 h-4 shrink-0" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round">
|
|
324
|
-
<path d={a.icon} />
|
|
325
|
-
</svg>
|
|
326
|
-
<span>{a.label}</span>
|
|
327
|
-
</Link>
|
|
328
|
-
))}
|
|
329
|
-
</section>
|
|
330
|
-
|
|
331
|
-
<BroadcastBar />
|
|
332
|
-
|
|
333
|
-
{/* Recent Activity */}
|
|
334
|
-
{tasks.length > 0 && (
|
|
335
|
-
<section className="mb-6 bg-[#111128] border border-[#2a2a4a] rounded-xl p-4">
|
|
336
|
-
<div className="flex items-center justify-between mb-3">
|
|
337
|
-
<h2 className="text-sm font-semibold text-gray-300">Recent Activity</h2>
|
|
338
|
-
<Link href="/tasks" className="text-xs text-cyan-400 hover:text-cyan-300">All tasks →</Link>
|
|
339
|
-
</div>
|
|
340
|
-
<div className="space-y-2 max-h-40 overflow-y-auto">
|
|
341
|
-
{tasks.slice(0, 5).map((t: { task_id: string; from_name: string; to_name: string; status: string; content: string; created_at: string }) => (
|
|
342
|
-
<div key={t.task_id} className="flex items-center gap-2 text-xs">
|
|
343
|
-
<span
|
|
344
|
-
className="w-1.5 h-1.5 rounded-full shrink-0"
|
|
345
|
-
style={{ backgroundColor: STATUS_DOT_HEX[t.status] || '#6b7280' }}
|
|
346
|
-
/>
|
|
347
|
-
{t.from_name && <AliasAvatar alias={t.from_name} size={14} />}
|
|
348
|
-
<span className="text-gray-300 shrink-0 max-w-[20%] truncate">{t.from_name || '?'}</span>
|
|
349
|
-
<span className="text-gray-600">→</span>
|
|
350
|
-
{t.to_name && <AliasAvatar alias={t.to_name} size={14} />}
|
|
351
|
-
<span className="text-gray-300 shrink-0 max-w-[20%] truncate">{t.to_name || '?'}</span>
|
|
352
|
-
<span className="text-gray-500 truncate flex-1" title={t.content || ''}>{previewContent(t.content).slice(0, 60)}</span>
|
|
353
|
-
<span className={`shrink-0 px-1.5 py-0.5 rounded text-[10px] border ${
|
|
354
|
-
STATUS_CHIP_CLASS[t.status] || 'text-gray-500 border-gray-700/30'
|
|
355
|
-
}`}>{t.status}</span>
|
|
356
|
-
</div>
|
|
357
|
-
))}
|
|
358
|
-
</div>
|
|
359
|
-
</section>
|
|
360
|
-
)}
|
|
361
|
-
</>}
|
|
127
|
+
{/* #217 S5 (less is more): Quick Navigation stat cards, the nav
|
|
128
|
+
rail, and Recent Activity are deleted. Every route they linked
|
|
129
|
+
to is one tap away in the bottom tab bar (mobile) or sidebar
|
|
130
|
+
(desktop), the headline numbers already live in the KPI cards
|
|
131
|
+
and the task summary line, and recent tasks live on /tasks.
|
|
132
|
+
Restore path: git revert this commit. */}
|
|
362
133
|
|
|
363
134
|
{sessError && (
|
|
364
135
|
<div className="bg-red-900/20 border border-red-800/40 text-red-300 px-4 py-3 rounded-lg mb-6 text-sm flex items-center justify-between" role="alert">
|
|
@@ -367,8 +138,12 @@ export default function Dashboard() {
|
|
|
367
138
|
</div>
|
|
368
139
|
)}
|
|
369
140
|
|
|
141
|
+
{/* #217 M1: topology toggle is lg-only — on a 390px phone the
|
|
142
|
+
graph needed a 70vh cap (R41) just to stay scrollable, i.e.
|
|
143
|
+
it never really worked there. Desktop keeps the full feature;
|
|
144
|
+
mobile Overview loses its last piece of chrome. */}
|
|
370
145
|
{sessions.length > 0 && (
|
|
371
|
-
<div className="flex justify-center mb-4">
|
|
146
|
+
<div className="hidden lg:flex justify-center mb-4">
|
|
372
147
|
<button
|
|
373
148
|
onClick={() => setShowTopo(!showTopo)}
|
|
374
149
|
className="text-xs text-gray-500 hover:text-gray-300 border border-gray-700/50 px-4 py-1.5 rounded-lg transition-colors hover:border-gray-600 cursor-pointer"
|
|
@@ -378,15 +153,21 @@ export default function Dashboard() {
|
|
|
378
153
|
</div>
|
|
379
154
|
)}
|
|
380
155
|
|
|
381
|
-
{
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
156
|
+
{showTopo && sessions.length > 0 && (
|
|
157
|
+
// #209 R41: mobile-only soft cap on the rendered TopoGraph.
|
|
158
|
+
// Default behaviour on desktop is unchanged (lg: drops the cap
|
|
159
|
+
// entirely). On phones the SVG card was free to claim ~600+ px
|
|
160
|
+
// of vertical real-estate, which on a 667-844 px viewport meant
|
|
161
|
+
// tapping "Show Topology" pushed the agent grid completely off
|
|
162
|
+
// screen. Capping to 70 vh with overflow-y-auto keeps the graph
|
|
163
|
+
// interactive (the SVG already does its own pan + zoom inside
|
|
164
|
+
// the viewport) while letting the page below stay reachable
|
|
165
|
+
// with a single ordinary scroll past the cap.
|
|
166
|
+
<div className="lg:max-h-none lg:overflow-visible max-h-[70vh] overflow-y-auto rounded-xl border border-transparent lg:border-0">
|
|
167
|
+
<TopoGraph sessions={sessions} sseSessions={sseSessions} renameSignal={renameSignal} />
|
|
385
168
|
</div>
|
|
386
169
|
)}
|
|
387
170
|
|
|
388
|
-
{showTopo && sessions.length > 0 && <TopoGraph sessions={sessions} sseSessions={sseSessions} renameSignal={renameSignal} />}
|
|
389
|
-
|
|
390
171
|
{sessions.length === 0 && !sessError ? (
|
|
391
172
|
<EmptyState
|
|
392
173
|
hint={sessHint}
|
|
@@ -426,12 +207,14 @@ export default function Dashboard() {
|
|
|
426
207
|
className={`flex items-center gap-1.5 rounded-md px-2.5 py-1 text-xs transition-colors disabled:opacity-30 disabled:cursor-not-allowed ${
|
|
427
208
|
agentFilter === c.key
|
|
428
209
|
? 'bg-cyan-500/10 text-cyan-300 border border-cyan-500/30'
|
|
429
|
-
: 'text-gray-500 hover:text-gray-200 hover:bg-[#
|
|
210
|
+
: 'text-gray-500 hover:text-gray-200 hover:bg-[#1c1c1f] border border-transparent'
|
|
430
211
|
}`}
|
|
431
212
|
>
|
|
432
213
|
{c.dot && <span aria-hidden className="inline-block w-1.5 h-1.5 rounded-full" style={{ backgroundColor: c.dot }} />}
|
|
214
|
+
{/* #217 D5: counts dropped — the KPI cards directly above
|
|
215
|
+
already carry 53/100/153; repeating them here doubled
|
|
216
|
+
every number on the first screen. */}
|
|
433
217
|
<span>{c.label}</span>
|
|
434
|
-
<span className={`text-[10px] tabular-nums ${agentFilter === c.key ? 'text-cyan-400' : 'text-gray-600'}`}>{counts[c.key]}</span>
|
|
435
218
|
</button>
|
|
436
219
|
))}
|
|
437
220
|
</div>
|
|
@@ -454,8 +237,6 @@ export default function Dashboard() {
|
|
|
454
237
|
);
|
|
455
238
|
})()}
|
|
456
239
|
|
|
457
|
-
<InboxPanel messages={inbox} />
|
|
458
|
-
|
|
459
240
|
{/* Round 111 (issue #82): dropped the license badge — "trial (12d
|
|
460
241
|
left)" read like a paywall countdown on an open-source dashboard
|
|
461
242
|
and Vincent flagged it as misleading more than once. The SSE /
|
|
@@ -470,9 +251,6 @@ export default function Dashboard() {
|
|
|
470
251
|
)}
|
|
471
252
|
</div>
|
|
472
253
|
|
|
473
|
-
{/* Dispatch Panel */}
|
|
474
|
-
{showDispatch && <DispatchPanel sessions={sessions} onClose={() => setShowDispatch(false)} />}
|
|
475
|
-
|
|
476
254
|
{/* Command Center (multi-tab chat) */}
|
|
477
255
|
{cmd.tabs.length > 0 && (
|
|
478
256
|
<CommandCenter
|
package/app/server-logs/page.tsx
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
3
|
import { useState, useEffect, useRef, useCallback } from 'react';
|
|
4
|
+
import { useCollapsibleSearch } from '@/app/components/CollapsibleSearch';
|
|
4
5
|
import Link from 'next/link';
|
|
5
6
|
|
|
6
7
|
interface LogLine {
|
|
@@ -63,6 +64,16 @@ export default function ServerLogsPage() {
|
|
|
63
64
|
const [filterLevel, setFilterLevel] = useState<'all' | LogLine['level']>('all');
|
|
64
65
|
const [search, setSearch] = useState('');
|
|
65
66
|
const [autoRefresh, setAutoRefresh] = useState(true);
|
|
67
|
+
// #209 R35: adopt the shared CollapsibleSearch hook (R34) so the
|
|
68
|
+
// inline 全宽 search input collapses behind a magnifier circle in
|
|
69
|
+
// the toolbar — same WeChat-style affordance as /nodes /messages.
|
|
70
|
+
const searchCtl = useCollapsibleSearch({
|
|
71
|
+
value: search,
|
|
72
|
+
onChange: setSearch,
|
|
73
|
+
placeholder: '搜索关键字 (alias / task_id / error message)',
|
|
74
|
+
label: 'Search logs',
|
|
75
|
+
enabled: true,
|
|
76
|
+
});
|
|
66
77
|
const lastTsRef = useRef<string>('');
|
|
67
78
|
|
|
68
79
|
const fetchLogs = useCallback(async (initial = false) => {
|
|
@@ -116,10 +127,17 @@ export default function ServerLogsPage() {
|
|
|
116
127
|
for (const l of logs) counts[l.level]++;
|
|
117
128
|
|
|
118
129
|
return (
|
|
119
|
-
|
|
130
|
+
// #209 R35: p-6 → p-4 sm:p-6 mobile-tighten (matches /tasks, /nodes,
|
|
131
|
+
// /messages, /overview convention). Saves 16 px of L/R padding on phones.
|
|
132
|
+
<div className="p-4 sm:p-6 max-w-[1600px] mx-auto">
|
|
120
133
|
<div className="flex items-center justify-between mb-4 gap-3">
|
|
121
134
|
<div className="flex items-center gap-3 min-w-0">
|
|
122
|
-
|
|
135
|
+
{/* #209 R35: lg:ml-0 ml-10 burger-clearance — without it the
|
|
136
|
+
fixed top-3 left-3 mobile hamburger sat right on top of the
|
|
137
|
+
"Se" of "Server Logs". Caught by playwright mobile shot. */}
|
|
138
|
+
{/* #217 D8: text-xl + nowrap on phones — at text-2xl the title
|
|
139
|
+
wrapped to two lines under the 4-control toolbar. */}
|
|
140
|
+
<h1 className="text-xl sm:text-2xl font-bold text-white lg:ml-0 ml-10 whitespace-nowrap">Server Logs</h1>
|
|
123
141
|
{/* Round 86: dropped the {logs.length} header chip — r84 added
|
|
124
142
|
`all <count>` to the filter strip just below, so this duplicated
|
|
125
143
|
the value within 40px of itself. */}
|
|
@@ -158,9 +176,17 @@ export default function ServerLogsPage() {
|
|
|
158
176
|
</svg>
|
|
159
177
|
<span className="hidden sm:inline">Reload</span>
|
|
160
178
|
</button>
|
|
179
|
+
{/* #209 R35: magnifier-toggle search (WeChat-style, via the
|
|
180
|
+
shared CollapsibleSearch hook). Lives at the tail of the
|
|
181
|
+
toolbar so it sits at the right edge of the header. */}
|
|
182
|
+
<searchCtl.Button />
|
|
161
183
|
</div>
|
|
162
184
|
</div>
|
|
163
185
|
|
|
186
|
+
{/* R35: collapsible search row — sits above the filter chip strip
|
|
187
|
+
so toggling it doesn't shift the chip layout. */}
|
|
188
|
+
<searchCtl.Row />
|
|
189
|
+
|
|
164
190
|
{/* Round 95: flex-wrap + min-w-0 on the search wrapper so the
|
|
165
191
|
search input drops below the chip strip on mobile instead of
|
|
166
192
|
overflowing past the viewport. Desktop layout (single row)
|
|
@@ -183,7 +209,7 @@ export default function ServerLogsPage() {
|
|
|
183
209
|
className={`px-2.5 py-1 rounded border flex items-center gap-1 disabled:opacity-30 disabled:cursor-not-allowed ${
|
|
184
210
|
isActive
|
|
185
211
|
? 'bg-cyan-500/15 text-cyan-200 border-cyan-500/40'
|
|
186
|
-
: 'bg-[#
|
|
212
|
+
: 'bg-[#161618] text-gray-400 border-[#26262b] hover:bg-[#1c1c1f]'
|
|
187
213
|
}`}
|
|
188
214
|
>
|
|
189
215
|
<span>{lv}</span>
|
|
@@ -192,15 +218,15 @@ export default function ServerLogsPage() {
|
|
|
192
218
|
);
|
|
193
219
|
})}
|
|
194
220
|
</div>
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
221
|
+
{/* #217 D8 (same rule as the D6 /tasks chip): the counter only
|
|
222
|
+
renders when it carries unique info — a filter or search is
|
|
223
|
+
actually narrowing the list. "500 / 500" duplicated the
|
|
224
|
+
`all 500` chip 20px to its left. */}
|
|
225
|
+
{filtered.length < logs.length && (
|
|
226
|
+
<span className="text-[10px] text-gray-600 ml-auto tabular-nums">
|
|
227
|
+
{filtered.length} / {logs.length}
|
|
228
|
+
</span>
|
|
229
|
+
)}
|
|
204
230
|
</div>
|
|
205
231
|
|
|
206
232
|
{error && (() => {
|
|
@@ -235,7 +261,7 @@ export default function ServerLogsPage() {
|
|
|
235
261
|
);
|
|
236
262
|
})()}
|
|
237
263
|
|
|
238
|
-
<div className="rounded border border-[#
|
|
264
|
+
<div className="rounded border border-[#1c1c1f] bg-[#060607] font-mono text-[11px] leading-relaxed overflow-hidden">
|
|
239
265
|
{filtered.length === 0 ? (
|
|
240
266
|
<div className="p-8 text-center text-gray-600">
|
|
241
267
|
{error ? '加载失败' : logs.length === 0 ? '加载中...' : '没有匹配的日志'}
|
|
@@ -243,7 +269,7 @@ export default function ServerLogsPage() {
|
|
|
243
269
|
) : (
|
|
244
270
|
<div className="divide-y divide-[#0d0d18] max-h-[calc(100vh-260px)] overflow-y-auto">
|
|
245
271
|
{filtered.map((l, i) => (
|
|
246
|
-
<div key={`${l.ts}-${i}`} className="relative pl-3 pr-3 py-1 hover:bg-[#
|
|
272
|
+
<div key={`${l.ts}-${i}`} className="relative pl-3 pr-3 py-1 hover:bg-[#0e0e10] flex gap-3">
|
|
247
273
|
{/* Round 32: 2px left rail keyed to level. Makes warn/error
|
|
248
274
|
spike visible in a wall of `log` lines without users having
|
|
249
275
|
to read the level chip on every row. */}
|
package/app/servers/page.tsx
CHANGED
|
@@ -4,24 +4,45 @@ import { ServersPanel } from '../components/ServersDrawer';
|
|
|
4
4
|
|
|
5
5
|
export default function ServersPage() {
|
|
6
6
|
return (
|
|
7
|
-
<main className="min-h-screen bg-[#
|
|
7
|
+
<main className="min-h-screen bg-[#0b0b0d] px-4 py-5 text-gray-100 sm:px-6 lg:px-8">
|
|
8
8
|
<div className="mx-auto max-w-5xl space-y-5">
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
9
|
+
{/* #209 R37: header card compressed for mobile. Original layout
|
|
10
|
+
stacked 4 things vertically on phones (INFRASTRUCTURE eyebrow,
|
|
11
|
+
big h1, 3-line description, full-width "live" chip) eating
|
|
12
|
+
~50% of the iPhone viewport before any server card appeared.
|
|
13
|
+
New shape:
|
|
14
|
+
row 1: h1 "Servers" + tiny live chip (inline on every width)
|
|
15
|
+
row 2: optional desc line, single-truncate on mobile so it
|
|
16
|
+
fits without wrapping; full text via title= on hover.
|
|
17
|
+
eyebrow: kept but inlined with h1 as small uppercase prefix
|
|
18
|
+
(sm: up) — drops out on phones for density.
|
|
19
|
+
p-5 → p-4 sm:p-5 also tightens the inner padding.
|
|
20
|
+
Zero feature removed; the eyebrow + desc still render where
|
|
21
|
+
there is room. */}
|
|
22
|
+
<header className="rounded-2xl border border-[#26262b] bg-[#161618] p-4 sm:p-5 shadow-lg shadow-black/20">
|
|
23
|
+
<div className="flex items-center justify-between gap-3 lg:ml-0 ml-10">
|
|
24
|
+
<div className="flex items-baseline gap-2 min-w-0">
|
|
25
|
+
<span className="hidden sm:inline text-[11px] uppercase tracking-[0.18em] text-cyan-300/70 shrink-0">
|
|
26
|
+
Infrastructure
|
|
27
|
+
</span>
|
|
28
|
+
<span className="hidden sm:inline text-gray-700">·</span>
|
|
29
|
+
<h1 className="text-xl sm:text-2xl font-semibold text-white truncate">Servers</h1>
|
|
17
30
|
</div>
|
|
18
|
-
<div className="rounded-
|
|
19
|
-
|
|
31
|
+
<div className="shrink-0 rounded-full border border-cyan-500/20 bg-cyan-500/10 px-2.5 py-1 text-[11px] font-mono text-cyan-200 inline-flex items-center gap-1.5">
|
|
32
|
+
<span aria-hidden className="inline-block w-1.5 h-1.5 rounded-full bg-cyan-400 animate-pulse" />
|
|
33
|
+
<span className="hidden sm:inline">live · refreshes every 5s</span>
|
|
34
|
+
<span className="sm:hidden">live</span>
|
|
20
35
|
</div>
|
|
21
36
|
</div>
|
|
37
|
+
<p
|
|
38
|
+
className="mt-2 max-w-2xl text-xs sm:text-sm leading-snug sm:leading-6 text-gray-400 truncate sm:whitespace-normal lg:ml-0 ml-10"
|
|
39
|
+
title="Host-level health, disk, memory, CPU history, and agent rollups from CommHub telemetry."
|
|
40
|
+
>
|
|
41
|
+
Host-level health, disk, memory, CPU history, and agent rollups from CommHub telemetry.
|
|
42
|
+
</p>
|
|
22
43
|
</header>
|
|
23
44
|
|
|
24
|
-
<section className="rounded-2xl border border-[#
|
|
45
|
+
<section className="rounded-2xl border border-[#26262b] bg-[#161618] p-3 shadow-lg shadow-black/20">
|
|
25
46
|
<ServersPanel className="max-h-none overflow-visible" />
|
|
26
47
|
</section>
|
|
27
48
|
</div>
|