@sleep2agi/agent-network-dashboard 0.6.3-preview.1 → 0.6.3-preview.10
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_COMMIT +1 -1
- package/.next/BUILD_ID +1 -1
- package/.next/app-path-routes-manifest.json +5 -0
- package/.next/build-manifest.json +3 -3
- package/.next/cache/.previewinfo +1 -0
- package/.next/cache/.rscinfo +1 -0
- package/.next/diagnostics/route-bundle-stats.json +56 -39
- package/.next/fallback-build-manifest.json +3 -3
- package/.next/prerender-manifest.json +27 -3
- package/.next/routes-manifest.json +30 -0
- 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_client-reference-manifest.js +1 -1
- package/.next/server/app/_not-found.html +2 -2
- package/.next/server/app/_not-found.rsc +13 -13
- package/.next/server/app/_not-found.segments/_full.segment.rsc +13 -13
- package/.next/server/app/_not-found.segments/_head.segment.rsc +4 -4
- package/.next/server/app/_not-found.segments/_index.segment.rsc +8 -8
- 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 +2 -2
- package/.next/server/app/admin/page_client-reference-manifest.js +1 -1
- package/.next/server/app/admin.html +2 -2
- package/.next/server/app/admin.rsc +15 -15
- package/.next/server/app/admin.segments/_full.segment.rsc +15 -15
- package/.next/server/app/admin.segments/_head.segment.rsc +4 -4
- package/.next/server/app/admin.segments/_index.segment.rsc +8 -8
- package/.next/server/app/admin.segments/_tree.segment.rsc +2 -2
- 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/api/anet/host-supervisors/route/app-paths-manifest.json +3 -0
- package/.next/server/app/api/anet/host-supervisors/route/build-manifest.json +9 -0
- package/.next/server/app/api/anet/host-supervisors/route/server-reference-manifest.json +4 -0
- package/.next/server/app/api/anet/host-supervisors/route.js +7 -0
- package/.next/server/app/api/anet/host-supervisors/route.js.map +5 -0
- package/.next/server/app/api/anet/host-supervisors/route.js.nft.json +1 -0
- package/.next/server/app/api/anet/host-supervisors/route_client-reference-manifest.js +3 -0
- package/.next/server/app/api/anet/providers/probe/route/app-paths-manifest.json +3 -0
- package/.next/server/app/api/anet/providers/probe/route/build-manifest.json +9 -0
- package/.next/server/app/api/anet/providers/probe/route/server-reference-manifest.json +4 -0
- package/.next/server/app/api/anet/providers/probe/route.js +7 -0
- package/.next/server/app/api/anet/providers/probe/route.js.map +5 -0
- package/.next/server/app/api/anet/providers/probe/route.js.nft.json +1 -0
- package/.next/server/app/api/anet/providers/probe/route_client-reference-manifest.js +3 -0
- package/.next/server/app/api/anet/providers/probe-results/route/app-paths-manifest.json +3 -0
- package/.next/server/app/api/anet/providers/probe-results/route/build-manifest.json +9 -0
- package/.next/server/app/api/anet/providers/probe-results/route/server-reference-manifest.json +4 -0
- package/.next/server/app/api/anet/providers/probe-results/route.js +7 -0
- package/.next/server/app/api/anet/providers/probe-results/route.js.map +5 -0
- package/.next/server/app/api/anet/providers/probe-results/route.js.nft.json +1 -0
- package/.next/server/app/api/anet/providers/probe-results/route_client-reference-manifest.js +3 -0
- package/.next/server/app/api/anet/providers/route/app-paths-manifest.json +3 -0
- package/.next/server/app/api/anet/providers/route/build-manifest.json +9 -0
- package/.next/server/app/api/anet/providers/route/server-reference-manifest.json +4 -0
- package/.next/server/app/api/anet/providers/route.js +8 -0
- package/.next/server/app/api/anet/providers/route.js.map +5 -0
- package/.next/server/app/api/anet/providers/route.js.nft.json +1 -0
- package/.next/server/app/api/anet/providers/route_client-reference-manifest.js +3 -0
- package/.next/server/app/index.html +2 -2
- package/.next/server/app/index.rsc +15 -15
- package/.next/server/app/index.segments/__PAGE__.segment.rsc +4 -4
- package/.next/server/app/index.segments/_full.segment.rsc +15 -15
- package/.next/server/app/index.segments/_head.segment.rsc +4 -4
- package/.next/server/app/index.segments/_index.segment.rsc +8 -8
- package/.next/server/app/index.segments/_tree.segment.rsc +2 -2
- 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 +15 -15
- package/.next/server/app/login.segments/_full.segment.rsc +15 -15
- package/.next/server/app/login.segments/_head.segment.rsc +4 -4
- package/.next/server/app/login.segments/_index.segment.rsc +8 -8
- package/.next/server/app/login.segments/_tree.segment.rsc +2 -2
- 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_client-reference-manifest.js +1 -1
- package/.next/server/app/logs.html +2 -2
- package/.next/server/app/logs.rsc +15 -15
- package/.next/server/app/logs.segments/_full.segment.rsc +15 -15
- package/.next/server/app/logs.segments/_head.segment.rsc +4 -4
- package/.next/server/app/logs.segments/_index.segment.rsc +8 -8
- package/.next/server/app/logs.segments/_tree.segment.rsc +2 -2
- 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/messages/page_client-reference-manifest.js +1 -1
- package/.next/server/app/messages.html +2 -2
- package/.next/server/app/messages.rsc +15 -15
- package/.next/server/app/messages.segments/_full.segment.rsc +15 -15
- package/.next/server/app/messages.segments/_head.segment.rsc +4 -4
- package/.next/server/app/messages.segments/_index.segment.rsc +8 -8
- package/.next/server/app/messages.segments/_tree.segment.rsc +2 -2
- 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_client-reference-manifest.js +1 -1
- package/.next/server/app/node.html +2 -2
- package/.next/server/app/node.rsc +15 -15
- package/.next/server/app/node.segments/_full.segment.rsc +15 -15
- package/.next/server/app/node.segments/_head.segment.rsc +4 -4
- package/.next/server/app/node.segments/_index.segment.rsc +8 -8
- package/.next/server/app/node.segments/_tree.segment.rsc +2 -2
- 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_client-reference-manifest.js +1 -1
- package/.next/server/app/nodes.html +2 -2
- package/.next/server/app/nodes.rsc +15 -15
- package/.next/server/app/nodes.segments/_full.segment.rsc +15 -15
- package/.next/server/app/nodes.segments/_head.segment.rsc +4 -4
- package/.next/server/app/nodes.segments/_index.segment.rsc +8 -8
- package/.next/server/app/nodes.segments/_tree.segment.rsc +2 -2
- 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_client-reference-manifest.js +1 -1
- package/.next/server/app/providers/page/app-paths-manifest.json +3 -0
- package/.next/server/app/providers/page/build-manifest.json +17 -0
- package/.next/server/app/providers/page/next-font-manifest.json +11 -0
- package/.next/server/app/providers/page/react-loadable-manifest.json +1 -0
- package/.next/server/app/providers/page/server-reference-manifest.json +4 -0
- package/.next/server/app/providers/page.js +14 -0
- package/.next/server/app/providers/page.js.map +5 -0
- package/.next/server/app/providers/page.js.nft.json +1 -0
- package/.next/server/app/providers/page_client-reference-manifest.js +3 -0
- package/.next/server/app/providers.html +12 -0
- package/.next/server/app/providers.meta +15 -0
- package/.next/server/app/providers.rsc +27 -0
- package/.next/server/app/providers.segments/_full.segment.rsc +27 -0
- package/.next/server/app/providers.segments/_head.segment.rsc +6 -0
- package/.next/server/app/providers.segments/_index.segment.rsc +10 -0
- package/.next/server/app/providers.segments/_tree.segment.rsc +5 -0
- package/.next/server/app/providers.segments/providers/__PAGE__.segment.rsc +9 -0
- package/.next/server/app/providers.segments/providers.segment.rsc +5 -0
- package/.next/server/app/server-logs/page_client-reference-manifest.js +1 -1
- package/.next/server/app/server-logs.html +2 -2
- package/.next/server/app/server-logs.rsc +15 -15
- package/.next/server/app/server-logs.segments/_full.segment.rsc +15 -15
- package/.next/server/app/server-logs.segments/_head.segment.rsc +4 -4
- package/.next/server/app/server-logs.segments/_index.segment.rsc +8 -8
- package/.next/server/app/server-logs.segments/_tree.segment.rsc +2 -2
- 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_client-reference-manifest.js +1 -1
- package/.next/server/app/servers.html +2 -2
- package/.next/server/app/servers.rsc +15 -15
- package/.next/server/app/servers.segments/_full.segment.rsc +15 -15
- package/.next/server/app/servers.segments/_head.segment.rsc +4 -4
- package/.next/server/app/servers.segments/_index.segment.rsc +8 -8
- package/.next/server/app/servers.segments/_tree.segment.rsc +2 -2
- 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_client-reference-manifest.js +1 -1
- package/.next/server/app/settings/networks.html +2 -2
- package/.next/server/app/settings/networks.rsc +15 -15
- package/.next/server/app/settings/networks.segments/_full.segment.rsc +15 -15
- package/.next/server/app/settings/networks.segments/_head.segment.rsc +4 -4
- package/.next/server/app/settings/networks.segments/_index.segment.rsc +8 -8
- package/.next/server/app/settings/networks.segments/_tree.segment.rsc +2 -2
- 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_client-reference-manifest.js +1 -1
- package/.next/server/app/settings/tokens/page_client-reference-manifest.js +1 -1
- package/.next/server/app/settings/tokens.html +2 -2
- package/.next/server/app/settings/tokens.rsc +15 -15
- package/.next/server/app/settings/tokens.segments/_full.segment.rsc +15 -15
- package/.next/server/app/settings/tokens.segments/_head.segment.rsc +4 -4
- package/.next/server/app/settings/tokens.segments/_index.segment.rsc +8 -8
- package/.next/server/app/settings/tokens.segments/_tree.segment.rsc +2 -2
- 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 +2 -2
- package/.next/server/app/settings.rsc +15 -15
- package/.next/server/app/settings.segments/_full.segment.rsc +15 -15
- package/.next/server/app/settings.segments/_head.segment.rsc +4 -4
- package/.next/server/app/settings.segments/_index.segment.rsc +8 -8
- package/.next/server/app/settings.segments/_tree.segment.rsc +2 -2
- 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_client-reference-manifest.js +1 -1
- package/.next/server/app/tasks/page_client-reference-manifest.js +1 -1
- package/.next/server/app/tasks.html +2 -2
- package/.next/server/app/tasks.rsc +15 -15
- package/.next/server/app/tasks.segments/_full.segment.rsc +15 -15
- package/.next/server/app/tasks.segments/_head.segment.rsc +4 -4
- package/.next/server/app/tasks.segments/_index.segment.rsc +8 -8
- package/.next/server/app/tasks.segments/_tree.segment.rsc +2 -2
- 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 +5 -0
- package/.next/server/chunks/00jm_next_dist_esm_build_templates_app-route_0bobkt3.js +3 -0
- package/.next/server/chunks/00jm_next_dist_esm_build_templates_app-route_0bobkt3.js.map +1 -0
- package/.next/server/chunks/0dk5_next-internal_server_app_api_anet_providers_probe-results_route_actions_07.d.5a.js +3 -0
- package/.next/server/chunks/0dk5_next-internal_server_app_api_anet_providers_probe-results_route_actions_07.d.5a.js.map +1 -0
- package/.next/server/chunks/0ykm__next-internal_server_app_api_anet_host-supervisors_route_actions_0g3hek2.js +3 -0
- package/.next/server/chunks/0ykm__next-internal_server_app_api_anet_host-supervisors_route_actions_0g3hek2.js.map +1 -0
- package/.next/server/chunks/0ykm__next-internal_server_app_api_anet_providers_probe_route_actions_05f000..js +3 -0
- package/.next/server/chunks/0ykm__next-internal_server_app_api_anet_providers_probe_route_actions_05f000..js.map +1 -0
- package/.next/server/chunks/0ykm__next-internal_server_app_api_anet_providers_route_actions_10htbhd.js +3 -0
- package/.next/server/chunks/0ykm__next-internal_server_app_api_anet_providers_route_actions_10htbhd.js.map +1 -0
- package/.next/server/chunks/[root-of-the-server]__0-29ynz._.js.map +1 -1
- package/.next/server/chunks/[root-of-the-server]__0-2le8-._.js.map +1 -1
- package/.next/server/chunks/[root-of-the-server]__0-8_f0o._.js.map +1 -1
- package/.next/server/chunks/[root-of-the-server]__02p2n3n._.js.map +1 -1
- package/.next/server/chunks/[root-of-the-server]__03nze3z._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__03nze3z._.js.map +1 -0
- package/.next/server/chunks/[root-of-the-server]__043tnx2._.js.map +1 -1
- package/.next/server/chunks/[root-of-the-server]__04z62zk._.js.map +1 -1
- package/.next/server/chunks/[root-of-the-server]__07ztet2._.js.map +1 -1
- package/.next/server/chunks/[root-of-the-server]__0aqb4n5._.js +1 -1
- package/.next/server/chunks/[root-of-the-server]__0aqb4n5._.js.map +1 -1
- package/.next/server/chunks/[root-of-the-server]__0cphmer._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__0cphmer._.js.map +1 -0
- package/.next/server/chunks/[root-of-the-server]__0e3ucl1._.js.map +1 -1
- package/.next/server/chunks/[root-of-the-server]__0e6yail._.js.map +1 -1
- package/.next/server/chunks/[root-of-the-server]__0gx2_6a._.js.map +1 -1
- package/.next/server/chunks/[root-of-the-server]__0hg3_8r._.js.map +1 -1
- package/.next/server/chunks/[root-of-the-server]__0lhq4ha._.js.map +1 -1
- package/.next/server/chunks/[root-of-the-server]__0mkwzz7._.js +1 -1
- package/.next/server/chunks/[root-of-the-server]__0mkwzz7._.js.map +1 -1
- package/.next/server/chunks/[root-of-the-server]__0mxw4vb._.js.map +1 -1
- package/.next/server/chunks/[root-of-the-server]__0mzopco._.js.map +1 -1
- package/.next/server/chunks/[root-of-the-server]__0o45a4q._.js.map +1 -1
- package/.next/server/chunks/[root-of-the-server]__0w1w_w0._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__0w1w_w0._.js.map +1 -0
- package/.next/server/chunks/[root-of-the-server]__0xtp-et._.js.map +1 -1
- package/.next/server/chunks/[root-of-the-server]__0yyo7k5._.js +1 -1
- package/.next/server/chunks/[root-of-the-server]__0yyo7k5._.js.map +1 -1
- package/.next/server/chunks/[root-of-the-server]__0~rwgo1._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__0~rwgo1._.js.map +1 -0
- package/.next/server/chunks/[root-of-the-server]__10pvabe._.js.map +1 -1
- package/.next/server/chunks/[root-of-the-server]__10t11zq._.js.map +1 -1
- package/.next/server/chunks/[root-of-the-server]__12r~omy._.js.map +1 -1
- package/.next/server/chunks/[root-of-the-server]__1389~cs._.js.map +1 -1
- package/.next/server/chunks/[root-of-the-server]__13n8t..._.js.map +1 -1
- package/.next/server/chunks/ssr/00jm_next_dist_esm_build_templates_app-page_02lorbl.js +4 -0
- package/.next/server/chunks/ssr/00jm_next_dist_esm_build_templates_app-page_02lorbl.js.map +1 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__030vg4n._.js.map +1 -1
- package/.next/server/chunks/ssr/[root-of-the-server]__04mx~5g._.js +3 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__04mx~5g._.js.map +1 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__05kf31s._.js +1 -1
- package/.next/server/chunks/ssr/[root-of-the-server]__05kf31s._.js.map +1 -1
- package/.next/server/chunks/ssr/[root-of-the-server]__096ytyk._.js.map +1 -1
- 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]__0h5dae6._.js +1 -1
- package/.next/server/chunks/ssr/[root-of-the-server]__0h5dae6._.js.map +1 -1
- 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__next-internal_server_app_providers_page_actions_0ou6p43.js +3 -0
- package/.next/server/chunks/ssr/agent-network-dashboard__next-internal_server_app_providers_page_actions_0ou6p43.js.map +1 -0
- package/.next/server/chunks/ssr/agent-network-dashboard_app_012oyw5._.js +1 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_app_012oyw5._.js.map +1 -1
- 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_0gd.4pc._.js +1 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_app_0gd.4pc._.js.map +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 +1 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_app_components_0r7kb.o._.js.map +1 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_app_components_EmptyState_tsx_0aol-el._.js +3 -0
- package/.next/server/chunks/ssr/agent-network-dashboard_app_components_EmptyState_tsx_0aol-el._.js.map +1 -0
- package/.next/server/chunks/ssr/agent-network-dashboard_app_nodes_page_tsx_11haf_p._.js +2 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_app_nodes_page_tsx_11haf_p._.js.map +1 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_app_providers_page_tsx_0hw2n0v._.js +3 -0
- package/.next/server/chunks/ssr/agent-network-dashboard_app_providers_page_tsx_0hw2n0v._.js.map +1 -0
- 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 +4 -0
- package/.next/server/pages/404.html +2 -2
- 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/{10kkhdde5ve~c.js → 0-z_kfck7-6_1.js} +3 -3
- package/.next/static/chunks/049vx3qljs1tt.js +1 -0
- package/.next/static/chunks/06.5euf239uvr.css +1 -0
- package/.next/static/chunks/{0vun~4ljcrj3p.js → 091hae.lhv9t1.js} +2 -2
- package/.next/static/chunks/0chpv7zsh-qrg.js +1 -0
- package/.next/static/chunks/0i-l67o_ae5hk.js +2 -0
- package/.next/static/chunks/{0vus9xpsz0s~i.js → 0l.gu-iqnmeja.js} +1 -1
- package/.next/static/chunks/{149a4l50_3vw-.js → 0mnmn-~ava1vy.js} +1 -1
- package/.next/static/chunks/0o-b62_a66.jr.js +1 -0
- package/.next/static/chunks/0pk6amtz5icbx.js +1 -0
- package/.next/static/chunks/0r4u1.sl.8p15.js +1 -0
- package/.next/static/chunks/0wz0122ym_gr3.js +1 -0
- package/.next/static/chunks/15aqdc5txzq9r.js +1 -0
- package/.next/trace +2 -2
- package/.next/trace-build +1 -1
- package/.next/types/routes.d.ts +7 -2
- package/.next/types/validator.ts +45 -0
- package/app/admin/page.tsx +3 -1
- package/app/api/anet/host-supervisors/route.ts +102 -0
- package/app/api/anet/node-config/route.ts +26 -2
- package/app/api/anet/node-create/route.ts +14 -5
- package/app/api/anet/node-lifecycle/route.ts +54 -5
- package/app/api/anet/providers/probe/route.ts +79 -0
- package/app/api/anet/providers/probe-results/route.ts +60 -0
- package/app/api/anet/providers/route.ts +191 -0
- package/app/api/hub/auth/route.ts +0 -12
- package/app/api/hub/networks/route.ts +1 -1
- package/app/api/hub/nodes/route.ts +0 -14
- package/app/api/hub/upload/route.ts +0 -9
- package/app/components/CommandCenter.tsx +3 -6
- package/app/components/CommandPalette.tsx +0 -5
- package/app/components/CreateNodeWizard.tsx +140 -47
- package/app/components/HostSupervisorPicker.tsx +283 -0
- package/app/components/NodeLifecycleMenu.tsx +436 -0
- package/app/components/NodeSettingsPanel.tsx +80 -39
- package/app/components/ProviderFormModal.tsx +303 -0
- package/app/components/ReachabilityMatrix.tsx +196 -0
- package/app/components/Sidebar.tsx +1 -0
- package/app/components/TaskDrawer.tsx +1 -0
- package/app/components/TopoGraph.tsx +4 -8
- package/app/components/UserBar.tsx +37 -0
- package/app/components/types.ts +11 -0
- package/app/lib/chat-unread.ts +0 -6
- package/app/lib/dashboard-auth.ts +0 -12
- package/app/lib/hooks.ts +22 -4
- package/app/lib/hub.ts +4 -0
- package/app/lib/network-context.tsx +0 -6
- package/app/lib/rate-limit.ts +2 -16
- package/app/node/page.tsx +12 -1
- package/app/nodes/page.tsx +42 -2
- package/app/page.tsx +1 -0
- package/app/providers/page.tsx +182 -0
- package/app/settings/networks/page.tsx +1 -1
- package/app/settings/page.tsx +5 -0
- package/app/tasks/[id]/page.tsx +1 -0
- package/app/tasks/page.tsx +1 -0
- package/package.json +1 -1
- package/.next/static/chunks/0-t2rbg9~-oh5.js +0 -1
- package/.next/static/chunks/0iv.0p9_5b36e.js +0 -1
- package/.next/static/chunks/0l_hz3xrjwumg.js +0 -1
- package/.next/static/chunks/0lmdw~i5qjqsg.js +0 -1
- package/.next/static/chunks/0vruzstkdr99w.js +0 -1
- package/.next/static/chunks/0xssg9sin~2xw.js +0 -1
- package/.next/static/chunks/124dtwo1k24ao.css +0 -1
- package/bun.lock +0 -1663
- /package/.next/static/{ZxdmFd_iOEELuA2Km4Q5t → tRPXkJdGLR6a0skqvMgQa}/_buildManifest.js +0 -0
- /package/.next/static/{ZxdmFd_iOEELuA2Km4Q5t → tRPXkJdGLR6a0skqvMgQa}/_clientMiddlewareManifest.js +0 -0
- /package/.next/static/{ZxdmFd_iOEELuA2Km4Q5t → tRPXkJdGLR6a0skqvMgQa}/_ssgManifest.js +0 -0
|
@@ -16,12 +16,6 @@ function hashSecret(secret: string) {
|
|
|
16
16
|
return createHash('sha256').update(`anet-dashboard:${secret}`).digest('hex');
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
// Constant-time string compare. Callers always pass sha256 hex digests
|
|
20
|
-
// (see hashSecret / verifyDashboardPassword), never raw secrets — two wins:
|
|
21
|
-
// the inputs are always 64 chars so the length guard never short-circuits
|
|
22
|
-
// on real data, and any residual timing signal leaks bytes of the *hash*,
|
|
23
|
-
// not the password. The length check is required because timingSafeEqual
|
|
24
|
-
// throws on mismatched buffer lengths.
|
|
25
19
|
function safeEqual(a: string, b: string) {
|
|
26
20
|
const aBuffer = Buffer.from(a);
|
|
27
21
|
const bBuffer = Buffer.from(b);
|
|
@@ -55,12 +49,6 @@ export async function verifyDashboardPassword(password: string) {
|
|
|
55
49
|
return expectedPassword.length > 0 && safeEqual(hashSecret(password), hashSecret(expectedPassword));
|
|
56
50
|
}
|
|
57
51
|
|
|
58
|
-
// The session cookie carries one of two valid formats:
|
|
59
|
-
// • "v3:<token>" — a hub-issued token (atok_/utok_/ntok_). The dashboard
|
|
60
|
-
// is a thin proxy, so getV3UserToken forwards this as the Bearer for hub
|
|
61
|
-
// calls; here we only sanity-check its shape (real auth is the hub's).
|
|
62
|
-
// • a bare password hash — the legacy single-password login, compared in
|
|
63
|
-
// constant time against the expected hash.
|
|
64
52
|
export async function verifyDashboardSession() {
|
|
65
53
|
const cookieStore = await cookies();
|
|
66
54
|
const sessionValue = cookieStore.get(DASHBOARD_SESSION_COOKIE)?.value || '';
|
package/app/lib/hooks.ts
CHANGED
|
@@ -11,10 +11,6 @@ const fetcher = async (url: string) => {
|
|
|
11
11
|
return res.json();
|
|
12
12
|
};
|
|
13
13
|
|
|
14
|
-
// 5s refresh keeps the fleet view live-ish without hammering the hub;
|
|
15
|
-
// 3s dedup collapses the burst of revalidations when several components
|
|
16
|
-
// mount or the tab refocuses at once, so one shared key = one in-flight
|
|
17
|
-
// request rather than N. (dedup < refresh so periodic refreshes still fire.)
|
|
18
14
|
const SWR_OPTIONS = { refreshInterval: 5000, dedupingInterval: 3000 };
|
|
19
15
|
|
|
20
16
|
/** Append network_id to URL if set */
|
|
@@ -34,6 +30,28 @@ export function useSessions() {
|
|
|
34
30
|
return { sessions: data?.sessions || [], hint: data?._hint, error, isLoading };
|
|
35
31
|
}
|
|
36
32
|
|
|
33
|
+
// RFC-027 PR2 — alias → lifecycle_state map sourced from /api/nodes
|
|
34
|
+
// (commhub-server preview.12+). /api/status reads from `sessions` which
|
|
35
|
+
// doesn't carry lifecycle_state; /api/nodes does. Cheap secondary
|
|
36
|
+
// fetch, same SWR cadence as useSessions; merged client-side by alias.
|
|
37
|
+
// Absent alias → caller defaults to 'active'.
|
|
38
|
+
interface NodesResp { nodes?: Array<{ alias?: string; node_id?: string; lifecycle_state?: string | null }>; }
|
|
39
|
+
export function useNodeLifecycle() {
|
|
40
|
+
const { networkId } = useNetworkId();
|
|
41
|
+
const { data, error } = useSWR<NodesResp>(
|
|
42
|
+
withNetwork('/api/hub/nodes', networkId),
|
|
43
|
+
fetcher,
|
|
44
|
+
SWR_OPTIONS,
|
|
45
|
+
);
|
|
46
|
+
const lifecycleByAlias: Record<string, string> = {};
|
|
47
|
+
const nodeIdByAlias: Record<string, string> = {};
|
|
48
|
+
for (const n of data?.nodes ?? []) {
|
|
49
|
+
if (n.alias && typeof n.lifecycle_state === 'string') lifecycleByAlias[n.alias] = n.lifecycle_state;
|
|
50
|
+
if (n.alias && typeof n.node_id === 'string') nodeIdByAlias[n.alias] = n.node_id;
|
|
51
|
+
}
|
|
52
|
+
return { lifecycleByAlias, nodeIdByAlias, error };
|
|
53
|
+
}
|
|
54
|
+
|
|
37
55
|
export function useHealth() {
|
|
38
56
|
const { data, error } = useSWR<Health>('/api/hub/health', fetcher, SWR_OPTIONS);
|
|
39
57
|
return { health: data || null, error };
|
package/app/lib/hub.ts
CHANGED
|
@@ -6,6 +6,10 @@ function getHubUrl() {
|
|
|
6
6
|
|
|
7
7
|
export const HUB_URL = getHubUrl();
|
|
8
8
|
|
|
9
|
+
export function hubHeaders(): Record<string, string> {
|
|
10
|
+
return {};
|
|
11
|
+
}
|
|
12
|
+
|
|
9
13
|
/**
|
|
10
14
|
* Fetch from CommHub. Uses the browser session's V3 user token when available.
|
|
11
15
|
* Dashboard is a thin proxy and does not fall back to a service/master token.
|
|
@@ -9,12 +9,6 @@ interface NetworkContextType {
|
|
|
9
9
|
|
|
10
10
|
const NetworkContext = createContext<NetworkContextType>({ networkId: '', setNetworkId: () => {} });
|
|
11
11
|
|
|
12
|
-
// Holds the network selected in UserBar. Empty string is the sentinel for
|
|
13
|
-
// "no filter / global view": the withNetwork() helpers (hooks.ts,
|
|
14
|
-
// chat-unread.ts) omit the network_id query param when it's '', so every
|
|
15
|
-
// SWR key falls back to the unscoped hub endpoint. Persisted in
|
|
16
|
-
// sessionStorage so a reload keeps the selection (per-tab, like the auth
|
|
17
|
-
// session — not shared across tabs).
|
|
18
12
|
export function NetworkProvider({ children }: { children: ReactNode }) {
|
|
19
13
|
const [networkId, setNetworkId] = useState('');
|
|
20
14
|
|
package/app/lib/rate-limit.ts
CHANGED
|
@@ -1,17 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Simple in-memory rate limiter for login attempts.
|
|
3
|
-
* Tracks by IP, allows
|
|
4
|
-
*
|
|
5
|
-
* Fixed-window, not sliding: the window opens on the first attempt and
|
|
6
|
-
* the whole counter resets once `resetAt` passes (a burst right after a
|
|
7
|
-
* reset can briefly allow up to 2×MAX over the boundary — acceptable for
|
|
8
|
-
* a login throttle, not a billing meter).
|
|
9
|
-
*
|
|
10
|
-
* State lives in this process's heap, so the limit is per-instance: the
|
|
11
|
-
* dashboard runs as a single `next start` process, so one shared counter.
|
|
12
|
-
* Behind multiple replicas the effective limit multiplies by replica
|
|
13
|
-
* count and an attacker could be balanced across them — move to a shared
|
|
14
|
-
* store (Redis) before scaling out.
|
|
3
|
+
* Tracks by IP, allows `max` attempts per `windowMs`.
|
|
15
4
|
*/
|
|
16
5
|
const attempts = new Map<string, { count: number; resetAt: number }>();
|
|
17
6
|
|
|
@@ -35,10 +24,7 @@ export function checkRateLimit(ip: string): { allowed: boolean; remaining: numbe
|
|
|
35
24
|
return { allowed: true, remaining: MAX_ATTEMPTS - entry.count, retryAfterMs: 0 };
|
|
36
25
|
}
|
|
37
26
|
|
|
38
|
-
// Cleanup stale entries every 5 minutes
|
|
39
|
-
// reset lazily on the next checkRateLimit for that IP (the `now >
|
|
40
|
-
// resetAt` branch above), so this sweep only reclaims memory for IPs
|
|
41
|
-
// that never come back — it isn't load-bearing for correctness.
|
|
27
|
+
// Cleanup stale entries every 5 minutes
|
|
42
28
|
if (typeof setInterval !== 'undefined') {
|
|
43
29
|
setInterval(() => {
|
|
44
30
|
const now = Date.now();
|
package/app/node/page.tsx
CHANGED
|
@@ -35,6 +35,15 @@ interface SessionDetail {
|
|
|
35
35
|
version: string;
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
+
interface Message {
|
|
39
|
+
id: string;
|
|
40
|
+
content: string;
|
|
41
|
+
from_session: string;
|
|
42
|
+
priority: string;
|
|
43
|
+
created_at: string;
|
|
44
|
+
type: string;
|
|
45
|
+
}
|
|
46
|
+
|
|
38
47
|
function TmuxViewer({ tmuxName }: { tmuxName: string }) {
|
|
39
48
|
const [output, setOutput] = useState('');
|
|
40
49
|
const [loading, setLoading] = useState(false);
|
|
@@ -80,6 +89,7 @@ function NodeDetailContent() {
|
|
|
80
89
|
const searchParams = useSearchParams();
|
|
81
90
|
const alias = searchParams.get('alias') || '';
|
|
82
91
|
const [session, setSession] = useState<SessionDetail | null>(null);
|
|
92
|
+
const [inbox, setInbox] = useState<Message[]>([]);
|
|
83
93
|
const [sse, setSse] = useState(0);
|
|
84
94
|
const [error, setError] = useState('');
|
|
85
95
|
const [sendMsg, setSendMsg] = useState('');
|
|
@@ -91,6 +101,7 @@ function NodeDetailContent() {
|
|
|
91
101
|
const res = await fetch(`/api/hub/session?alias=${encodeURIComponent(alias)}`);
|
|
92
102
|
const data = await res.json();
|
|
93
103
|
if (data.session) setSession(data.session);
|
|
104
|
+
if (data.inbox) setInbox(data.inbox);
|
|
94
105
|
setSse(data.sse || 0);
|
|
95
106
|
setError('');
|
|
96
107
|
} catch (e: unknown) {
|
|
@@ -349,7 +360,7 @@ function EventsTimeline({ events, loading }: { events: Array<{ id: number; event
|
|
|
349
360
|
{/* Vertical line */}
|
|
350
361
|
<div className="absolute left-[9px] top-2 bottom-2 w-0.5 bg-[#1c1c1f]" />
|
|
351
362
|
|
|
352
|
-
{taskEvents.map((e) => {
|
|
363
|
+
{taskEvents.map((e, i) => {
|
|
353
364
|
const cfg = EVENT_COLORS[e.to_status] || EVENT_COLORS.created;
|
|
354
365
|
return (
|
|
355
366
|
<div key={e.id} className="relative pb-4 last:pb-0">
|
package/app/nodes/page.tsx
CHANGED
|
@@ -2,9 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
import { useState } from 'react';
|
|
4
4
|
import { timeAgo } from '../components/utils';
|
|
5
|
-
import { useSessions, useHealth } from '../lib/hooks';
|
|
5
|
+
import { useSessions, useHealth, useNodeLifecycle } from '../lib/hooks';
|
|
6
|
+
import { useSWRConfig } from 'swr';
|
|
6
7
|
import { TaskChatPanel } from '../components/TaskChatPanel';
|
|
7
8
|
import { CreateNodeWizard } from '../components/CreateNodeWizard';
|
|
9
|
+
import { NodeLifecycleMenu } from '../components/NodeLifecycleMenu';
|
|
8
10
|
import { EmptyState, NodesEmptyState } from '../components/EmptyState';
|
|
9
11
|
import { AliasAvatar } from '../components/AliasAvatar';
|
|
10
12
|
import { useCollapsibleSearch } from '../components/CollapsibleSearch';
|
|
@@ -26,7 +28,16 @@ type SessionRow = Session & { online: boolean };
|
|
|
26
28
|
export default function NodesPage() {
|
|
27
29
|
const { sessions, isLoading: loading } = useSessions();
|
|
28
30
|
const { health } = useHealth();
|
|
31
|
+
const { lifecycleByAlias, nodeIdByAlias } = useNodeLifecycle();
|
|
29
32
|
const { hasUnread } = useChatUnread();
|
|
33
|
+
const { mutate } = useSWRConfig();
|
|
34
|
+
// RFC-027 PR2 — after a stop/delete/restart dispatch lands, refresh
|
|
35
|
+
// /api/hub/nodes (lifecycle_state) AND /api/hub/status (sessions).
|
|
36
|
+
// Both feed the menu's state-aware items; otherwise menu stays
|
|
37
|
+
// stale until next 5s SWR poll.
|
|
38
|
+
const refreshNodes = () => {
|
|
39
|
+
mutate((k: unknown) => typeof k === 'string' && (k.startsWith('/api/hub/nodes') || k.startsWith('/api/hub/status')));
|
|
40
|
+
};
|
|
30
41
|
const sseMap = health?.sse_sessions || {};
|
|
31
42
|
// SSE keys are `network_id:alias` since server v0.7+. Look up with the
|
|
32
43
|
// composite key first, fall back to alias-only for legacy hubs.
|
|
@@ -215,6 +226,16 @@ export default function NodesPage() {
|
|
|
215
226
|
</div>
|
|
216
227
|
</div>
|
|
217
228
|
<span className="hidden shrink-0 rounded-lg border border-cyan-500/15 bg-cyan-500/5 px-2 py-1 text-[10px] text-cyan-300/70 sm:inline">Tap to chat</span>
|
|
229
|
+
{/* RFC-027 PR2 — per-node ⋮ lifecycle menu. The button stopsPropagation
|
|
230
|
+
internally so it doesn't open chat. lifecycleByAlias absent → 'active'
|
|
231
|
+
default, menu renders normal stop/delete options. */}
|
|
232
|
+
<NodeLifecycleMenu
|
|
233
|
+
nodeId={nodeIdByAlias[s.alias] || s.node_id || s.alias}
|
|
234
|
+
alias={s.alias}
|
|
235
|
+
lifecycleState={lifecycleByAlias[s.alias]}
|
|
236
|
+
networkId={s.network_id || null}
|
|
237
|
+
onCompleted={refreshNodes}
|
|
238
|
+
/>
|
|
218
239
|
</div>
|
|
219
240
|
|
|
220
241
|
<div className="mt-3 rounded-lg border border-[#1c1c1f] bg-[#0e0e10] px-3 py-2 text-xs">
|
|
@@ -282,7 +303,18 @@ export default function NodesPage() {
|
|
|
282
303
|
<span className="truncate">{s.agent || '--'}<span className="text-gray-700 mx-1.5">·</span>{shortServer(s.server)}</span>
|
|
283
304
|
</div>
|
|
284
305
|
<div className="col-span-4 truncate text-xs text-gray-500" title={s.task || ''}>{s.task || '--'}</div>
|
|
285
|
-
<div className="col-span-1 text-xs text-gray-500">
|
|
306
|
+
<div className="col-span-1 flex items-center justify-between gap-2 text-xs text-gray-500">
|
|
307
|
+
<span className="truncate">{timeAgo(s.last_seen_at || s.updated_at)}</span>
|
|
308
|
+
{/* RFC-027 PR2 ⋮ lifecycle menu — desktop list. Defaults
|
|
309
|
+
to 'active' when lifecycleByAlias absent. */}
|
|
310
|
+
<NodeLifecycleMenu
|
|
311
|
+
nodeId={nodeIdByAlias[s.alias] || s.node_id || s.alias}
|
|
312
|
+
alias={s.alias}
|
|
313
|
+
lifecycleState={lifecycleByAlias[s.alias]}
|
|
314
|
+
networkId={s.network_id || null}
|
|
315
|
+
onCompleted={refreshNodes}
|
|
316
|
+
/>
|
|
317
|
+
</div>
|
|
286
318
|
</div>
|
|
287
319
|
{/* R7 of #190: mobile node row was ~340px tall × ~150
|
|
288
320
|
rows = the 51k page. Wins this round, in priority
|
|
@@ -307,6 +339,14 @@ export default function NodesPage() {
|
|
|
307
339
|
<span className={`shrink-0 text-xs px-2 py-0.5 rounded-md border ${STATUS_COLORS[statusKey] || STATUS_COLORS.offline}`}>
|
|
308
340
|
{statusKey}
|
|
309
341
|
</span>
|
|
342
|
+
{/* RFC-027 PR2 ⋮ lifecycle menu — mobile list. */}
|
|
343
|
+
<NodeLifecycleMenu
|
|
344
|
+
nodeId={nodeIdByAlias[s.alias] || s.node_id || s.alias}
|
|
345
|
+
alias={s.alias}
|
|
346
|
+
lifecycleState={lifecycleByAlias[s.alias]}
|
|
347
|
+
networkId={s.network_id || null}
|
|
348
|
+
onCompleted={refreshNodes}
|
|
349
|
+
/>
|
|
310
350
|
</div>
|
|
311
351
|
{s.task && <div className="truncate text-xs text-gray-500">{s.task}</div>}
|
|
312
352
|
</div>
|
package/app/page.tsx
CHANGED
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { useCallback, useEffect, useState } from 'react';
|
|
4
|
+
import { EmptyState } from '../components/EmptyState';
|
|
5
|
+
import { ProviderFormModal, type ProviderDraft } from '../components/ProviderFormModal';
|
|
6
|
+
import { ReachabilityMatrix } from '../components/ReachabilityMatrix';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Model providers (RFC-028 P1 — CRUD). Lists providers from
|
|
10
|
+
* /api/anet/providers, with create/edit (ProviderFormModal), an enabled
|
|
11
|
+
* toggle, soft-delete (enabled:0), and a per-row "Test" placeholder for the
|
|
12
|
+
* P2 connectivity matrix. Keys are write-only — the list only shows a
|
|
13
|
+
* key/no-key indicator, never a value.
|
|
14
|
+
*
|
|
15
|
+
* When the hub predates RFC-028 (#308 not merged / hub not upgraded) the API
|
|
16
|
+
* returns `unconfirmed` — we surface an honest banner instead of faking data.
|
|
17
|
+
* Set MOCK_PROVIDERS=1 on the dashboard server to preview the populated UI.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
interface Provider {
|
|
21
|
+
provider_id?: string;
|
|
22
|
+
name: string;
|
|
23
|
+
type: string;
|
|
24
|
+
base_url: string;
|
|
25
|
+
models?: string[];
|
|
26
|
+
enabled?: boolean;
|
|
27
|
+
hasKey?: boolean;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function hostOf(url: string) {
|
|
31
|
+
try { return new URL(url).host; } catch { return url; }
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Humanize the raw vendor enum for the row badge so it matches the create
|
|
35
|
+
// modal's wording. A DeepSeek/MiniMax row tagged bare "anthropic" reads as
|
|
36
|
+
// wrong — they're Anthropic-*compatible* endpoints, not Anthropic itself.
|
|
37
|
+
const TYPE_LABELS: Record<string, string> = {
|
|
38
|
+
anthropic: 'Anthropic 兼容',
|
|
39
|
+
'openai-compatible': 'OpenAI 兼容',
|
|
40
|
+
grok: 'Grok',
|
|
41
|
+
custom: 'Custom',
|
|
42
|
+
};
|
|
43
|
+
const typeLabel = (t: string) => TYPE_LABELS[t] || t;
|
|
44
|
+
|
|
45
|
+
export default function ProvidersPage() {
|
|
46
|
+
const [providers, setProviders] = useState<Provider[]>([]);
|
|
47
|
+
const [loading, setLoading] = useState(true);
|
|
48
|
+
const [unconfirmed, setUnconfirmed] = useState<string | null>(null);
|
|
49
|
+
const [mock, setMock] = useState(false);
|
|
50
|
+
const [editing, setEditing] = useState<ProviderDraft | null>(null);
|
|
51
|
+
const [showForm, setShowForm] = useState(false);
|
|
52
|
+
const [expandedId, setExpandedId] = useState<string | null>(null);
|
|
53
|
+
|
|
54
|
+
const fetchProviders = useCallback(async () => {
|
|
55
|
+
try {
|
|
56
|
+
const res = await fetch('/api/anet/providers', { cache: 'no-store' });
|
|
57
|
+
const data = await res.json().catch(() => ({}));
|
|
58
|
+
setProviders(Array.isArray(data?.providers) ? data.providers : []);
|
|
59
|
+
setUnconfirmed(data?.unconfirmed ? (data?.error || 'backend not available') : null);
|
|
60
|
+
setMock(!!data?.mock);
|
|
61
|
+
} catch { setUnconfirmed('request failed'); } finally { setLoading(false); }
|
|
62
|
+
}, []);
|
|
63
|
+
|
|
64
|
+
useEffect(() => { fetchProviders(); }, [fetchProviders]);
|
|
65
|
+
|
|
66
|
+
const openCreate = () => { setEditing(null); setShowForm(true); };
|
|
67
|
+
// Edit / enable-disable wired to update_provider (#317). vendor + key are
|
|
68
|
+
// immutable on the backend, so the edit form patches name/base_url/models
|
|
69
|
+
// only (changing the key is a separate secret-first flow).
|
|
70
|
+
const openEdit = (p: Provider) => {
|
|
71
|
+
setEditing({ provider_id: p.provider_id, name: p.name, type: p.type, base_url: p.base_url, models: p.models || [], enabled: p.enabled ?? true, hasKey: p.hasKey });
|
|
72
|
+
setShowForm(true);
|
|
73
|
+
};
|
|
74
|
+
const toggleEnabled = async (p: Provider) => {
|
|
75
|
+
setProviders(prev => prev.map(x => (x.provider_id || x.name) === (p.provider_id || p.name) ? { ...x, enabled: !x.enabled } : x)); // optimistic
|
|
76
|
+
await fetch('/api/anet/providers', {
|
|
77
|
+
method: 'POST', headers: { 'Content-Type': 'application/json' },
|
|
78
|
+
body: JSON.stringify({ provider_id: p.provider_id, enabled: !p.enabled }),
|
|
79
|
+
}).catch(() => {});
|
|
80
|
+
fetchProviders();
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
return (
|
|
84
|
+
<div className="min-h-screen bg-[#0b0b0d] text-gray-100 p-4 sm:p-6">
|
|
85
|
+
<div className="flex items-center gap-4 mb-6">
|
|
86
|
+
<h1 className="text-2xl font-bold text-white lg:ml-0 ml-10">Model Providers</h1>
|
|
87
|
+
{mock && <span className="text-[10px] px-2 py-0.5 rounded-full border border-amber-500/30 bg-amber-500/5 text-amber-300">preview fixture</span>}
|
|
88
|
+
<button
|
|
89
|
+
onClick={openCreate}
|
|
90
|
+
className="ml-auto inline-flex shrink-0 items-center gap-1.5 whitespace-nowrap rounded-md bg-cyan-600 px-3 py-1.5 text-sm font-medium text-white hover:bg-cyan-500"
|
|
91
|
+
>
|
|
92
|
+
<svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round" aria-hidden><path d="M12 5v14M5 12h14" /></svg>
|
|
93
|
+
新增供应商
|
|
94
|
+
</button>
|
|
95
|
+
</div>
|
|
96
|
+
|
|
97
|
+
<div className="max-w-3xl space-y-4">
|
|
98
|
+
<p className="text-sm text-gray-500">
|
|
99
|
+
Configure model providers and per-server reachability. API keys are stored write-only in the secret vault and never displayed.
|
|
100
|
+
</p>
|
|
101
|
+
|
|
102
|
+
{unconfirmed && (
|
|
103
|
+
<div className="rounded-xl border border-amber-500/30 bg-amber-500/5 px-4 py-3 text-xs text-amber-300">
|
|
104
|
+
供应商后端(RFC-028)尚未在当前 hub 就绪:{unconfirmed}。UI 已就位;待 #308 合并 + hub 升级后接真后端。
|
|
105
|
+
<span className="text-amber-400/70">(开发预览可设 MOCK_PROVIDERS=1 看填充态。)</span>
|
|
106
|
+
</div>
|
|
107
|
+
)}
|
|
108
|
+
|
|
109
|
+
<section className="bg-[#161618] border border-[#26262b] rounded-xl p-5">
|
|
110
|
+
{loading ? (
|
|
111
|
+
<div className="animate-pulse space-y-2">{[1, 2, 3].map(i => <div key={i} className="h-14 bg-gray-800/20 rounded" />)}</div>
|
|
112
|
+
) : providers.length === 0 ? (
|
|
113
|
+
<EmptyState
|
|
114
|
+
variant="generic"
|
|
115
|
+
title="No model providers"
|
|
116
|
+
sub="Add a provider to register its models and test per-server reachability."
|
|
117
|
+
cta={{ label: '新增供应商', onClick: openCreate }}
|
|
118
|
+
/>
|
|
119
|
+
) : (
|
|
120
|
+
<div className="space-y-2">
|
|
121
|
+
{providers.map(p => {
|
|
122
|
+
const rid = p.provider_id || p.name;
|
|
123
|
+
const isOpen = expandedId === rid;
|
|
124
|
+
return (
|
|
125
|
+
<div key={rid} className={`rounded-lg border border-[#1c1c1f] bg-[#0e0e10] ${p.enabled ? '' : 'opacity-60'}`} data-provider={p.name}>
|
|
126
|
+
<div className="flex flex-col gap-2 px-3 py-2.5 sm:flex-row sm:items-center sm:gap-3">
|
|
127
|
+
<div className="flex min-w-0 flex-1 items-center gap-3">
|
|
128
|
+
<span className={`inline-block h-2 w-2 shrink-0 rounded-full ${p.enabled ? 'bg-green-500' : 'bg-gray-600'}`} title={p.enabled ? 'enabled' : 'disabled'} />
|
|
129
|
+
<div className="min-w-0 flex-1">
|
|
130
|
+
<div className="flex flex-wrap items-center gap-x-2 gap-y-1">
|
|
131
|
+
<span className="text-sm font-semibold text-white truncate">{p.name}</span>
|
|
132
|
+
<span className="text-[10px] px-1.5 py-0.5 rounded border border-gray-600/30 text-gray-400 shrink-0" title={p.type}>{typeLabel(p.type)}</span>
|
|
133
|
+
{p.hasKey
|
|
134
|
+
? <span className="text-[10px] px-1.5 py-0.5 rounded border border-green-500/20 bg-green-500/5 text-green-400 shrink-0">key set</span>
|
|
135
|
+
: <span className="text-[10px] px-1.5 py-0.5 rounded border border-gray-600/20 text-gray-500 shrink-0">no key</span>}
|
|
136
|
+
</div>
|
|
137
|
+
<div className="text-[11px] text-gray-500 truncate">
|
|
138
|
+
{hostOf(p.base_url)} · {(p.models?.length || 0)} model{(p.models?.length || 0) === 1 ? '' : 's'}
|
|
139
|
+
</div>
|
|
140
|
+
</div>
|
|
141
|
+
</div>
|
|
142
|
+
<div className="flex w-full shrink-0 items-center justify-end gap-1.5 border-t border-[#1c1c1f] pt-2 sm:w-auto sm:justify-normal sm:self-auto sm:border-t-0 sm:pt-0">
|
|
143
|
+
<button
|
|
144
|
+
type="button"
|
|
145
|
+
onClick={() => setExpandedId(isOpen ? null : rid)}
|
|
146
|
+
disabled={!p.enabled}
|
|
147
|
+
title={p.enabled ? '连通性测试(模型 × 服务器 可达矩阵)' : '供应商已停用,启用后可测连通性'}
|
|
148
|
+
className={`rounded border px-2 py-1 text-[11px] transition-colors ${!p.enabled ? 'border-[#26262b] text-gray-600 cursor-not-allowed' : isOpen ? 'border-cyan-500/40 bg-cyan-500/10 text-cyan-300' : 'border-[#26262b] text-gray-300 hover:border-cyan-500/30 hover:text-cyan-300'}`}
|
|
149
|
+
>Test{isOpen ? ' ▾' : ''}</button>
|
|
150
|
+
<button type="button" onClick={() => openEdit(p)} title="编辑(名称 / base_url / 模型)" className="rounded border border-[#26262b] px-2 py-1 text-[11px] text-gray-300 hover:border-cyan-500/30 hover:text-cyan-300">Edit</button>
|
|
151
|
+
<button type="button" onClick={() => toggleEnabled(p)} title={p.enabled ? '停用(软删,可重新启用)' : '启用'} className="rounded border border-[#26262b] px-2 py-1 text-[11px] text-gray-400 hover:text-gray-200">
|
|
152
|
+
{p.enabled ? 'Disable' : 'Enable'}
|
|
153
|
+
</button>
|
|
154
|
+
</div>
|
|
155
|
+
</div>
|
|
156
|
+
{isOpen && (
|
|
157
|
+
(p.models?.length || 0) > 0
|
|
158
|
+
? <ReachabilityMatrix providerId={p.provider_id} models={p.models || []} />
|
|
159
|
+
: <div className="border-t border-[#1c1c1f] px-3 py-3 text-[11px] text-gray-500">该供应商未配置模型——先 Edit 添加模型再测可达性。</div>
|
|
160
|
+
)}
|
|
161
|
+
</div>
|
|
162
|
+
);
|
|
163
|
+
})}
|
|
164
|
+
</div>
|
|
165
|
+
)}
|
|
166
|
+
</section>
|
|
167
|
+
|
|
168
|
+
<p className="text-[11px] text-gray-600">
|
|
169
|
+
按 <span className="text-gray-400">Test</span> 展开「模型 × 服务器」连通性矩阵(对每个模型实时探测可达性)。创建节点向导的模型下拉将从此处的 registry 拉取(即将支持)。
|
|
170
|
+
</p>
|
|
171
|
+
</div>
|
|
172
|
+
|
|
173
|
+
{showForm && (
|
|
174
|
+
<ProviderFormModal
|
|
175
|
+
initial={editing}
|
|
176
|
+
onClose={() => setShowForm(false)}
|
|
177
|
+
onSaved={fetchProviders}
|
|
178
|
+
/>
|
|
179
|
+
)}
|
|
180
|
+
</div>
|
|
181
|
+
);
|
|
182
|
+
}
|
package/app/settings/page.tsx
CHANGED
|
@@ -269,6 +269,11 @@ export default function SettingsPage() {
|
|
|
269
269
|
<p className="text-xs text-gray-500 mt-2">Create, manage, and delete agent networks.</p>
|
|
270
270
|
<span className="text-xs text-cyan-400 mt-3 inline-block">Manage →</span>
|
|
271
271
|
</Link>
|
|
272
|
+
<Link href="/settings/providers" className="bg-[#161618] border border-[#26262b] rounded-xl p-5 hover:border-cyan-500/30 transition-colors">
|
|
273
|
+
<h2 className="text-sm font-semibold text-gray-300">Model Providers</h2>
|
|
274
|
+
<p className="text-xs text-gray-500 mt-2">Configure model providers and per-server reachability.</p>
|
|
275
|
+
<span className="text-xs text-cyan-400 mt-3 inline-block">Manage →</span>
|
|
276
|
+
</Link>
|
|
272
277
|
<Link href="/messages" className="bg-[#161618] border border-[#26262b] rounded-xl p-5 hover:border-cyan-500/30 transition-colors">
|
|
273
278
|
<h2 className="text-sm font-semibold text-gray-300">Messages</h2>
|
|
274
279
|
<p className="text-xs text-gray-500 mt-2">Global timeline of CommHub messages across all agents.</p>
|
package/app/tasks/[id]/page.tsx
CHANGED
package/app/tasks/page.tsx
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import { useEffect, useState, useCallback, Suspense } from 'react';
|
|
4
4
|
import { useSearchParams } from 'next/navigation';
|
|
5
|
+
import Link from 'next/link';
|
|
5
6
|
import { useNetworkId } from '../lib/network-context';
|
|
6
7
|
import { TaskDrawer } from '../components/TaskDrawer';
|
|
7
8
|
import { EmptyState } from '../components/EmptyState';
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,3479,e=>{"use strict";var a=e.i(59746);e.s(["previewContent",0,function(e){return e&&e.replace(/!\[([^\]]*)\]\([^)]*\)/g,"$1").replace(/\[([^\]]+)\]\([^)]*\)/g,"$1").replace(/`([^`]+)`/g,"$1").replace(/\s+/g," ").trim()||"--"},"timeAgo",0,function(e){return(0,a.relativeAgo)(e)??"--"}])},46228,e=>{"use strict";var a=e.i(22381);let t=[180,200,220,270,300,330,30,90];function r(e){let a=0;for(let t=0;t<e.length;t++)a=31*a+e.charCodeAt(t)>>>0;let r=t[a%t.length];return{bg:`hsl(${r} 55% 22%)`,ring:`hsl(${r} 60% 45%)`,text:`hsl(${r} 80% 78%)`}}function s(e){return e?(e.trim().match(/[\p{L}\p{N}]/u)?.[0]||e.trim()[0]||"·").toUpperCase():"·"}e.s(["AliasAvatar",0,function({alias:e,size:t=28,className:l=""}){if(/\bgrok\b|grok-build|grok测试员|grok-demo/i.test(e))return(0,a.jsx)("span",{className:`anet-alias-avatar inline-flex items-center justify-center rounded-full border border-emerald-500/45 bg-emerald-950/70 shrink-0 ${l}`,style:{width:t,height:t,backgroundImage:"url(/vendors/grok.svg)",backgroundPosition:"center",backgroundRepeat:"no-repeat",backgroundSize:"68% 68%"},title:e,"aria-hidden":!0});let n=r(e),i=Math.max(9,Math.round(.42*t));return(0,a.jsx)("span",{className:`anet-alias-avatar inline-flex items-center justify-center rounded-full border shrink-0 font-semibold ${l}`,style:{width:t,height:t,fontSize:i,backgroundColor:n.bg,borderColor:n.ring,color:n.text},title:e,"aria-hidden":!0,children:s(e)})},"aliasAvatarColors",0,r,"aliasInitial",0,s])},98025,e=>{"use strict";e.s(["SESSION_STATUS_CHIP_CLASS",0,{working:"bg-green-500/10 text-green-300 border-green-500/20",idle:"bg-gray-500/10 text-gray-300 border-gray-500/20",blocked:"bg-yellow-500/10 text-yellow-300 border-yellow-500/20",error:"bg-red-500/10 text-red-300 border-red-500/20",offline:"bg-gray-500/10 text-gray-500 border-gray-500/20"},"SESSION_STATUS_TEXT_CLASS",0,{working:"text-green-400",idle:"text-gray-400",blocked:"text-yellow-400",error:"text-red-400",offline:"text-gray-500"},"STATUS_BAR_CLASS",0,{created:"bg-gray-500",delivered:"bg-gray-400",acked:"bg-gray-300",running:"bg-green-500",replied:"bg-gray-400",closed:"bg-gray-600",failed:"bg-red-500",cancelled:"bg-gray-600",expired:"bg-gray-600"},"STATUS_CHIP_CLASS",0,{created:"bg-gray-500/10 text-gray-400 border-gray-500/20",delivered:"bg-gray-500/10 text-gray-300 border-gray-500/20",acked:"bg-gray-500/10 text-gray-300 border-gray-500/20",running:"bg-green-500/10 text-green-300 border-green-500/20",replied:"bg-gray-500/10 text-gray-300 border-gray-500/20",closed:"bg-gray-500/10 text-gray-500 border-gray-500/20",failed:"bg-red-500/10 text-red-300 border-red-500/20",cancelled:"bg-gray-500/10 text-gray-500 border-gray-500/20",expired:"bg-gray-500/10 text-gray-500 border-gray-500/20"},"STATUS_DOT_HEX",0,{created:"#9ca3af",delivered:"#9ca3af",acked:"#9ca3af",running:"#4ade80",replied:"#9ca3af",closed:"#6b7280",failed:"#f87171",cancelled:"#6b7280",expired:"#6b7280"},"TASK_STATUSES",0,["created","delivered","acked","running","replied","closed","failed","cancelled","expired"]])},51868,e=>{"use strict";var a=e.i(22381),t=e.i(23910),r=e.i(56058),s=e.i(56839),l=e.i(43058),n=e.i(3479),i=e.i(46228),d=e.i(98025),o=e.i(38263);function c({tmuxName:e}){let[r,s]=(0,t.useState)(""),[l,n]=(0,t.useState)(!1),[i,d]=(0,t.useState)(!1),o=async()=>{n(!0);try{let a=await fetch(`/api/hub/tmux?name=${encodeURIComponent(e)}`),t=await a.json();s(t.output||t.error||"No output")}catch{s("Failed to fetch")}n(!1)};return(0,a.jsxs)("div",{className:"bg-[#161618] border border-[#26262b] rounded-xl p-4",children:[(0,a.jsxs)("div",{className:"flex items-center justify-between mb-2",children:[(0,a.jsxs)("h2",{className:"text-sm font-semibold text-gray-300",children:["Terminal (",e,")"]}),(0,a.jsxs)("div",{className:"flex gap-2",children:[(0,a.jsx)("button",{onClick:o,disabled:l,className:"text-xs text-cyan-400 hover:text-cyan-300 disabled:text-gray-600",children:l?"Loading...":"Capture"}),r&&(0,a.jsx)("button",{onClick:()=>d(!i),className:"text-xs text-gray-500 hover:text-gray-300",children:i?"Collapse":"Expand"})]})]}),r&&(0,a.jsx)("pre",{className:`text-[11px] text-green-300 bg-[#060607] rounded-lg px-3 py-2 border border-[#1c1c1f] overflow-x-auto whitespace-pre font-mono ${i?"max-h-96":"max-h-32"} overflow-y-auto`,children:r}),!r&&(0,a.jsx)("p",{className:"text-xs text-gray-600",children:"Click Capture to view terminal output"})]})}function x(){let e=(0,r.useSearchParams)().get("alias")||"",[l,n]=(0,t.useState)(null),[o,c]=(0,t.useState)(0),[x,b]=(0,t.useState)(""),[h,u]=(0,t.useState)(""),[m,p]=(0,t.useState)(!1),y=(0,t.useCallback)(async()=>{if(e)try{let a=await fetch(`/api/hub/session?alias=${encodeURIComponent(e)}`),t=await a.json();t.session&&n(t.session),c(t.sse||0),b("")}catch(e){b(e instanceof Error?e.message:"fetch failed")}},[e]);(0,t.useEffect)(()=>{y();let e=setInterval(y,5e3);return()=>clearInterval(e)},[y]);let[f,v]=(0,t.useState)(""),j=async()=>{if(h.trim()&&e){p(!0),v("");try{let a=await fetch("/api/hub/send",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({alias:e,task:h})}),t=await a.json();t.ok?(u(""),setTimeout(y,2e3)):v(t.error||"Send failed")}catch(e){v(e instanceof Error?e.message:"Send failed")}p(!1)}};if(!e)return(0,a.jsx)("div",{className:"min-h-screen bg-[#0b0b0d] text-gray-100 p-6 flex items-center justify-center",children:(0,a.jsxs)("p",{className:"text-gray-500",children:["No alias specified. ",(0,a.jsx)(s.default,{href:"/",className:"text-blue-400 hover:underline",children:"Back to dashboard"})]})});let S=d.SESSION_STATUS_TEXT_CLASS[l?.status||""]||d.SESSION_STATUS_TEXT_CLASS.offline;return(0,a.jsxs)("div",{className:"min-h-screen bg-[#0b0b0d] text-gray-100 p-4 sm:p-6",children:[(0,a.jsxs)("div",{className:"flex items-center gap-3 mb-6 lg:ml-0 ml-10",children:[(0,a.jsx)(s.default,{href:"/nodes",className:"text-gray-500 hover:text-gray-300 text-sm shrink-0",children:"← Nodes"}),(0,a.jsx)(i.AliasAvatar,{alias:e,size:32}),(0,a.jsxs)("div",{className:"min-w-0 flex-1",children:[(0,a.jsxs)("div",{className:"flex items-center gap-2",children:[(0,a.jsx)("h1",{className:"text-xl sm:text-2xl font-bold text-white truncate",children:e}),(0,a.jsx)("span",{className:`inline-block w-1.5 h-1.5 rounded-full shrink-0 ${o>0?l?.status==="working"?"bg-green-500 animate-pulse":"bg-emerald-400":"bg-gray-500"}`}),(0,a.jsx)("span",{className:`text-[10px] uppercase tracking-wide font-semibold ${S}`,children:l?.status||"unknown"})]}),l?.agent&&(0,a.jsxs)("div",{className:"text-xs text-gray-500 truncate",children:[l.agent,l.server?(0,a.jsxs)(a.Fragment,{children:[" ",(0,a.jsx)("span",{className:"text-gray-700 mx-1",children:"·"})," ",l.server]}):null]})]})]}),x&&(0,a.jsx)("div",{className:"bg-red-900/20 border border-red-800/40 text-red-300 px-4 py-2 rounded-lg mb-6 text-sm",children:x}),(0,a.jsx)(g,{alias:e,session:l,sse:o,sendMsg:h,setSendMsg:u,sending:m,sendTask:j,sendError:f})]})}function g({alias:e,session:r,sse:s,sendMsg:n,setSendMsg:i,sending:d,sendTask:x,sendError:b}){let[u,m]=(0,t.useState)("chat"),{hasUnread:p}=(0,o.useChatUnread)(),[y,f]=(0,t.useState)([]),[v,j]=(0,t.useState)(!1),S=p(e);return(0,t.useEffect)(()=>{"events"!==u||v||fetch("/api/hub/task-events?limit=50").then(e=>e.json()).then(e=>{f(e.events||[]),j(!0)}).catch(()=>j(!0))},[u,v]),(0,a.jsxs)("div",{className:"bg-[#111113] border border-[#26262b] rounded-xl overflow-hidden h-[calc(100vh-140px)] flex flex-col",children:[(0,a.jsx)("div",{className:"flex border-b border-[#26262b] bg-[#0e0e10] shrink-0",children:[{id:"chat",label:"Chat",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"},{id:"events",label:"Events",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"},{id:"info",label:"Info",icon:"M12 21a9 9 0 100-18 9 9 0 000 18z M12 8h.01 M11 12h1v4h1"}].map(e=>(0,a.jsxs)("button",{onClick:()=>m(e.id),className:`flex items-center gap-2 px-5 py-3 text-sm font-medium border-b-2 transition-colors ${u===e.id?"border-cyan-400 text-cyan-300":"border-transparent text-gray-500 hover:text-gray-300"}`,children:[(0,a.jsx)("svg",{className:"w-4 h-4 shrink-0",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round",children:(0,a.jsx)("path",{d:e.icon})}),(0,a.jsxs)("span",{className:"relative inline-flex items-center gap-2",children:[e.label,"chat"===e.id&&S&&"chat"!==u&&(0,a.jsx)("span",{className:"inline-block h-2.5 w-2.5 rounded-full bg-red-500","aria-label":"Unread chat messages"})]})]},e.id))}),(0,a.jsxs)("div",{className:"flex-1 overflow-hidden",children:["chat"===u&&(0,a.jsx)(l.TaskChatPanel,{alias:e,onClose:()=>{},inline:!0}),"events"===u&&(0,a.jsx)(h,{events:y,loading:!v}),"info"===u&&(0,a.jsxs)("div",{className:"p-4 overflow-y-auto h-full space-y-4 max-w-2xl",children:[(0,a.jsxs)("div",{className:"bg-[#161618] border border-[#26262b] rounded-xl p-4",children:[(0,a.jsx)("h2",{className:"text-sm font-semibold text-gray-300 mb-3",children:"Node Info"}),(0,a.jsx)("div",{className:"space-y-2 text-xs",children:[{label:"Node ID",value:r?.node_id,alwaysShow:!0},{label:"Session ID",value:r?.session_id,alwaysShow:!0},{label:"Resume ID",value:r?.resume_id,alwaysShow:!0},{label:"Alias",value:r?.alias,alwaysShow:!0},{label:"Agent",value:r?.agent,alwaysShow:!0},{label:"Model",value:r?.model,alwaysShow:!0},{label:"Version",value:r?.version},{label:"Server",value:r?.server,alwaysShow:!0},{label:"Hostname",value:r?.hostname,alwaysShow:!0},{label:"IP",value:r?.ip,alwaysShow:!0},{label:"Project",value:r?.project_dir},{label:"Config",value:r?.config_path,alwaysShow:!0},{label:"Channels",value:r?.channels?.length?Array.isArray(r.channels)?r.channels.join(", "):r.channels:null,alwaysShow:!0},{label:"Tmux",value:r?.tmux_name},{label:"SSE",value:s>0?`Connected (${s})`:"Disconnected",alwaysShow:!0},{label:"Progress",value:r?.progress?`${r.progress}%`:null},{label:"Score",value:r?.score},{label:"Last Seen",value:r?.last_seen_at,alwaysShow:!0},{label:"Registered",value:r?.registered_at,alwaysShow:!0},{label:"Updated",value:r?.updated_at,alwaysShow:!0}].map(({label:e,value:t,alwaysShow:r})=>t||r?(0,a.jsxs)("div",{className:"flex justify-between gap-3",children:[(0,a.jsx)("span",{className:"text-gray-500 shrink-0",children:e}),(0,a.jsx)("span",{className:"text-gray-300 truncate max-w-[200px]",title:t?String(t):"--",children:t?String(t):"--"})]},e):null)})]}),r?.task&&(0,a.jsxs)("div",{className:"bg-[#161618] border border-[#26262b] rounded-xl p-4",children:[(0,a.jsx)("h2",{className:"text-sm font-semibold text-gray-300 mb-2",children:"Current Task"}),(0,a.jsx)("p",{className:"text-xs text-gray-400 whitespace-pre-wrap",children:r.task})]}),r?.output&&(0,a.jsxs)("div",{className:"bg-[#161618] border border-[#26262b] rounded-xl p-4",children:[(0,a.jsx)("h2",{className:"text-sm font-semibold text-gray-300 mb-2",children:"Last Output"}),(0,a.jsx)("p",{className:"text-xs text-gray-400 whitespace-pre-wrap max-h-48 overflow-y-auto",children:r.output})]}),(0,a.jsxs)("div",{className:"bg-[#161618] border border-[#26262b] rounded-xl p-4",children:[(0,a.jsx)("h2",{className:"text-sm font-semibold text-gray-300 mb-2",children:"Send Task"}),(0,a.jsxs)("div",{className:"flex gap-2",children:[(0,a.jsx)("input",{type:"text",value:n,onChange:e=>i(e.target.value),onKeyDown:e=>"Enter"===e.key&&x(),placeholder:`Send task to ${e}...`,className:"flex-1 bg-[#0e0e10] border border-[#26262b] rounded px-3 py-2 text-base sm:text-xs text-white placeholder-gray-600 focus:border-blue-500 focus:outline-none"}),(0,a.jsx)("button",{onClick:x,disabled:d||!n.trim(),className:"inline-flex min-h-[44px] items-center justify-center px-4 py-2 bg-blue-600 hover:bg-blue-500 disabled:bg-gray-700 text-white text-xs rounded transition-colors",children:d?"...":"Send"})]}),b&&(0,a.jsx)("div",{className:"mt-2 text-xs text-red-400",children:b})]}),r?.tmux_name&&(0,a.jsx)(c,{tmuxName:r.tmux_name})]})]})]})}let b={delivered:{dot:"bg-blue-400",line:"bg-blue-500/30",path:"M12 5v14 M5 12l7 7 7-7"},acked:{dot:"bg-yellow-400",line:"bg-yellow-500/30",path:"M20 6 9 17l-5-5"},running:{dot:"bg-green-400",line:"bg-green-500/30",path:"M13 2L4 14h6l-1 8 10-12h-6l1-8z"},replied:{dot:"bg-purple-400",line:"bg-purple-500/30",path:"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"},failed:{dot:"bg-red-400",line:"bg-red-500/30",path:"M18 6 6 18 M6 6l12 12"},created:{dot:"bg-gray-400",line:"bg-gray-500/30",path:"M12 5v14 M5 12h14"}};function h({events:e,loading:t}){if(t)return(0,a.jsx)("div",{className:"flex justify-center py-8",children:(0,a.jsx)("div",{className:"w-5 h-5 border-2 border-cyan-500/30 border-t-cyan-500 rounded-full animate-spin"})});if(0===e.length)return(0,a.jsx)("div",{className:"text-center py-12 text-gray-600 text-xs",children:"No task events yet"});let r=new Map;return e.forEach(e=>{let a=e.task_id||`ungrouped-${e.id}`,t=r.get(a)||[];t.push(e),r.set(a,t)}),(0,a.jsx)("div",{className:"p-4 overflow-y-auto h-full space-y-4",children:[...r.entries()].map(([e,t])=>(0,a.jsxs)("div",{className:"bg-[#161618] border border-[#26262b] rounded-xl p-4",children:[(0,a.jsxs)("div",{className:"text-[10px] text-gray-600 mb-3 truncate",children:["Task: ",e.slice(0,20),"..."]}),(0,a.jsxs)("div",{className:"relative pl-6",children:[(0,a.jsx)("div",{className:"absolute left-[9px] top-2 bottom-2 w-0.5 bg-[#1c1c1f]"}),t.map(e=>{let t=b[e.to_status]||b.created;return(0,a.jsxs)("div",{className:"relative pb-4 last:pb-0",children:[(0,a.jsx)("div",{className:`absolute -left-6 top-0.5 w-[18px] h-[18px] rounded-full ${t.dot} flex items-center justify-center z-10 border-2 border-[#161618]`,children:(0,a.jsx)("svg",{width:"10",height:"10",viewBox:"0 0 24 24",fill:"none",stroke:"#0e0e10",strokeWidth:"2.5",strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":!0,children:(0,a.jsx)("path",{d:t.path})})}),(0,a.jsxs)("div",{className:"ml-2",children:[(0,a.jsxs)("div",{className:"flex items-center gap-2",children:[(0,a.jsx)("span",{className:`text-xs font-medium ${"failed"===e.to_status?"text-red-400":"replied"===e.to_status?"text-purple-400":"text-gray-300"}`,children:e.event_type}),e.from_status&&(0,a.jsxs)("span",{className:"text-[10px] text-gray-600",children:[e.from_status," → ",e.to_status]}),(0,a.jsx)("span",{className:"text-[10px] text-gray-600 ml-auto",children:(0,n.timeAgo)(e.created_at)})]}),e.detail&&(0,a.jsxs)("div",{className:"text-[11px] text-gray-500 mt-0.5 truncate",children:[e.detail.slice(0,50),e.detail.length>50?"...":""]})]})]},e.id)})]})]},e))})}e.s(["default",0,function(){return(0,a.jsx)(t.Suspense,{fallback:(0,a.jsx)("div",{className:"min-h-screen bg-[#0b0b0d] text-gray-100 p-4 sm:p-6",children:(0,a.jsx)("div",{className:"lg:ml-0 ml-10 text-gray-500 text-sm",children:"Loading…"})}),children:(0,a.jsx)(x,{})})}])}]);
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,3479,e=>{"use strict";var t=e.i(59746);e.s(["previewContent",0,function(e){return e&&e.replace(/!\[([^\]]*)\]\([^)]*\)/g,"$1").replace(/\[([^\]]+)\]\([^)]*\)/g,"$1").replace(/`([^`]+)`/g,"$1").replace(/\s+/g," ").trim()||"--"},"timeAgo",0,function(e){return(0,t.relativeAgo)(e)??"--"}])},46228,e=>{"use strict";var t=e.i(22381);let s=[180,200,220,270,300,330,30,90];function a(e){let t=0;for(let s=0;s<e.length;s++)t=31*t+e.charCodeAt(s)>>>0;let a=s[t%s.length];return{bg:`hsl(${a} 55% 22%)`,ring:`hsl(${a} 60% 45%)`,text:`hsl(${a} 80% 78%)`}}function r(e){return e?(e.trim().match(/[\p{L}\p{N}]/u)?.[0]||e.trim()[0]||"·").toUpperCase():"·"}e.s(["AliasAvatar",0,function({alias:e,size:s=28,className:l=""}){if(/\bgrok\b|grok-build|grok测试员|grok-demo/i.test(e))return(0,t.jsx)("span",{className:`anet-alias-avatar inline-flex items-center justify-center rounded-full border border-emerald-500/45 bg-emerald-950/70 shrink-0 ${l}`,style:{width:s,height:s,backgroundImage:"url(/vendors/grok.svg)",backgroundPosition:"center",backgroundRepeat:"no-repeat",backgroundSize:"68% 68%"},title:e,"aria-hidden":!0});let i=a(e),n=Math.max(9,Math.round(.42*s));return(0,t.jsx)("span",{className:`anet-alias-avatar inline-flex items-center justify-center rounded-full border shrink-0 font-semibold ${l}`,style:{width:s,height:s,fontSize:n,backgroundColor:i.bg,borderColor:i.ring,color:i.text},title:e,"aria-hidden":!0,children:r(e)})},"aliasAvatarColors",0,a,"aliasInitial",0,r])},98025,e=>{"use strict";e.s(["SESSION_STATUS_CHIP_CLASS",0,{working:"bg-green-500/10 text-green-300 border-green-500/20",idle:"bg-gray-500/10 text-gray-300 border-gray-500/20",blocked:"bg-yellow-500/10 text-yellow-300 border-yellow-500/20",error:"bg-red-500/10 text-red-300 border-red-500/20",offline:"bg-gray-500/10 text-gray-500 border-gray-500/20"},"SESSION_STATUS_TEXT_CLASS",0,{working:"text-green-400",idle:"text-gray-400",blocked:"text-yellow-400",error:"text-red-400",offline:"text-gray-500"},"STATUS_BAR_CLASS",0,{created:"bg-gray-500",delivered:"bg-gray-400",acked:"bg-gray-300",running:"bg-green-500",replied:"bg-gray-400",closed:"bg-gray-600",failed:"bg-red-500",cancelled:"bg-gray-600",expired:"bg-gray-600"},"STATUS_CHIP_CLASS",0,{created:"bg-gray-500/10 text-gray-400 border-gray-500/20",delivered:"bg-gray-500/10 text-gray-300 border-gray-500/20",acked:"bg-gray-500/10 text-gray-300 border-gray-500/20",running:"bg-green-500/10 text-green-300 border-green-500/20",replied:"bg-gray-500/10 text-gray-300 border-gray-500/20",closed:"bg-gray-500/10 text-gray-500 border-gray-500/20",failed:"bg-red-500/10 text-red-300 border-red-500/20",cancelled:"bg-gray-500/10 text-gray-500 border-gray-500/20",expired:"bg-gray-500/10 text-gray-500 border-gray-500/20"},"STATUS_DOT_HEX",0,{created:"#9ca3af",delivered:"#9ca3af",acked:"#9ca3af",running:"#4ade80",replied:"#9ca3af",closed:"#6b7280",failed:"#f87171",cancelled:"#6b7280",expired:"#6b7280"},"TASK_STATUSES",0,["created","delivered","acked","running","replied","closed","failed","cancelled","expired"]])},59276,e=>{"use strict";var t=e.i(12629),s=e.i(11449);let a=async e=>{let t=await fetch(e);if(401===t.status)throw window.location.assign("/login"),Error("unauthorized");return t.json()},r={refreshInterval:5e3,dedupingInterval:3e3};function l(e,t){if(!t)return e;let s=e.includes("?")?"&":"?";return`${e}${s}network_id=${encodeURIComponent(t)}`}e.s(["useAnetConfig",0,function(){let{data:e}=(0,t.default)("/api/anet/config",a,{refreshInterval:3e4});return{config:e||null}},"useHealth",0,function(){let{data:e,error:s}=(0,t.default)("/api/hub/health",a,r);return{health:e||null,error:s}},"useMessages",0,function(e=100){let{networkId:i}=(0,s.useNetworkId)(),{data:n,error:d,isLoading:o}=(0,t.default)(l(`/api/hub/messages?limit=${e}`,i),a,{...r,keepPreviousData:!0});return{messages:n?.messages||[],error:d,isLoading:o}},"useSessions",0,function(){let{networkId:e}=(0,s.useNetworkId)(),{data:i,error:n,isLoading:d}=(0,t.default)(l("/api/hub/status",e),a,r);return{sessions:i?.sessions||[],hint:i?._hint,error:n,isLoading:d}},"useStats",0,function(){let{networkId:e}=(0,s.useNetworkId)(),{data:i,error:n}=(0,t.default)(l("/api/hub/stats",e),a,r);return{stats:i?.ok?i:null,error:n}},"useTasks",0,function(e){let{networkId:i}=(0,s.useNetworkId)(),n=new URLSearchParams({limit:"100",...e}).toString(),{data:d,error:o,isLoading:c}=(0,t.default)(l(`/api/hub/tasks?${n}`,i),a,r);return{tasks:d?.tasks||[],count:d?.count??0,source:d?.source,error:o,isLoading:c}}])},28729,e=>{"use strict";var t=e.i(22381),s=e.i(23910),a=e.i(56839),r=e.i(59276),l=e.i(3479),i=e.i(46228),n=e.i(98025);e.s(["default",0,function(){let e,{sessions:d}=(0,r.useSessions)(),{health:o}=(0,r.useHealth)(),{stats:c}=(0,r.useStats)(),x=o?.sse_sessions||{},g=e=>(e.network_id?x[`${e.network_id}:${e.alias}`]:void 0)??x[e.alias],[u,b]=(0,s.useState)(""),[m,h]=(0,s.useState)(""),[p,y]=(0,s.useState)(""),[f,j]=(0,s.useState)(""),[v,N]=(0,s.useState)(""),[S,k]=(0,s.useState)(""),[w,T]=(0,s.useState)(""),[C,A]=(0,s.useState)(""),_=async()=>{if(u.trim()&&m.trim()){try{let e=await fetch("/api/hub/auth",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({action:"register",username:u,password:m})}),t=await e.json();y(t.ok?`Created: ${t.user.username} (${t.user.user_id})`:`Failed: ${t.error}`),t.ok&&(b(""),h(""))}catch{y("Failed")}setTimeout(()=>y(""),8e3)}},$=async()=>{if(f.trim()){try{let e=await fetch("/api/hub/broadcast",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({message:f})}),t=await e.json();N(t.ok?`Sent to ${t.recipients} nodes`:`Failed: ${t.error}`),t.ok&&j("")}catch{N("Failed")}setTimeout(()=>N(""),5e3)}},O=async()=>{if(S&&w.trim()){try{let e=await fetch("/api/hub/send",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({alias:S,task:w})}),t=await e.json();A(t.ok?"Task sent":`Failed: ${t.error}`),t.ok&&T("")}catch{A("Failed")}setTimeout(()=>A(""),5e3)}},I=d.filter(e=>g(e)),U=d.filter(e=>!g(e));return(0,t.jsxs)("div",{className:"min-h-screen bg-[#0b0b0d] text-gray-100 p-4 sm:p-6",children:[(0,t.jsx)("h1",{className:"text-2xl font-bold text-white mb-3 lg:ml-0 ml-10",children:"Admin"}),(0,t.jsx)("nav",{className:"mb-4 sm:mb-8 flex flex-wrap gap-2 text-xs",children:[{href:"#status",label:"Status"},{href:"#actions",label:"Actions"},{href:"#users",label:"Users"}].map(e=>(0,t.jsx)("a",{href:e.href,className:"inline-flex min-h-[44px] items-center rounded-md border border-[#26262b] bg-[#0e0e10]/60 px-3 py-2 text-gray-400 hover:border-cyan-500/50 hover:text-cyan-300 hover:bg-cyan-500/10 transition-colors",children:e.label},e.href))}),(0,t.jsxs)("div",{className:"max-w-6xl space-y-10",children:[(0,t.jsxs)("div",{id:"status",className:"space-y-4 scroll-mt-6",children:[(0,t.jsxs)("div",{className:"flex items-center gap-2 px-1",children:[(0,t.jsx)("div",{className:"text-[11px] uppercase tracking-[0.14em] text-gray-400 font-semibold",children:"Status"}),(0,t.jsx)("div",{className:"flex-1 h-px bg-[#26262b]"})]}),(0,t.jsxs)("div",{className:"grid grid-cols-1 lg:grid-cols-2 gap-4",children:[(0,t.jsxs)("section",{className:"bg-[#161618] border border-[#26262b] rounded-xl p-4 sm:p-5",children:[(0,t.jsx)("h2",{className:"text-sm font-semibold text-gray-300 mb-3 sm:mb-4",children:"Server Overview"}),(0,t.jsxs)("div",{className:"grid grid-cols-2 gap-4 text-sm",children:[(0,t.jsxs)("div",{children:[(0,t.jsx)("div",{className:"text-2xl sm:text-3xl font-bold text-green-400 tabular-nums",children:I.length}),(0,t.jsx)("div",{className:"text-xs text-gray-500",children:"Online"})]}),(0,t.jsxs)("div",{children:[(0,t.jsx)("div",{className:"text-2xl sm:text-3xl font-bold text-gray-500 tabular-nums",children:U.length}),(0,t.jsx)("div",{className:"text-xs text-gray-500",children:"Offline"})]}),(0,t.jsxs)("div",{children:[(0,t.jsx)("div",{className:"text-2xl sm:text-3xl font-bold text-cyan-400 tabular-nums",children:o?.sse_connections??"--"}),(0,t.jsxs)("div",{className:"text-xs text-gray-500",children:["SSE Streams ",(0,t.jsx)("span",{className:"text-gray-600",children:"· server"})]})]}),(0,t.jsxs)("div",{children:[(0,t.jsx)("div",{className:"text-2xl sm:text-3xl font-bold text-white tabular-nums",children:c?.tasks?.total??"--"}),(0,t.jsx)("div",{className:"text-xs text-gray-500",children:"Total Tasks"})]})]}),c?.tasks?.by_status&&c.tasks.by_status.length>0&&(e=Object.fromEntries(c.tasks.by_status.map(e=>[e.status,e.count])),(0,t.jsxs)("div",{className:"mt-4 flex items-center justify-between border-t border-[#26262b] pt-3 text-xs",children:[(0,t.jsxs)("div",{className:"text-gray-400 tabular-nums",children:[(0,t.jsxs)("span",{className:e.running?"text-green-400":"text-gray-500",children:[e.running||0," running"]}),(0,t.jsx)("span",{className:"text-gray-600",children:" · "}),(0,t.jsxs)("span",{className:e.failed?"text-red-400":"text-gray-500",children:[e.failed||0," failed"]})]}),(0,t.jsx)(a.default,{href:"/tasks",prefetch:!1,className:"text-cyan-400 hover:text-cyan-300",children:"View all →"})]}))]}),(0,t.jsxs)("section",{className:"bg-[#161618] border border-[#26262b] rounded-xl p-5",children:[(0,t.jsxs)("h2",{className:"text-sm font-semibold text-gray-300 mb-4",children:["Online Sessions ",(0,t.jsxs)("span",{className:"text-gray-600",children:["(",I.length,")"]})]}),(0,t.jsx)("div",{className:"space-y-2 max-h-80 overflow-y-auto",children:0===I.length?(0,t.jsx)("div",{className:"text-xs text-gray-600 text-center py-4",children:"No online sessions"}):I.map(e=>(0,t.jsxs)("div",{className:"flex items-center gap-3 bg-[#0e0e10] rounded-lg px-3 py-2 border border-[#1c1c1f]",children:[(0,t.jsx)(i.AliasAvatar,{alias:e.alias,size:20}),(0,t.jsxs)("div",{className:"min-w-0 flex-1",children:[(0,t.jsx)("div",{className:"text-sm text-white font-medium truncate",children:e.alias}),(0,t.jsxs)("div",{className:"text-xs text-gray-500 truncate",children:[e.agent||"--"," · ",e.task||"idle"]})]}),(0,t.jsxs)("div",{className:"flex items-center gap-2 shrink-0",children:[(0,t.jsx)("span",{className:`text-xs px-2 py-0.5 rounded border ${n.SESSION_STATUS_CHIP_CLASS[e.status]||n.SESSION_STATUS_CHIP_CLASS.idle}`,children:e.status}),(0,t.jsx)("span",{className:"text-[10px] text-gray-600",children:(0,l.timeAgo)(e.updated_at)})]})]},e.alias))})]})]})]}),(0,t.jsxs)("div",{id:"actions",className:"space-y-4 scroll-mt-6",children:[(0,t.jsxs)("div",{className:"flex items-center gap-2 px-1",children:[(0,t.jsx)("div",{className:"text-[11px] uppercase tracking-[0.14em] text-gray-400 font-semibold",children:"Actions"}),(0,t.jsx)("div",{className:"flex-1 h-px bg-[#26262b]"})]}),0===d.length?(0,t.jsx)("div",{className:"bg-[#161618] border border-[#26262b] rounded-xl px-5 py-4 text-sm text-gray-500",children:"Broadcast and Send Task become available after the first agent registers."}):(0,t.jsxs)("div",{className:"grid grid-cols-1 lg:grid-cols-2 gap-4",children:[(0,t.jsxs)("section",{className:"bg-[#161618] border border-[#26262b] rounded-xl p-5",children:[(0,t.jsx)("h2",{className:"text-sm font-semibold text-gray-300 mb-4",children:"Broadcast"}),(0,t.jsx)("textarea",{value:f,onChange:e=>j(e.target.value),placeholder:"Message to all online nodes...",rows:3,className:"w-full bg-[#0e0e10] border border-[#26262b] rounded-lg px-3 py-2 text-sm text-white placeholder-gray-600 focus:border-cyan-500/50 focus:outline-none resize-none"}),(0,t.jsxs)("div",{className:"flex justify-between items-center mt-3",children:[(0,t.jsxs)("span",{className:"text-xs text-gray-600",children:[f.length,"/500"]}),(0,t.jsx)("button",{onClick:$,disabled:!f.trim(),className:"px-4 py-2 bg-purple-600 hover:bg-purple-500 disabled:bg-gray-800 disabled:text-gray-600 text-white text-sm rounded-lg transition-colors",children:"Broadcast"})]}),v&&(0,t.jsx)("div",{className:`mt-2 text-xs ${v.startsWith("Failed")?"text-red-400":"text-green-400"}`,children:v})]}),(0,t.jsxs)("section",{className:"bg-[#161618] border border-[#26262b] rounded-xl p-5",children:[(0,t.jsx)("h2",{className:"text-sm font-semibold text-gray-300 mb-4",children:"Send Task"}),(0,t.jsxs)("select",{value:S,onChange:e=>k(e.target.value),className:"w-full bg-[#0e0e10] border border-[#26262b] rounded-lg px-3 py-2 text-base sm:text-sm text-white focus:border-cyan-500/50 focus:outline-none mb-3",children:[(0,t.jsx)("option",{value:"",children:"Select target node..."}),I.map(e=>(0,t.jsxs)("option",{value:e.alias,children:[e.alias," (",e.status,")"]},e.alias)),(0,t.jsx)("optgroup",{label:"Offline",children:U.map(e=>(0,t.jsxs)("option",{value:e.alias,children:[e.alias," (offline)"]},e.alias))})]}),(0,t.jsx)("textarea",{value:w,onChange:e=>T(e.target.value),placeholder:"Task content...",rows:3,className:"w-full bg-[#0e0e10] border border-[#26262b] rounded-lg px-3 py-2 text-sm text-white placeholder-gray-600 focus:border-cyan-500/50 focus:outline-none resize-none"}),(0,t.jsx)("div",{className:"flex justify-end mt-3",children:(0,t.jsx)("button",{onClick:O,disabled:!S||!w.trim(),className:"px-4 py-2 bg-cyan-600 hover:bg-cyan-500 disabled:bg-gray-800 disabled:text-gray-600 text-white text-sm rounded-lg transition-colors",children:"Send Task"})}),C&&(0,t.jsx)("div",{className:`mt-2 text-xs ${C.startsWith("Failed")?"text-red-400":"text-green-400"}`,children:C})]})]})]}),(0,t.jsxs)("div",{id:"users",className:"space-y-4 scroll-mt-6",children:[(0,t.jsxs)("div",{className:"flex items-center gap-2 px-1",children:[(0,t.jsx)("div",{className:"text-[11px] uppercase tracking-[0.14em] text-gray-400 font-semibold",children:"Users"}),(0,t.jsx)("div",{className:"flex-1 h-px bg-[#26262b]"})]}),(0,t.jsx)("div",{className:"grid grid-cols-1 lg:grid-cols-2 gap-4",children:(0,t.jsxs)("section",{className:"bg-[#161618] border border-[#26262b] rounded-xl p-5",children:[(0,t.jsx)("h2",{className:"text-sm font-semibold text-gray-300 mb-4",children:"Register User (V3)"}),(0,t.jsxs)("div",{className:"space-y-3",children:[(0,t.jsx)("input",{type:"text",value:u,onChange:e=>b(e.target.value),placeholder:"Username",className:"w-full bg-[#0e0e10] border border-[#26262b] rounded-lg px-3 py-2 text-sm text-white placeholder-gray-600 focus:border-cyan-500/50 focus:outline-none"}),(0,t.jsx)("input",{type:"password",value:m,onChange:e=>h(e.target.value),placeholder:"Password",className:"w-full bg-[#0e0e10] border border-[#26262b] rounded-lg px-3 py-2 text-sm text-white placeholder-gray-600 focus:border-cyan-500/50 focus:outline-none"}),(0,t.jsx)("button",{onClick:_,disabled:!u.trim()||!m.trim(),className:"w-full px-4 py-2 bg-green-600 hover:bg-green-500 disabled:bg-gray-800 disabled:text-gray-600 text-white text-sm rounded-lg transition-colors",children:"Register"})]}),p&&(0,t.jsx)("div",{className:`mt-2 text-xs ${p.startsWith("Failed")?"text-red-400":"text-green-400"}`,children:p})]})})]})]})]})}])}]);
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,59276,e=>{"use strict";var s=e.i(12629),t=e.i(11449);let a=async e=>{let s=await fetch(e);if(401===s.status)throw window.location.assign("/login"),Error("unauthorized");return s.json()},r={refreshInterval:5e3,dedupingInterval:3e3};function n(e,s){if(!s)return e;let t=e.includes("?")?"&":"?";return`${e}${t}network_id=${encodeURIComponent(s)}`}e.s(["useAnetConfig",0,function(){let{data:e}=(0,s.default)("/api/anet/config",a,{refreshInterval:3e4});return{config:e||null}},"useHealth",0,function(){let{data:e,error:t}=(0,s.default)("/api/hub/health",a,r);return{health:e||null,error:t}},"useMessages",0,function(e=100){let{networkId:l}=(0,t.useNetworkId)(),{data:c,error:i,isLoading:o}=(0,s.default)(n(`/api/hub/messages?limit=${e}`,l),a,{...r,keepPreviousData:!0});return{messages:c?.messages||[],error:i,isLoading:o}},"useSessions",0,function(){let{networkId:e}=(0,t.useNetworkId)(),{data:l,error:c,isLoading:i}=(0,s.default)(n("/api/hub/status",e),a,r);return{sessions:l?.sessions||[],hint:l?._hint,error:c,isLoading:i}},"useStats",0,function(){let{networkId:e}=(0,t.useNetworkId)(),{data:l,error:c}=(0,s.default)(n("/api/hub/stats",e),a,r);return{stats:l?.ok?l:null,error:c}},"useTasks",0,function(e){let{networkId:l}=(0,t.useNetworkId)(),c=new URLSearchParams({limit:"100",...e}).toString(),{data:i,error:o,isLoading:d}=(0,s.default)(n(`/api/hub/tasks?${c}`,l),a,r);return{tasks:i?.tasks||[],count:i?.count??0,source:i?.source,error:o,isLoading:d}}])},70286,e=>{"use strict";e.s(["DASHBOARD_VERSION",0,"0.6.3-preview.0"],70286)},65610,e=>{"use strict";var s=e.i(22381),t=e.i(23910),a=e.i(56839),r=e.i(59276),n=e.i(70286);e.s(["default",0,function(){let{config:e}=(0,r.useAnetConfig)(),{health:l,error:c}=(0,r.useHealth)(),[i,o]=(0,t.useState)(()=>{try{return localStorage.getItem("anet-theme")||"cyber"}catch{return"cyber"}}),[d,x]=(0,t.useState)(""),[m,h]=(0,t.useState)(""),[b,g]=(0,t.useState)(""),u="flex flex-col gap-1 sm:flex-row sm:items-start sm:justify-between",p="break-all sm:max-w-[320px] sm:text-right";return(0,s.jsxs)("div",{className:"min-h-screen bg-[#0b0b0d] text-gray-100 p-4 sm:p-6",children:[(0,s.jsx)("h1",{className:"text-2xl font-bold text-white mb-3 lg:ml-0 ml-10",children:"Settings"}),(0,s.jsx)("nav",{className:"mb-4 sm:mb-8 flex flex-wrap gap-2 text-xs",children:[{href:"#appearance",label:"Appearance"},{href:"#connection",label:"Connection"},{href:"#account",label:"Account"},{href:"#resources",label:"Resources"}].map(e=>(0,s.jsx)("a",{href:e.href,className:"inline-flex min-h-[44px] items-center rounded-md border border-[#26262b] bg-[#0e0e10]/60 px-3 py-2 text-gray-400 hover:border-cyan-500/50 hover:text-cyan-300 hover:bg-cyan-500/10 transition-colors",children:e.label},e.href))}),(0,s.jsxs)("div",{className:"max-w-2xl space-y-10",children:[(0,s.jsxs)("div",{id:"appearance",className:"space-y-4 scroll-mt-6",children:[(0,s.jsxs)("div",{className:"flex items-center gap-2 px-1",children:[(0,s.jsx)("div",{className:"text-[11px] uppercase tracking-[0.14em] text-gray-400 font-semibold",children:"Appearance"}),(0,s.jsx)("div",{className:"flex-1 h-px bg-[#26262b]"})]}),(0,s.jsxs)("section",{className:"bg-[#161618] border border-[#26262b] rounded-xl p-5",children:[(0,s.jsx)("h2",{className:"text-sm font-semibold text-gray-300 mb-4",children:"Theme"}),(0,s.jsx)("div",{className:"grid grid-cols-2 gap-3",children:[{id:"cyber",label:"Dark",swatch:"#0b0b0d"},{id:"light",label:"Light",swatch:"#f6f7f9"}].map(e=>(0,s.jsxs)("button",{onClick:()=>{try{localStorage.setItem("anet-theme",e.id)}catch{}document.documentElement.setAttribute("data-theme",e.id),o(e.id)},"aria-pressed":i===e.id,className:`flex items-center gap-3 rounded-lg border px-4 py-3 text-sm transition-colors ${i===e.id?"border-cyan-500/60 bg-cyan-500/10 text-gray-100":"border-[#26262b] text-gray-400 hover:border-[#3a3a41]"}`,children:[(0,s.jsx)("span",{"aria-hidden":!0,className:"inline-block w-5 h-5 rounded-full border border-black/20 shrink-0",style:{backgroundColor:e.swatch}}),e.label,i===e.id&&(0,s.jsx)("span",{className:"ml-auto text-cyan-400",children:"✓"})]},e.id))})]})]}),(0,s.jsxs)("div",{id:"connection",className:"space-y-4 scroll-mt-6",children:[(0,s.jsxs)("div",{className:"flex items-center gap-2 px-1",children:[(0,s.jsx)("div",{className:"text-[11px] uppercase tracking-[0.14em] text-gray-400 font-semibold",children:"Connection"}),(0,s.jsx)("div",{className:"flex-1 h-px bg-[#26262b]"})]}),(0,s.jsxs)("section",{className:"bg-[#161618] border border-[#26262b] rounded-xl p-5",children:[(0,s.jsx)("h2",{className:"text-sm font-semibold text-gray-300 mb-4",children:"CommHub Connection"}),(0,s.jsxs)("div",{className:"space-y-3 text-sm",children:[(0,s.jsxs)("div",{className:u,children:[(0,s.jsx)("span",{className:"text-gray-500 shrink-0",children:"Hub URL"}),(0,s.jsx)("span",{className:`text-cyan-300 ${p}`,children:e?.hub||"not configured"})]}),(0,s.jsxs)("div",{className:u,children:[(0,s.jsx)("span",{className:"text-gray-500",children:"Config Source"}),(0,s.jsx)("span",{className:`text-gray-300 ${p}`,children:e?.source==="file"?"Local file (~/.anet/config.json)":e?.source==="runtime-env"?"Vercel env vars":"Missing"})]}),(0,s.jsxs)("div",{className:u,children:[(0,s.jsx)("span",{className:"text-gray-500",children:"Auth Token"}),(0,s.jsx)("span",{className:`${e?.tokenConfigured?"text-green-400":"text-red-400"} ${p}`,children:e?.tokenConfigured?`Configured (${e.tokenPreview})`:"Not configured"})]}),(0,s.jsxs)("div",{className:u,children:[(0,s.jsx)("span",{className:"text-gray-500",children:"Server Auth"}),(0,s.jsx)("span",{className:`${l?.auth==="enabled"?"text-green-400":"text-yellow-400"} sm:text-right`,children:l?.auth||"--"})]}),e?.error&&(0,s.jsx)("div",{className:"border-t border-[#26262b] pt-3 text-xs text-gray-600",children:e.error}),(c||l?.ok===!1)&&(0,s.jsxs)("div",{className:"border-t border-red-500/20 pt-3 text-xs space-y-1.5",role:"alert",children:[(0,s.jsx)("div",{className:"text-red-300 font-medium",children:"CommHub unreachable — how to recover:"}),(0,s.jsxs)("div",{className:"text-gray-400",children:["1. Check the hub process on the server: ",(0,s.jsx)("code",{className:"font-mono bg-[#0e0e10] border border-[#1c1c1f] rounded px-1.5 py-0.5",children:"anet hub status"})]}),(0,s.jsxs)("div",{className:"text-gray-400",children:["2. Start it if stopped: ",(0,s.jsx)("code",{className:"font-mono bg-[#0e0e10] border border-[#1c1c1f] rounded px-1.5 py-0.5",children:"anet hub start"})]}),(0,s.jsx)("div",{className:"text-gray-400",children:"3. Confirm the Hub URL above matches where the hub actually listens."})]})]})]}),(0,s.jsxs)("section",{className:"bg-[#161618] border border-[#26262b] rounded-xl p-5",children:[(0,s.jsx)("h2",{className:"text-sm font-semibold text-gray-300 mb-4",children:"Server Info"}),(0,s.jsxs)("div",{className:"space-y-3 text-sm",children:[(0,s.jsxs)("div",{className:u,children:[(0,s.jsx)("span",{className:"text-gray-500",children:"Version"}),(0,s.jsx)("span",{className:`text-gray-300 ${p}`,children:l?.version||"--"})]}),(0,s.jsxs)("div",{className:u,children:[(0,s.jsx)("span",{className:"text-gray-500",children:"Sessions"}),(0,s.jsx)("span",{className:`text-gray-300 ${p}`,children:l?.sessions??"--"})]}),(0,s.jsxs)("div",{className:u,children:[(0,s.jsxs)("span",{className:"text-gray-500",children:["SSE streams ",(0,s.jsx)("span",{className:"text-gray-600",children:"· server"})]}),(0,s.jsx)("span",{className:`text-gray-300 ${p}`,children:l?.sse_connections??"--"})]}),(0,s.jsxs)("div",{className:u,children:[(0,s.jsx)("span",{className:"text-gray-500",children:"Uptime"}),(0,s.jsx)("span",{className:`text-gray-300 ${p}`,children:l?.uptime?`${Math.floor(l.uptime/3600)}h ${Math.floor(l.uptime%3600/60)}m`:"--"})]})]})]}),(0,s.jsxs)("section",{className:"bg-[#161618] border border-[#26262b] rounded-xl p-5",children:[(0,s.jsx)("h2",{className:"text-sm font-semibold text-gray-300 mb-4",children:"Dashboard"}),(0,s.jsxs)("div",{className:"space-y-3 text-sm",children:[(0,s.jsxs)("div",{className:u,children:[(0,s.jsx)("span",{className:"text-gray-500",children:"Version"}),(0,s.jsx)("span",{className:`text-gray-300 font-mono ${p}`,title:"From package.json @sleep2agi/agent-network-dashboard",children:n.DASHBOARD_VERSION})]}),(0,s.jsxs)("div",{className:u,children:[(0,s.jsx)("span",{className:"text-gray-500",children:"Data Layer"}),(0,s.jsx)("span",{className:`text-gray-300 ${p}`,children:"SWR (5s refresh, 3s dedup)"})]}),(0,s.jsxs)("div",{className:u,children:[(0,s.jsx)("span",{className:"text-gray-500",children:"Pages"}),(0,s.jsx)("span",{className:`text-gray-300 ${p}`,children:"Overview, Tasks, Nodes, Messages, Networks, Audit, Server Logs, Admin, Settings"})]})]})]})]}),(0,s.jsxs)("div",{id:"account",className:"space-y-4 scroll-mt-6",children:[(0,s.jsxs)("div",{className:"flex items-center gap-2 px-1",children:[(0,s.jsx)("div",{className:"text-[11px] uppercase tracking-[0.14em] text-gray-400 font-semibold",children:"Account"}),(0,s.jsx)("div",{className:"flex-1 h-px bg-[#26262b]"})]}),(0,s.jsxs)("section",{className:"bg-[#161618] border border-[#26262b] rounded-xl p-5",children:[(0,s.jsx)("h2",{className:"text-sm font-semibold text-gray-300 mb-4",children:"Change Password"}),(0,s.jsxs)("div",{className:"space-y-3",children:[(0,s.jsx)("input",{type:"password",value:d,onChange:e=>x(e.target.value),placeholder:"Current password",className:"w-full bg-[#0e0e10] border border-[#26262b] rounded-lg px-3 py-2 text-base sm:text-sm text-white placeholder-gray-600 focus:border-cyan-500/50 focus:outline-none"}),(0,s.jsx)("input",{type:"password",value:m,onChange:e=>h(e.target.value),placeholder:"New password",className:"w-full bg-[#0e0e10] border border-[#26262b] rounded-lg px-3 py-2 text-base sm:text-sm text-white placeholder-gray-600 focus:border-cyan-500/50 focus:outline-none"}),(0,s.jsx)("button",{onClick:async()=>{if(!d||!m)return;let e=sessionStorage.getItem("anet_v3_auth");if(!e)return void g("Not logged in with V3 auth");let{token:s}=JSON.parse(e),t=await fetch("/api/hub/auth",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({action:"change_password",token:s,current_password:d,new_password:m})}),a=await t.json();if(g(a.ok?"Password changed":`Failed: ${a.error}`),a.ok){if(a.token){let s=JSON.parse(e);sessionStorage.setItem("anet_v3_auth",JSON.stringify({...s,token:a.token}))}x(""),h("")}setTimeout(()=>g(""),5e3)},disabled:!d||!m,className:"px-4 py-2 bg-cyan-600 hover:bg-cyan-500 disabled:bg-gray-800 disabled:text-gray-600 text-white text-sm rounded-lg transition-colors",children:"Change Password"})]}),b&&(0,s.jsx)("div",{className:`mt-2 text-xs ${b.startsWith("Failed")?"text-red-400":"text-green-400"}`,children:b})]}),(0,s.jsxs)("section",{className:"bg-[#161618] border border-[#26262b] rounded-xl p-5",children:[(0,s.jsx)("h2",{className:"text-sm font-semibold text-gray-300 mb-4",children:"Sign out"}),(0,s.jsx)("p",{className:"text-xs text-gray-500 mb-3",children:"Signing out clears your dashboard session cookie. You'll return to the login page."}),(0,s.jsx)("button",{onClick:async()=>{await fetch("/api/auth/logout",{method:"POST"}).catch(()=>{}),window.location.assign("/login")},className:"px-4 py-2 bg-transparent hover:bg-[#1c1c1f] text-gray-300 text-sm rounded-lg border border-[#26262b] hover:border-[#3a3a41] transition-colors",children:"Sign out"})]})]}),(0,s.jsxs)("div",{id:"resources",className:"space-y-4 scroll-mt-6",children:[(0,s.jsxs)("div",{className:"flex items-center gap-2 px-1",children:[(0,s.jsx)("div",{className:"text-[11px] uppercase tracking-[0.14em] text-gray-400 font-semibold",children:"Resources"}),(0,s.jsx)("div",{className:"flex-1 h-px bg-[#26262b]"})]}),(0,s.jsxs)("div",{className:"grid grid-cols-1 sm:grid-cols-2 gap-4",children:[(0,s.jsxs)(a.default,{href:"/settings/tokens",className:"bg-[#161618] border border-[#26262b] rounded-xl p-5 hover:border-cyan-500/30 transition-colors",children:[(0,s.jsx)("h2",{className:"text-sm font-semibold text-gray-300",children:"API Tokens"}),(0,s.jsx)("p",{className:"text-xs text-gray-500 mt-2",children:"Create and manage tokens for CLI access."}),(0,s.jsx)("span",{className:"text-xs text-cyan-400 mt-3 inline-block",children:"Manage →"})]}),(0,s.jsxs)(a.default,{href:"/settings/networks",className:"bg-[#161618] border border-[#26262b] rounded-xl p-5 hover:border-cyan-500/30 transition-colors",children:[(0,s.jsx)("h2",{className:"text-sm font-semibold text-gray-300",children:"Networks"}),(0,s.jsx)("p",{className:"text-xs text-gray-500 mt-2",children:"Create, manage, and delete agent networks."}),(0,s.jsx)("span",{className:"text-xs text-cyan-400 mt-3 inline-block",children:"Manage →"})]}),(0,s.jsxs)(a.default,{href:"/messages",className:"bg-[#161618] border border-[#26262b] rounded-xl p-5 hover:border-cyan-500/30 transition-colors",children:[(0,s.jsx)("h2",{className:"text-sm font-semibold text-gray-300",children:"Messages"}),(0,s.jsx)("p",{className:"text-xs text-gray-500 mt-2",children:"Global timeline of CommHub messages across all agents."}),(0,s.jsx)("span",{className:"text-xs text-cyan-400 mt-3 inline-block",children:"Open →"})]}),(0,s.jsxs)(a.default,{href:"/logs",className:"bg-[#161618] border border-[#26262b] rounded-xl p-5 hover:border-cyan-500/30 transition-colors",children:[(0,s.jsx)("h2",{className:"text-sm font-semibold text-gray-300",children:"Audit Log"}),(0,s.jsx)("p",{className:"text-xs text-gray-500 mt-2",children:"Authentication, token rotations, and admin actions."}),(0,s.jsx)("span",{className:"text-xs text-cyan-400 mt-3 inline-block",children:"Open →"})]}),(0,s.jsxs)(a.default,{href:"/server-logs",className:"bg-[#161618] border border-[#26262b] rounded-xl p-5 hover:border-cyan-500/30 transition-colors",children:[(0,s.jsx)("h2",{className:"text-sm font-semibold text-gray-300",children:"Server Logs"}),(0,s.jsx)("p",{className:"text-xs text-gray-500 mt-2",children:"Live stdout / stderr from the CommHub server."}),(0,s.jsx)("span",{className:"text-xs text-cyan-400 mt-3 inline-block",children:"Open →"})]})]})]})]})]})}])}]);
|