@sleep2agi/agent-network-dashboard 0.6.3-preview.56 → 0.6.3-preview.58
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 +9 -0
- package/.next/build-manifest.json +3 -3
- package/.next/diagnostics/route-bundle-stats.json +143 -93
- package/.next/fallback-build-manifest.json +3 -3
- package/.next/next-server.js.nft.json +1 -1
- package/.next/prerender-manifest.json +75 -19
- package/.next/required-server-files.js +4 -4
- package/.next/required-server-files.json +4 -4
- package/.next/routes-manifest.json +63 -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/_tree.segment.rsc +1 -1
- package/.next/server/app/_not-found/page.js.nft.json +1 -1
- package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/.next/server/app/_not-found.html +2 -2
- package/.next/server/app/_not-found.rsc +14 -14
- package/.next/server/app/_not-found.segments/_full.segment.rsc +14 -14
- package/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +13 -13
- package/.next/server/app/_not-found.segments/_tree.segment.rsc +3 -3
- package/.next/server/app/admin/page.js.nft.json +1 -1
- package/.next/server/app/admin/page_client-reference-manifest.js +1 -1
- package/.next/server/app/admin.html +2 -2
- package/.next/server/app/admin.rsc +16 -16
- package/.next/server/app/admin.segments/_full.segment.rsc +16 -16
- package/.next/server/app/admin.segments/_tree.segment.rsc +3 -3
- package/.next/server/app/admin.segments/admin/__PAGE__.segment.rsc +15 -15
- package/.next/server/app/api/anet/host-supervisors/route.js.nft.json +1 -1
- package/.next/server/app/api/anet/node-config/route.js +1 -1
- package/.next/server/app/api/anet/node-config/route.js.nft.json +1 -1
- package/.next/server/app/api/hub/people/route/app-paths-manifest.json +3 -0
- package/.next/server/app/api/hub/people/route/build-manifest.json +12 -0
- package/.next/server/app/api/hub/people/route/server-reference-manifest.json +4 -0
- package/.next/server/app/api/hub/people/route.js +7 -0
- package/.next/server/app/api/hub/people/route.js.map +5 -0
- package/.next/server/app/api/hub/people/route.js.nft.json +1 -0
- package/.next/server/app/api/hub/people/route_client-reference-manifest.js +3 -0
- package/.next/server/app/api/hub/requirements/[id]/checklist/[itemId]/route/app-paths-manifest.json +3 -0
- package/.next/server/app/api/hub/requirements/[id]/checklist/[itemId]/route/build-manifest.json +12 -0
- package/.next/server/app/api/hub/requirements/[id]/checklist/[itemId]/route/server-reference-manifest.json +4 -0
- package/.next/server/app/api/hub/requirements/[id]/checklist/[itemId]/route.js +7 -0
- package/.next/server/app/api/hub/requirements/[id]/checklist/[itemId]/route.js.map +5 -0
- package/.next/server/app/api/hub/requirements/[id]/checklist/[itemId]/route.js.nft.json +1 -0
- package/.next/server/app/api/hub/requirements/[id]/checklist/[itemId]/route_client-reference-manifest.js +3 -0
- package/.next/server/app/api/hub/requirements/[id]/comments/route/app-paths-manifest.json +3 -0
- package/.next/server/app/api/hub/requirements/[id]/comments/route/build-manifest.json +12 -0
- package/.next/server/app/api/hub/requirements/[id]/comments/route/server-reference-manifest.json +4 -0
- package/.next/server/app/api/hub/requirements/[id]/comments/route.js +7 -0
- package/.next/server/app/api/hub/requirements/[id]/comments/route.js.map +5 -0
- package/.next/server/app/api/hub/requirements/[id]/comments/route.js.nft.json +1 -0
- package/.next/server/app/api/hub/requirements/[id]/comments/route_client-reference-manifest.js +3 -0
- package/.next/server/app/api/hub/requirements/[id]/route/app-paths-manifest.json +3 -0
- package/.next/server/app/api/hub/requirements/[id]/route/build-manifest.json +12 -0
- package/.next/server/app/api/hub/requirements/[id]/route/server-reference-manifest.json +4 -0
- package/.next/server/app/api/hub/requirements/[id]/route.js +7 -0
- package/.next/server/app/api/hub/requirements/[id]/route.js.map +5 -0
- package/.next/server/app/api/hub/requirements/[id]/route.js.nft.json +1 -0
- package/.next/server/app/api/hub/requirements/[id]/route_client-reference-manifest.js +3 -0
- package/.next/server/app/api/hub/requirements/events/route/app-paths-manifest.json +3 -0
- package/.next/server/app/api/hub/requirements/events/route/build-manifest.json +12 -0
- package/.next/server/app/api/hub/requirements/events/route/server-reference-manifest.json +4 -0
- package/.next/server/app/api/hub/requirements/events/route.js +7 -0
- package/.next/server/app/api/hub/requirements/events/route.js.map +5 -0
- package/.next/server/app/api/hub/requirements/events/route.js.nft.json +1 -0
- package/.next/server/app/api/hub/requirements/events/route_client-reference-manifest.js +3 -0
- package/.next/server/app/api/hub/requirements/route/app-paths-manifest.json +3 -0
- package/.next/server/app/api/hub/requirements/route/build-manifest.json +12 -0
- package/.next/server/app/api/hub/requirements/route/server-reference-manifest.json +4 -0
- package/.next/server/app/api/hub/requirements/route.js +7 -0
- package/.next/server/app/api/hub/requirements/route.js.map +5 -0
- package/.next/server/app/api/hub/requirements/route.js.nft.json +1 -0
- package/.next/server/app/api/hub/requirements/route_client-reference-manifest.js +3 -0
- package/.next/server/app/index.html +2 -2
- package/.next/server/app/index.rsc +16 -16
- package/.next/server/app/index.segments/__PAGE__.segment.rsc +15 -15
- package/.next/server/app/index.segments/_full.segment.rsc +16 -16
- package/.next/server/app/index.segments/_tree.segment.rsc +3 -3
- package/.next/server/app/login/page.js.nft.json +1 -1
- package/.next/server/app/login/page_client-reference-manifest.js +1 -1
- package/.next/server/app/login.html +2 -2
- package/.next/server/app/login.rsc +16 -16
- package/.next/server/app/login.segments/_full.segment.rsc +16 -16
- package/.next/server/app/login.segments/_tree.segment.rsc +3 -3
- package/.next/server/app/login.segments/login/__PAGE__.segment.rsc +15 -15
- package/.next/server/app/logs/page.js.nft.json +1 -1
- package/.next/server/app/logs/page_client-reference-manifest.js +1 -1
- package/.next/server/app/logs.html +2 -2
- package/.next/server/app/logs.rsc +16 -16
- package/.next/server/app/logs.segments/_full.segment.rsc +16 -16
- package/.next/server/app/logs.segments/_tree.segment.rsc +3 -3
- package/.next/server/app/logs.segments/logs/__PAGE__.segment.rsc +15 -15
- package/.next/server/app/messages/page.js.nft.json +1 -1
- package/.next/server/app/messages/page_client-reference-manifest.js +1 -1
- package/.next/server/app/messages.html +2 -2
- package/.next/server/app/messages.rsc +16 -16
- package/.next/server/app/messages.segments/_full.segment.rsc +16 -16
- package/.next/server/app/messages.segments/_tree.segment.rsc +3 -3
- package/.next/server/app/messages.segments/messages/__PAGE__.segment.rsc +15 -15
- package/.next/server/app/node/page.js.nft.json +1 -1
- package/.next/server/app/node/page_client-reference-manifest.js +1 -1
- package/.next/server/app/node.html +2 -2
- package/.next/server/app/node.rsc +16 -16
- package/.next/server/app/node.segments/_full.segment.rsc +16 -16
- package/.next/server/app/node.segments/_tree.segment.rsc +3 -3
- package/.next/server/app/node.segments/node/__PAGE__.segment.rsc +15 -15
- package/.next/server/app/nodes/[alias]/page.js.nft.json +1 -1
- package/.next/server/app/nodes/[alias]/page_client-reference-manifest.js +1 -1
- package/.next/server/app/nodes/page.js.nft.json +1 -1
- package/.next/server/app/nodes/page_client-reference-manifest.js +1 -1
- package/.next/server/app/nodes.html +2 -2
- package/.next/server/app/nodes.rsc +16 -16
- package/.next/server/app/nodes.segments/_full.segment.rsc +16 -16
- package/.next/server/app/nodes.segments/_tree.segment.rsc +3 -3
- package/.next/server/app/nodes.segments/nodes/__PAGE__.segment.rsc +15 -15
- package/.next/server/app/org/page/app-paths-manifest.json +3 -0
- package/.next/server/app/org/page/build-manifest.json +20 -0
- package/.next/server/app/org/page/next-font-manifest.json +11 -0
- package/.next/server/app/org/page/react-loadable-manifest.json +1 -0
- package/.next/server/app/org/page/server-reference-manifest.json +4 -0
- package/.next/server/app/org/page.js +13 -0
- package/.next/server/app/org/page.js.map +5 -0
- package/.next/server/app/org/page.js.nft.json +1 -0
- package/.next/server/app/org/page_client-reference-manifest.js +3 -0
- package/.next/server/app/org.html +12 -0
- package/.next/server/app/org.meta +26 -0
- package/.next/server/app/org.rsc +27 -0
- package/.next/server/app/org.segments/_full.segment.rsc +27 -0
- package/.next/server/app/org.segments/_tree.segment.rsc +5 -0
- package/.next/server/app/org.segments/org/__PAGE__.segment.rsc +32 -0
- package/.next/server/app/page.js.nft.json +1 -1
- package/.next/server/app/page_client-reference-manifest.js +1 -1
- package/.next/server/app/providers/page.js.nft.json +1 -1
- package/.next/server/app/providers/page_client-reference-manifest.js +1 -1
- package/.next/server/app/providers.html +2 -2
- package/.next/server/app/providers.rsc +16 -16
- package/.next/server/app/providers.segments/_full.segment.rsc +16 -16
- package/.next/server/app/providers.segments/_tree.segment.rsc +3 -3
- package/.next/server/app/providers.segments/providers/__PAGE__.segment.rsc +15 -15
- package/.next/server/app/requirements/[id]/page/app-paths-manifest.json +3 -0
- package/.next/server/app/requirements/[id]/page/build-manifest.json +20 -0
- package/.next/server/app/requirements/[id]/page/next-font-manifest.json +11 -0
- package/.next/server/app/requirements/[id]/page/react-loadable-manifest.json +1 -0
- package/.next/server/app/requirements/[id]/page/server-reference-manifest.json +4 -0
- package/.next/server/app/requirements/[id]/page.js +13 -0
- package/.next/server/app/requirements/[id]/page.js.map +5 -0
- package/.next/server/app/requirements/[id]/page.js.nft.json +1 -0
- package/.next/server/app/requirements/[id]/page_client-reference-manifest.js +3 -0
- package/.next/server/app/requirements/page/app-paths-manifest.json +3 -0
- package/.next/server/app/requirements/page/build-manifest.json +20 -0
- package/.next/server/app/requirements/page/next-font-manifest.json +11 -0
- package/.next/server/app/requirements/page/react-loadable-manifest.json +1 -0
- package/.next/server/app/requirements/page/server-reference-manifest.json +4 -0
- package/.next/server/app/requirements/page.js +13 -0
- package/.next/server/app/requirements/page.js.map +5 -0
- package/.next/server/app/requirements/page.js.nft.json +1 -0
- package/.next/server/app/requirements/page_client-reference-manifest.js +3 -0
- package/.next/server/app/requirements.html +12 -0
- package/.next/server/app/requirements.meta +26 -0
- package/.next/server/app/requirements.rsc +27 -0
- package/.next/server/app/requirements.segments/_full.segment.rsc +27 -0
- package/.next/server/app/requirements.segments/_tree.segment.rsc +5 -0
- package/.next/server/app/requirements.segments/requirements/__PAGE__.segment.rsc +32 -0
- package/.next/server/app/scheduled-tasks/page.js.nft.json +1 -1
- package/.next/server/app/scheduled-tasks/page_client-reference-manifest.js +1 -1
- package/.next/server/app/scheduled-tasks.html +2 -2
- package/.next/server/app/scheduled-tasks.rsc +16 -16
- package/.next/server/app/scheduled-tasks.segments/_full.segment.rsc +16 -16
- package/.next/server/app/scheduled-tasks.segments/_tree.segment.rsc +3 -3
- package/.next/server/app/scheduled-tasks.segments/scheduled-tasks/__PAGE__.segment.rsc +15 -15
- package/.next/server/app/server-logs/page.js.nft.json +1 -1
- package/.next/server/app/server-logs/page_client-reference-manifest.js +1 -1
- package/.next/server/app/server-logs.html +2 -2
- package/.next/server/app/server-logs.rsc +16 -16
- package/.next/server/app/server-logs.segments/_full.segment.rsc +16 -16
- package/.next/server/app/server-logs.segments/_tree.segment.rsc +3 -3
- package/.next/server/app/server-logs.segments/server-logs/__PAGE__.segment.rsc +15 -15
- package/.next/server/app/servers/page.js.nft.json +1 -1
- package/.next/server/app/servers/page_client-reference-manifest.js +1 -1
- package/.next/server/app/servers.html +2 -2
- package/.next/server/app/servers.rsc +16 -16
- package/.next/server/app/servers.segments/_full.segment.rsc +16 -16
- package/.next/server/app/servers.segments/_tree.segment.rsc +3 -3
- package/.next/server/app/servers.segments/servers/__PAGE__.segment.rsc +15 -15
- package/.next/server/app/settings/networks/page.js.nft.json +1 -1
- package/.next/server/app/settings/networks/page_client-reference-manifest.js +1 -1
- package/.next/server/app/settings/networks.html +2 -2
- package/.next/server/app/settings/networks.rsc +16 -16
- package/.next/server/app/settings/networks.segments/_full.segment.rsc +16 -16
- package/.next/server/app/settings/networks.segments/_tree.segment.rsc +3 -3
- package/.next/server/app/settings/networks.segments/settings/networks/__PAGE__.segment.rsc +15 -15
- package/.next/server/app/settings/page.js.nft.json +1 -1
- package/.next/server/app/settings/page_client-reference-manifest.js +1 -1
- package/.next/server/app/settings/tokens/page.js.nft.json +1 -1
- package/.next/server/app/settings/tokens/page_client-reference-manifest.js +1 -1
- package/.next/server/app/settings/tokens.html +2 -2
- package/.next/server/app/settings/tokens.rsc +16 -16
- package/.next/server/app/settings/tokens.segments/_full.segment.rsc +16 -16
- package/.next/server/app/settings/tokens.segments/_tree.segment.rsc +3 -3
- package/.next/server/app/settings/tokens.segments/settings/tokens/__PAGE__.segment.rsc +15 -15
- package/.next/server/app/settings.html +2 -2
- package/.next/server/app/settings.rsc +16 -16
- package/.next/server/app/settings.segments/_full.segment.rsc +16 -16
- package/.next/server/app/settings.segments/_tree.segment.rsc +3 -3
- package/.next/server/app/settings.segments/settings/__PAGE__.segment.rsc +15 -15
- package/.next/server/app/skillhub/page.js.nft.json +1 -1
- package/.next/server/app/skillhub/page_client-reference-manifest.js +1 -1
- package/.next/server/app/skillhub.html +2 -2
- package/.next/server/app/skillhub.rsc +16 -16
- package/.next/server/app/skillhub.segments/_full.segment.rsc +16 -16
- package/.next/server/app/skillhub.segments/_tree.segment.rsc +3 -3
- package/.next/server/app/skillhub.segments/skillhub/__PAGE__.segment.rsc +15 -15
- package/.next/server/app/tasks/[id]/page.js.nft.json +1 -1
- package/.next/server/app/tasks/[id]/page_client-reference-manifest.js +1 -1
- package/.next/server/app/tasks/page.js.nft.json +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 +16 -16
- package/.next/server/app/tasks.segments/_full.segment.rsc +16 -16
- package/.next/server/app/tasks.segments/_tree.segment.rsc +3 -3
- package/.next/server/app/tasks.segments/tasks/__PAGE__.segment.rsc +15 -15
- package/.next/server/app-paths-manifest.json +9 -0
- package/.next/server/chunks/1oeh_server_app_api_hub_requirements_[id]_checklist_[itemId]_route_actions_05mpe5a.js +3 -0
- package/.next/server/chunks/1oeh_server_app_api_hub_requirements_[id]_checklist_[itemId]_route_actions_05mpe5a.js.map +1 -0
- package/.next/server/chunks/1oeh_server_app_api_hub_requirements_[id]_comments_route_actions_1lv4qr1.js +3 -0
- package/.next/server/chunks/1oeh_server_app_api_hub_requirements_[id]_comments_route_actions_1lv4qr1.js.map +1 -0
- package/.next/server/chunks/[root-of-the-server]__0-wvy_a._.js +1 -1
- package/.next/server/chunks/[root-of-the-server]__0-wvy_a._.js.map +1 -1
- package/.next/server/chunks/[root-of-the-server]__053z4wp._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__053z4wp._.js.map +1 -0
- package/.next/server/chunks/[root-of-the-server]__0if0bw1._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__0if0bw1._.js.map +1 -0
- package/.next/server/chunks/[root-of-the-server]__0liwkmx._.js +1 -1
- package/.next/server/chunks/[root-of-the-server]__0liwkmx._.js.map +1 -1
- package/.next/server/chunks/[root-of-the-server]__0q9xwca._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__0q9xwca._.js.map +1 -0
- package/.next/server/chunks/[root-of-the-server]__1941b2h._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__1941b2h._.js.map +1 -0
- package/.next/server/chunks/[root-of-the-server]__1_rzyvn._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__1_rzyvn._.js.map +1 -0
- package/.next/server/chunks/[root-of-the-server]__1vua9gf._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__1vua9gf._.js.map +1 -0
- package/.next/server/chunks/_05lpz54._.js +1 -1
- package/.next/server/chunks/_05lpz54._.js.map +1 -1
- package/.next/server/chunks/_next-internal_server_app_api_hub_people_route_actions_01pw78e.js +3 -0
- package/.next/server/chunks/_next-internal_server_app_api_hub_people_route_actions_01pw78e.js.map +1 -0
- package/.next/server/chunks/_next-internal_server_app_api_hub_requirements_[id]_route_actions_1jkq5c6.js +3 -0
- package/.next/server/chunks/_next-internal_server_app_api_hub_requirements_[id]_route_actions_1jkq5c6.js.map +1 -0
- package/.next/server/chunks/_next-internal_server_app_api_hub_requirements_events_route_actions_1ypnpu5.js +3 -0
- package/.next/server/chunks/_next-internal_server_app_api_hub_requirements_events_route_actions_1ypnpu5.js.map +1 -0
- package/.next/server/chunks/_next-internal_server_app_api_hub_requirements_route_actions_1lyeno6.js +3 -0
- package/.next/server/chunks/_next-internal_server_app_api_hub_requirements_route_actions_1lyeno6.js.map +1 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__0-94ipy._.js +3 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__0-94ipy._.js.map +1 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__09n7eih._.js +3 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__09n7eih._.js.map +1 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__0ol09h3._.js +3 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__0ol09h3._.js.map +1 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__14k36ti._.js +3 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__14k36ti._.js.map +1 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__1bn1jjm._.js +3 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__1bn1jjm._.js.map +1 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__1ovdbox._.js +1 -1
- package/.next/server/chunks/ssr/[root-of-the-server]__1ovdbox._.js.map +1 -1
- package/.next/server/chunks/ssr/_0q4m25o._.js +0 -0
- package/.next/server/chunks/ssr/_0q4m25o._.js.map +1 -1
- package/.next/server/chunks/ssr/_1z1o6o3._.js +0 -0
- package/.next/server/chunks/ssr/_1z1o6o3._.js.map +1 -1
- package/.next/server/chunks/ssr/_next-internal_server_app_org_page_actions_0hbcef1.js +3 -0
- package/.next/server/chunks/ssr/_next-internal_server_app_org_page_actions_0hbcef1.js.map +1 -0
- package/.next/server/chunks/ssr/_next-internal_server_app_requirements_[id]_page_actions_1wjoy4l.js +3 -0
- package/.next/server/chunks/ssr/_next-internal_server_app_requirements_[id]_page_actions_1wjoy4l.js.map +1 -0
- package/.next/server/chunks/ssr/_next-internal_server_app_requirements_page_actions_0x9m0gy.js +3 -0
- package/.next/server/chunks/ssr/_next-internal_server_app_requirements_page_actions_0x9m0gy.js.map +1 -0
- package/.next/server/chunks/ssr/app_05mfyco._.js +3 -0
- package/.next/server/chunks/ssr/app_05mfyco._.js.map +1 -0
- package/.next/server/chunks/ssr/{app_0_s8u96._.js → app_07bzc6w._.js} +1 -1
- package/.next/server/chunks/ssr/app_099f0wg._.js +3 -0
- package/.next/server/chunks/ssr/app_099f0wg._.js.map +1 -0
- package/.next/server/chunks/ssr/{app_1oxcq68._.js → app_0g7oz9w._.js} +1 -1
- package/.next/server/chunks/ssr/app_0iz553k._.js +1 -1
- package/.next/server/chunks/ssr/app_0iz553k._.js.map +1 -1
- package/.next/server/chunks/ssr/app_0los-eu._.js +1 -1
- package/.next/server/chunks/ssr/app_0los-eu._.js.map +1 -1
- package/.next/server/chunks/ssr/{app_0x7s72b._.js → app_0tt2ueo._.js} +1 -1
- package/.next/server/chunks/ssr/{app_081zy6c._.js → app_0ugqkd7._.js} +1 -1
- package/.next/server/chunks/ssr/app_1auk3il._.js +11 -0
- package/.next/server/chunks/ssr/app_1auk3il._.js.map +1 -0
- package/.next/server/chunks/ssr/{app_0o4bxq0._.js → app_1e91uc-._.js} +1 -1
- package/.next/server/chunks/ssr/{app_1psh956._.js → app_1f96aq_._.js} +1 -1
- package/.next/server/chunks/ssr/app_1rma_8a._.js +11 -0
- package/.next/server/chunks/ssr/app_1rma_8a._.js.map +1 -0
- package/.next/server/chunks/ssr/{app_0_dhiwi._.js → app_1ua57bx._.js} +1 -1
- package/.next/server/chunks/ssr/app_components_04a31va._.js +1 -1
- package/.next/server/chunks/ssr/app_components_04a31va._.js.map +1 -1
- package/.next/server/chunks/ssr/{app_lib_10o69j_._.js → app_lib_20-pe_0._.js} +2 -2
- package/.next/server/chunks/ssr/{app_lib_10o69j_._.js.map → app_lib_20-pe_0._.js.map} +1 -1
- package/.next/server/chunks/ssr/app_nodes_NodesView_tsx_1w6_d8p._.js +2 -2
- package/.next/server/chunks/ssr/app_nodes_NodesView_tsx_1w6_d8p._.js.map +1 -1
- package/.next/server/chunks/ssr/app_page_tsx_0pxmutw._.js +1 -1
- package/.next/server/chunks/ssr/app_page_tsx_0pxmutw._.js.map +1 -1
- package/.next/server/chunks/ssr/app_scheduled-tasks_page_tsx_0xs70_6._.js +1 -1
- package/.next/server/chunks/ssr/app_scheduled-tasks_page_tsx_0xs70_6._.js.map +1 -1
- package/.next/server/chunks/ssr/app_tasks_TasksView_tsx_068vqml._.js +1 -1
- package/.next/server/chunks/ssr/app_tasks_TasksView_tsx_068vqml._.js.map +1 -1
- package/.next/server/functions-config-manifest.json +4 -0
- package/.next/server/middleware-build-manifest.js +3 -3
- package/.next/server/middleware.js.nft.json +1 -1
- package/.next/server/next-font-manifest.js +1 -1
- package/.next/server/next-font-manifest.json +12 -0
- package/.next/server/pages/404.html +2 -2
- package/.next/server/pages/500.html +1 -1
- package/.next/server/prefetch-hints.json +28 -0
- package/.next/server/server-reference-manifest.js +1 -1
- package/.next/server/server-reference-manifest.json +1 -1
- package/.next/static/{trj9RsCWuEDMfq9BuoKfl → FEaCQpBc05SBAWTBHRt5h}/_clientMiddlewareManifest.js +4 -0
- package/.next/static/chunks/{27b9kqyo7bmdr.js → 08-obrj2goweb.js} +2 -2
- package/.next/static/chunks/0fih4pzed1syn.js +9 -0
- package/.next/static/chunks/0iiu4-g5k8jcq.js +1 -0
- package/.next/static/chunks/{37booeyruo9_l.js → 0iz44n632kw4w.js} +1 -1
- package/.next/static/chunks/0jt-1caejz1jv.js +1 -0
- package/.next/static/chunks/0k-4980o5t7_r.css +1 -0
- package/.next/static/chunks/{0agh8mvmpke4j.js → 0z9tzvfwtc16z.js} +1 -1
- package/.next/static/chunks/114pblaedlrqs.js +1 -0
- package/.next/static/chunks/1tcaw8g6u6o-4.js +1 -0
- package/.next/static/chunks/1v5-qgib9884o.js +0 -0
- package/.next/static/chunks/{02303d1rbqx74.js → 2-x9r-1t3c1mn.js} +1 -1
- package/.next/static/chunks/{28o3ssg0_q2n-.js → 26bpf-fpc6zpt.js} +1 -1
- package/.next/static/chunks/2anlzel60my8y.js +2 -0
- package/.next/static/chunks/{3jxk7q1jxyvol.js → 2divamiv1re3v.js} +1 -1
- package/.next/static/chunks/3cb3_kcec7bms.js +1 -0
- package/.next/static/chunks/{233p45nuh4m5b.css → 3d-1vk5hzu5rq.css} +2 -2
- package/.next/static/chunks/3u059pjgl4gcw.js +1 -0
- package/.next/static/chunks/3vv0y_64bnnsf.js +1 -0
- package/.next/trace +2 -2
- package/.next/trace-build +1 -1
- package/.next/types/routes.d.ts +11 -2
- package/.next/types/validator.ts +81 -0
- package/.vercel/.env.development.local +2 -0
- package/.vercel/.env.production.local +25 -0
- package/.vercel/README.txt +11 -0
- package/.vercel/output/builds.json +23 -0
- package/.vercel/output/config.json +489 -0
- package/.vercel/output/diagnostics/build-diagnostics.json +6 -0
- package/.vercel/output/diagnostics/cli_traces.json +1 -0
- package/.vercel/output/diagnostics/framework.json +1 -0
- package/.vercel/output/diagnostics/route-bundle-stats.json +245 -0
- package/.vercel/output/diagnostics/trace +2 -0
- package/.vercel/output/diagnostics/trace-build +1 -0
- package/.vercel/output/diagnostics/turbopack +0 -0
- package/.vercel/output/functions/_global-error.prerender-config.json +38 -0
- package/.vercel/output/functions/_global-error.prerender-fallback.html +1 -0
- package/.vercel/output/functions/_global-error.rsc.func/.next/routes-manifest.json +1 -0
- package/.vercel/output/functions/_global-error.rsc.func/.next/server/app-paths-manifest.json +1 -0
- package/.vercel/output/functions/_global-error.rsc.func/.next/server/pages-manifest.json +1 -0
- package/.vercel/output/functions/_global-error.rsc.func/.vc-config.json +807 -0
- package/.vercel/output/functions/_global-error.rsc.func/___next_launcher.cjs +68 -0
- package/.vercel/output/functions/_global-error.rsc.prerender-config.json +38 -0
- package/.vercel/output/functions/_global-error.rsc.prerender-fallback.rsc +15 -0
- package/.vercel/output/functions/_global-error.segments/__PAGE__.segment.rsc.prerender-config.json +28 -0
- package/.vercel/output/functions/_global-error.segments/__PAGE__.segment.rsc.prerender-fallback.rsc +5 -0
- package/.vercel/output/functions/_global-error.segments/_full.segment.rsc.prerender-config.json +28 -0
- package/.vercel/output/functions/_global-error.segments/_full.segment.rsc.prerender-fallback.rsc +15 -0
- package/.vercel/output/functions/_global-error.segments/_head.segment.rsc.prerender-config.json +28 -0
- package/.vercel/output/functions/_global-error.segments/_head.segment.rsc.prerender-fallback.rsc +6 -0
- package/.vercel/output/functions/_global-error.segments/_index.segment.rsc.prerender-config.json +28 -0
- package/.vercel/output/functions/_global-error.segments/_index.segment.rsc.prerender-fallback.rsc +5 -0
- package/.vercel/output/functions/_global-error.segments/_tree.segment.rsc.prerender-config.json +28 -0
- package/.vercel/output/functions/_global-error.segments/_tree.segment.rsc.prerender-fallback.rsc +1 -0
- package/.vercel/output/functions/_middleware.func/.vc-config.json +107 -0
- package/.vercel/output/functions/_middleware.func/___next_launcher.cjs +135 -0
- package/.vercel/output/functions/_not-found.prerender-config.json +38 -0
- package/.vercel/output/functions/_not-found.prerender-fallback.html +12 -0
- package/.vercel/output/functions/_not-found.rsc.prerender-config.json +38 -0
- package/.vercel/output/functions/_not-found.rsc.prerender-fallback.rsc +21 -0
- package/.vercel/output/functions/_not-found.segments/_full.segment.rsc.prerender-config.json +28 -0
- package/.vercel/output/functions/_not-found.segments/_full.segment.rsc.prerender-fallback.rsc +21 -0
- package/.vercel/output/functions/_not-found.segments/_head.segment.rsc.prerender-config.json +28 -0
- package/.vercel/output/functions/_not-found.segments/_head.segment.rsc.prerender-fallback.rsc +6 -0
- package/.vercel/output/functions/_not-found.segments/_index.segment.rsc.prerender-config.json +28 -0
- package/.vercel/output/functions/_not-found.segments/_index.segment.rsc.prerender-fallback.rsc +10 -0
- package/.vercel/output/functions/_not-found.segments/_not-found/__PAGE__.segment.rsc.prerender-config.json +28 -0
- package/.vercel/output/functions/_not-found.segments/_not-found/__PAGE__.segment.rsc.prerender-fallback.rsc +5 -0
- package/.vercel/output/functions/_not-found.segments/_not-found.segment.rsc.prerender-config.json +28 -0
- package/.vercel/output/functions/_not-found.segments/_not-found.segment.rsc.prerender-fallback.rsc +5 -0
- package/.vercel/output/functions/_not-found.segments/_tree.segment.rsc.prerender-config.json +28 -0
- package/.vercel/output/functions/_not-found.segments/_tree.segment.rsc.prerender-fallback.rsc +3 -0
- package/.vercel/output/functions/admin.prerender-config.json +37 -0
- package/.vercel/output/functions/admin.prerender-fallback.html +12 -0
- package/.vercel/output/functions/admin.rsc.prerender-config.json +38 -0
- package/.vercel/output/functions/admin.rsc.prerender-fallback.rsc +27 -0
- package/.vercel/output/functions/admin.segments/_full.segment.rsc.prerender-config.json +28 -0
- package/.vercel/output/functions/admin.segments/_full.segment.rsc.prerender-fallback.rsc +27 -0
- package/.vercel/output/functions/admin.segments/_head.segment.rsc.prerender-config.json +28 -0
- package/.vercel/output/functions/admin.segments/_head.segment.rsc.prerender-fallback.rsc +6 -0
- package/.vercel/output/functions/admin.segments/_index.segment.rsc.prerender-config.json +28 -0
- package/.vercel/output/functions/admin.segments/_index.segment.rsc.prerender-fallback.rsc +10 -0
- package/.vercel/output/functions/admin.segments/_tree.segment.rsc.prerender-config.json +28 -0
- package/.vercel/output/functions/admin.segments/_tree.segment.rsc.prerender-fallback.rsc +5 -0
- package/.vercel/output/functions/admin.segments/admin/__PAGE__.segment.rsc.prerender-config.json +28 -0
- package/.vercel/output/functions/admin.segments/admin/__PAGE__.segment.rsc.prerender-fallback.rsc +9 -0
- package/.vercel/output/functions/admin.segments/admin.segment.rsc.prerender-config.json +28 -0
- package/.vercel/output/functions/admin.segments/admin.segment.rsc.prerender-fallback.rsc +5 -0
- package/.vercel/output/functions/api/anet/config.func/.next/routes-manifest.json +1 -0
- package/.vercel/output/functions/api/anet/config.func/.next/server/app-paths-manifest.json +1 -0
- package/.vercel/output/functions/api/anet/config.func/.next/server/pages-manifest.json +1 -0
- package/.vercel/output/functions/api/anet/config.func/.vc-config.json +818 -0
- package/.vercel/output/functions/api/anet/config.func/___next_launcher.cjs +68 -0
- package/.vercel/output/functions/index.prerender-config.json +38 -0
- package/.vercel/output/functions/index.prerender-fallback.html +12 -0
- package/.vercel/output/functions/index.rsc.prerender-config.json +38 -0
- package/.vercel/output/functions/index.rsc.prerender-fallback.rsc +25 -0
- package/.vercel/output/functions/index.segments/__PAGE__.segment.rsc.prerender-config.json +28 -0
- package/.vercel/output/functions/index.segments/__PAGE__.segment.rsc.prerender-fallback.rsc +9 -0
- package/.vercel/output/functions/index.segments/_full.segment.rsc.prerender-config.json +28 -0
- package/.vercel/output/functions/index.segments/_full.segment.rsc.prerender-fallback.rsc +25 -0
- package/.vercel/output/functions/index.segments/_head.segment.rsc.prerender-config.json +28 -0
- package/.vercel/output/functions/index.segments/_head.segment.rsc.prerender-fallback.rsc +6 -0
- package/.vercel/output/functions/index.segments/_index.segment.rsc.prerender-config.json +28 -0
- package/.vercel/output/functions/index.segments/_index.segment.rsc.prerender-fallback.rsc +10 -0
- package/.vercel/output/functions/index.segments/_tree.segment.rsc.prerender-config.json +28 -0
- package/.vercel/output/functions/index.segments/_tree.segment.rsc.prerender-fallback.rsc +5 -0
- package/.vercel/output/functions/login.prerender-config.json +37 -0
- package/.vercel/output/functions/login.prerender-fallback.html +6 -0
- package/.vercel/output/functions/login.rsc.prerender-config.json +38 -0
- package/.vercel/output/functions/login.rsc.prerender-fallback.rsc +27 -0
- package/.vercel/output/functions/login.segments/_full.segment.rsc.prerender-config.json +28 -0
- package/.vercel/output/functions/login.segments/_full.segment.rsc.prerender-fallback.rsc +27 -0
- package/.vercel/output/functions/login.segments/_head.segment.rsc.prerender-config.json +28 -0
- package/.vercel/output/functions/login.segments/_head.segment.rsc.prerender-fallback.rsc +6 -0
- package/.vercel/output/functions/login.segments/_index.segment.rsc.prerender-config.json +28 -0
- package/.vercel/output/functions/login.segments/_index.segment.rsc.prerender-fallback.rsc +10 -0
- package/.vercel/output/functions/login.segments/_tree.segment.rsc.prerender-config.json +28 -0
- package/.vercel/output/functions/login.segments/_tree.segment.rsc.prerender-fallback.rsc +5 -0
- package/.vercel/output/functions/login.segments/login/__PAGE__.segment.rsc.prerender-config.json +28 -0
- package/.vercel/output/functions/login.segments/login/__PAGE__.segment.rsc.prerender-fallback.rsc +9 -0
- package/.vercel/output/functions/login.segments/login.segment.rsc.prerender-config.json +28 -0
- package/.vercel/output/functions/login.segments/login.segment.rsc.prerender-fallback.rsc +5 -0
- package/.vercel/output/functions/logs.prerender-config.json +37 -0
- package/.vercel/output/functions/logs.prerender-fallback.html +12 -0
- package/.vercel/output/functions/logs.rsc.prerender-config.json +38 -0
- package/.vercel/output/functions/logs.rsc.prerender-fallback.rsc +27 -0
- package/.vercel/output/functions/logs.segments/_full.segment.rsc.prerender-config.json +28 -0
- package/.vercel/output/functions/logs.segments/_full.segment.rsc.prerender-fallback.rsc +27 -0
- package/.vercel/output/functions/logs.segments/_head.segment.rsc.prerender-config.json +28 -0
- package/.vercel/output/functions/logs.segments/_head.segment.rsc.prerender-fallback.rsc +6 -0
- package/.vercel/output/functions/logs.segments/_index.segment.rsc.prerender-config.json +28 -0
- package/.vercel/output/functions/logs.segments/_index.segment.rsc.prerender-fallback.rsc +10 -0
- package/.vercel/output/functions/logs.segments/_tree.segment.rsc.prerender-config.json +28 -0
- package/.vercel/output/functions/logs.segments/_tree.segment.rsc.prerender-fallback.rsc +5 -0
- package/.vercel/output/functions/logs.segments/logs/__PAGE__.segment.rsc.prerender-config.json +28 -0
- package/.vercel/output/functions/logs.segments/logs/__PAGE__.segment.rsc.prerender-fallback.rsc +9 -0
- package/.vercel/output/functions/logs.segments/logs.segment.rsc.prerender-config.json +28 -0
- package/.vercel/output/functions/logs.segments/logs.segment.rsc.prerender-fallback.rsc +5 -0
- package/.vercel/output/functions/manifest.webmanifest.func/.next/routes-manifest.json +1 -0
- package/.vercel/output/functions/manifest.webmanifest.func/.next/server/app-paths-manifest.json +1 -0
- package/.vercel/output/functions/manifest.webmanifest.func/.next/server/pages-manifest.json +1 -0
- package/.vercel/output/functions/manifest.webmanifest.func/.vc-config.json +715 -0
- package/.vercel/output/functions/manifest.webmanifest.func/___next_launcher.cjs +68 -0
- package/.vercel/output/functions/manifest.webmanifest.prerender-config.json +38 -0
- package/.vercel/output/functions/manifest.webmanifest.prerender-fallback.body +1 -0
- package/.vercel/output/functions/messages.prerender-config.json +37 -0
- package/.vercel/output/functions/messages.prerender-fallback.html +12 -0
- package/.vercel/output/functions/messages.rsc.prerender-config.json +38 -0
- package/.vercel/output/functions/messages.rsc.prerender-fallback.rsc +27 -0
- package/.vercel/output/functions/messages.segments/_full.segment.rsc.prerender-config.json +28 -0
- package/.vercel/output/functions/messages.segments/_full.segment.rsc.prerender-fallback.rsc +27 -0
- package/.vercel/output/functions/messages.segments/_head.segment.rsc.prerender-config.json +28 -0
- package/.vercel/output/functions/messages.segments/_head.segment.rsc.prerender-fallback.rsc +6 -0
- package/.vercel/output/functions/messages.segments/_index.segment.rsc.prerender-config.json +28 -0
- package/.vercel/output/functions/messages.segments/_index.segment.rsc.prerender-fallback.rsc +10 -0
- package/.vercel/output/functions/messages.segments/_tree.segment.rsc.prerender-config.json +28 -0
- package/.vercel/output/functions/messages.segments/_tree.segment.rsc.prerender-fallback.rsc +5 -0
- package/.vercel/output/functions/messages.segments/messages/__PAGE__.segment.rsc.prerender-config.json +28 -0
- package/.vercel/output/functions/messages.segments/messages/__PAGE__.segment.rsc.prerender-fallback.rsc +9 -0
- package/.vercel/output/functions/messages.segments/messages.segment.rsc.prerender-config.json +28 -0
- package/.vercel/output/functions/messages.segments/messages.segment.rsc.prerender-fallback.rsc +5 -0
- package/.vercel/output/functions/node.prerender-config.json +37 -0
- package/.vercel/output/functions/node.prerender-fallback.html +12 -0
- package/.vercel/output/functions/node.rsc.prerender-config.json +38 -0
- package/.vercel/output/functions/node.rsc.prerender-fallback.rsc +27 -0
- package/.vercel/output/functions/node.segments/_full.segment.rsc.prerender-config.json +28 -0
- package/.vercel/output/functions/node.segments/_full.segment.rsc.prerender-fallback.rsc +27 -0
- package/.vercel/output/functions/node.segments/_head.segment.rsc.prerender-config.json +28 -0
- package/.vercel/output/functions/node.segments/_head.segment.rsc.prerender-fallback.rsc +6 -0
- package/.vercel/output/functions/node.segments/_index.segment.rsc.prerender-config.json +28 -0
- package/.vercel/output/functions/node.segments/_index.segment.rsc.prerender-fallback.rsc +10 -0
- package/.vercel/output/functions/node.segments/_tree.segment.rsc.prerender-config.json +28 -0
- package/.vercel/output/functions/node.segments/_tree.segment.rsc.prerender-fallback.rsc +5 -0
- package/.vercel/output/functions/node.segments/node/__PAGE__.segment.rsc.prerender-config.json +28 -0
- package/.vercel/output/functions/node.segments/node/__PAGE__.segment.rsc.prerender-fallback.rsc +9 -0
- package/.vercel/output/functions/node.segments/node.segment.rsc.prerender-config.json +28 -0
- package/.vercel/output/functions/node.segments/node.segment.rsc.prerender-fallback.rsc +5 -0
- package/.vercel/output/functions/nodes.prerender-config.json +37 -0
- package/.vercel/output/functions/nodes.prerender-fallback.html +12 -0
- package/.vercel/output/functions/nodes.rsc.prerender-config.json +38 -0
- package/.vercel/output/functions/nodes.rsc.prerender-fallback.rsc +27 -0
- package/.vercel/output/functions/nodes.segments/_full.segment.rsc.prerender-config.json +28 -0
- package/.vercel/output/functions/nodes.segments/_full.segment.rsc.prerender-fallback.rsc +27 -0
- package/.vercel/output/functions/nodes.segments/_head.segment.rsc.prerender-config.json +28 -0
- package/.vercel/output/functions/nodes.segments/_head.segment.rsc.prerender-fallback.rsc +6 -0
- package/.vercel/output/functions/nodes.segments/_index.segment.rsc.prerender-config.json +28 -0
- package/.vercel/output/functions/nodes.segments/_index.segment.rsc.prerender-fallback.rsc +10 -0
- package/.vercel/output/functions/nodes.segments/_tree.segment.rsc.prerender-config.json +28 -0
- package/.vercel/output/functions/nodes.segments/_tree.segment.rsc.prerender-fallback.rsc +5 -0
- package/.vercel/output/functions/nodes.segments/nodes/__PAGE__.segment.rsc.prerender-config.json +28 -0
- package/.vercel/output/functions/nodes.segments/nodes/__PAGE__.segment.rsc.prerender-fallback.rsc +9 -0
- package/.vercel/output/functions/nodes.segments/nodes.segment.rsc.prerender-config.json +28 -0
- package/.vercel/output/functions/nodes.segments/nodes.segment.rsc.prerender-fallback.rsc +5 -0
- package/.vercel/output/functions/server-logs.prerender-config.json +37 -0
- package/.vercel/output/functions/server-logs.prerender-fallback.html +12 -0
- package/.vercel/output/functions/server-logs.rsc.prerender-config.json +38 -0
- package/.vercel/output/functions/server-logs.rsc.prerender-fallback.rsc +27 -0
- package/.vercel/output/functions/server-logs.segments/_full.segment.rsc.prerender-config.json +28 -0
- package/.vercel/output/functions/server-logs.segments/_full.segment.rsc.prerender-fallback.rsc +27 -0
- package/.vercel/output/functions/server-logs.segments/_head.segment.rsc.prerender-config.json +28 -0
- package/.vercel/output/functions/server-logs.segments/_head.segment.rsc.prerender-fallback.rsc +6 -0
- package/.vercel/output/functions/server-logs.segments/_index.segment.rsc.prerender-config.json +28 -0
- package/.vercel/output/functions/server-logs.segments/_index.segment.rsc.prerender-fallback.rsc +10 -0
- package/.vercel/output/functions/server-logs.segments/_tree.segment.rsc.prerender-config.json +28 -0
- package/.vercel/output/functions/server-logs.segments/_tree.segment.rsc.prerender-fallback.rsc +5 -0
- package/.vercel/output/functions/server-logs.segments/server-logs/__PAGE__.segment.rsc.prerender-config.json +28 -0
- package/.vercel/output/functions/server-logs.segments/server-logs/__PAGE__.segment.rsc.prerender-fallback.rsc +9 -0
- package/.vercel/output/functions/server-logs.segments/server-logs.segment.rsc.prerender-config.json +28 -0
- package/.vercel/output/functions/server-logs.segments/server-logs.segment.rsc.prerender-fallback.rsc +5 -0
- package/.vercel/output/functions/servers.prerender-config.json +37 -0
- package/.vercel/output/functions/servers.prerender-fallback.html +12 -0
- package/.vercel/output/functions/servers.rsc.prerender-config.json +38 -0
- package/.vercel/output/functions/servers.rsc.prerender-fallback.rsc +27 -0
- package/.vercel/output/functions/servers.segments/_full.segment.rsc.prerender-config.json +28 -0
- package/.vercel/output/functions/servers.segments/_full.segment.rsc.prerender-fallback.rsc +27 -0
- package/.vercel/output/functions/servers.segments/_head.segment.rsc.prerender-config.json +28 -0
- package/.vercel/output/functions/servers.segments/_head.segment.rsc.prerender-fallback.rsc +6 -0
- package/.vercel/output/functions/servers.segments/_index.segment.rsc.prerender-config.json +28 -0
- package/.vercel/output/functions/servers.segments/_index.segment.rsc.prerender-fallback.rsc +10 -0
- package/.vercel/output/functions/servers.segments/_tree.segment.rsc.prerender-config.json +28 -0
- package/.vercel/output/functions/servers.segments/_tree.segment.rsc.prerender-fallback.rsc +5 -0
- package/.vercel/output/functions/servers.segments/servers/__PAGE__.segment.rsc.prerender-config.json +28 -0
- package/.vercel/output/functions/servers.segments/servers/__PAGE__.segment.rsc.prerender-fallback.rsc +9 -0
- package/.vercel/output/functions/servers.segments/servers.segment.rsc.prerender-config.json +28 -0
- package/.vercel/output/functions/servers.segments/servers.segment.rsc.prerender-fallback.rsc +5 -0
- package/.vercel/output/functions/settings/networks.prerender-config.json +37 -0
- package/.vercel/output/functions/settings/networks.prerender-fallback.html +12 -0
- package/.vercel/output/functions/settings/networks.rsc.prerender-config.json +38 -0
- package/.vercel/output/functions/settings/networks.rsc.prerender-fallback.rsc +27 -0
- package/.vercel/output/functions/settings/networks.segments/_full.segment.rsc.prerender-config.json +28 -0
- package/.vercel/output/functions/settings/networks.segments/_full.segment.rsc.prerender-fallback.rsc +27 -0
- package/.vercel/output/functions/settings/networks.segments/_head.segment.rsc.prerender-config.json +28 -0
- package/.vercel/output/functions/settings/networks.segments/_head.segment.rsc.prerender-fallback.rsc +6 -0
- package/.vercel/output/functions/settings/networks.segments/_index.segment.rsc.prerender-config.json +28 -0
- package/.vercel/output/functions/settings/networks.segments/_index.segment.rsc.prerender-fallback.rsc +10 -0
- package/.vercel/output/functions/settings/networks.segments/_tree.segment.rsc.prerender-config.json +28 -0
- package/.vercel/output/functions/settings/networks.segments/_tree.segment.rsc.prerender-fallback.rsc +5 -0
- package/.vercel/output/functions/settings/networks.segments/settings/networks/__PAGE__.segment.rsc.prerender-config.json +28 -0
- package/.vercel/output/functions/settings/networks.segments/settings/networks/__PAGE__.segment.rsc.prerender-fallback.rsc +9 -0
- package/.vercel/output/functions/settings/networks.segments/settings/networks.segment.rsc.prerender-config.json +28 -0
- package/.vercel/output/functions/settings/networks.segments/settings/networks.segment.rsc.prerender-fallback.rsc +5 -0
- package/.vercel/output/functions/settings/networks.segments/settings.segment.rsc.prerender-config.json +28 -0
- package/.vercel/output/functions/settings/networks.segments/settings.segment.rsc.prerender-fallback.rsc +5 -0
- package/.vercel/output/functions/settings/tokens.prerender-config.json +37 -0
- package/.vercel/output/functions/settings/tokens.prerender-fallback.html +12 -0
- package/.vercel/output/functions/settings/tokens.rsc.prerender-config.json +38 -0
- package/.vercel/output/functions/settings/tokens.rsc.prerender-fallback.rsc +27 -0
- package/.vercel/output/functions/settings/tokens.segments/_full.segment.rsc.prerender-config.json +28 -0
- package/.vercel/output/functions/settings/tokens.segments/_full.segment.rsc.prerender-fallback.rsc +27 -0
- package/.vercel/output/functions/settings/tokens.segments/_head.segment.rsc.prerender-config.json +28 -0
- package/.vercel/output/functions/settings/tokens.segments/_head.segment.rsc.prerender-fallback.rsc +6 -0
- package/.vercel/output/functions/settings/tokens.segments/_index.segment.rsc.prerender-config.json +28 -0
- package/.vercel/output/functions/settings/tokens.segments/_index.segment.rsc.prerender-fallback.rsc +10 -0
- package/.vercel/output/functions/settings/tokens.segments/_tree.segment.rsc.prerender-config.json +28 -0
- package/.vercel/output/functions/settings/tokens.segments/_tree.segment.rsc.prerender-fallback.rsc +5 -0
- package/.vercel/output/functions/settings/tokens.segments/settings/tokens/__PAGE__.segment.rsc.prerender-config.json +28 -0
- package/.vercel/output/functions/settings/tokens.segments/settings/tokens/__PAGE__.segment.rsc.prerender-fallback.rsc +9 -0
- package/.vercel/output/functions/settings/tokens.segments/settings/tokens.segment.rsc.prerender-config.json +28 -0
- package/.vercel/output/functions/settings/tokens.segments/settings/tokens.segment.rsc.prerender-fallback.rsc +5 -0
- package/.vercel/output/functions/settings/tokens.segments/settings.segment.rsc.prerender-config.json +28 -0
- package/.vercel/output/functions/settings/tokens.segments/settings.segment.rsc.prerender-fallback.rsc +5 -0
- package/.vercel/output/functions/settings.prerender-config.json +37 -0
- package/.vercel/output/functions/settings.prerender-fallback.html +12 -0
- package/.vercel/output/functions/settings.rsc.prerender-config.json +38 -0
- package/.vercel/output/functions/settings.rsc.prerender-fallback.rsc +27 -0
- package/.vercel/output/functions/settings.segments/_full.segment.rsc.prerender-config.json +28 -0
- package/.vercel/output/functions/settings.segments/_full.segment.rsc.prerender-fallback.rsc +27 -0
- package/.vercel/output/functions/settings.segments/_head.segment.rsc.prerender-config.json +28 -0
- package/.vercel/output/functions/settings.segments/_head.segment.rsc.prerender-fallback.rsc +6 -0
- package/.vercel/output/functions/settings.segments/_index.segment.rsc.prerender-config.json +28 -0
- package/.vercel/output/functions/settings.segments/_index.segment.rsc.prerender-fallback.rsc +10 -0
- package/.vercel/output/functions/settings.segments/_tree.segment.rsc.prerender-config.json +28 -0
- package/.vercel/output/functions/settings.segments/_tree.segment.rsc.prerender-fallback.rsc +5 -0
- package/.vercel/output/functions/settings.segments/settings/__PAGE__.segment.rsc.prerender-config.json +28 -0
- package/.vercel/output/functions/settings.segments/settings/__PAGE__.segment.rsc.prerender-fallback.rsc +9 -0
- package/.vercel/output/functions/settings.segments/settings.segment.rsc.prerender-config.json +28 -0
- package/.vercel/output/functions/settings.segments/settings.segment.rsc.prerender-fallback.rsc +5 -0
- package/.vercel/output/functions/tasks/[id].func/.next/routes-manifest.json +1 -0
- package/.vercel/output/functions/tasks/[id].func/.next/server/app-paths-manifest.json +1 -0
- package/.vercel/output/functions/tasks/[id].func/.next/server/pages-manifest.json +1 -0
- package/.vercel/output/functions/tasks/[id].func/.vc-config.json +713 -0
- package/.vercel/output/functions/tasks/[id].func/___next_launcher.cjs +68 -0
- package/.vercel/output/functions/tasks.prerender-config.json +37 -0
- package/.vercel/output/functions/tasks.prerender-fallback.html +12 -0
- package/.vercel/output/functions/tasks.rsc.prerender-config.json +38 -0
- package/.vercel/output/functions/tasks.rsc.prerender-fallback.rsc +27 -0
- package/.vercel/output/functions/tasks.segments/_full.segment.rsc.prerender-config.json +28 -0
- package/.vercel/output/functions/tasks.segments/_full.segment.rsc.prerender-fallback.rsc +27 -0
- package/.vercel/output/functions/tasks.segments/_head.segment.rsc.prerender-config.json +28 -0
- package/.vercel/output/functions/tasks.segments/_head.segment.rsc.prerender-fallback.rsc +6 -0
- package/.vercel/output/functions/tasks.segments/_index.segment.rsc.prerender-config.json +28 -0
- package/.vercel/output/functions/tasks.segments/_index.segment.rsc.prerender-fallback.rsc +10 -0
- package/.vercel/output/functions/tasks.segments/_tree.segment.rsc.prerender-config.json +28 -0
- package/.vercel/output/functions/tasks.segments/_tree.segment.rsc.prerender-fallback.rsc +5 -0
- package/.vercel/output/functions/tasks.segments/tasks/__PAGE__.segment.rsc.prerender-config.json +28 -0
- package/.vercel/output/functions/tasks.segments/tasks/__PAGE__.segment.rsc.prerender-fallback.rsc +9 -0
- package/.vercel/output/functions/tasks.segments/tasks.segment.rsc.prerender-config.json +28 -0
- package/.vercel/output/functions/tasks.segments/tasks.segment.rsc.prerender-fallback.rsc +5 -0
- package/.vercel/output/static/404.html +12 -0
- package/.vercel/output/static/404.rsc.json +1 -0
- package/.vercel/output/static/404.segments/_tree.segment.rsc.json +1 -0
- package/.vercel/output/static/500.html +1 -0
- package/.vercel/output/static/500.rsc.json +1 -0
- package/.vercel/output/static/500.segments/_tree.segment.rsc.json +1 -0
- package/.vercel/output/static/_next/__private/trace +2 -0
- package/.vercel/output/static/_next/static/TakLsJFW-DjjhsqoZu3Ok/_buildManifest.js +11 -0
- package/.vercel/output/static/_next/static/TakLsJFW-DjjhsqoZu3Ok/_clientMiddlewareManifest.js +42 -0
- package/.vercel/output/static/_next/static/TakLsJFW-DjjhsqoZu3Ok/_ssgManifest.js +1 -0
- package/.vercel/output/static/_next/static/chunks/00~h525bo.q7f.js +1 -0
- package/.vercel/output/static/_next/static/chunks/01xlw8hd842-c.js +1 -0
- package/.vercel/output/static/_next/static/chunks/0257pdz1-imal.js +2 -0
- package/.vercel/output/static/_next/static/chunks/03~yq9q893hmn.js +1 -0
- package/.vercel/output/static/_next/static/chunks/04uju~n5s9g7..css +1 -0
- package/.vercel/output/static/_next/static/chunks/066jf0nk75nic.css +2 -0
- package/.vercel/output/static/_next/static/chunks/085gdrlppedvd.js +1 -0
- package/.vercel/output/static/_next/static/chunks/0a5rikwbpt8_7.js +4 -0
- package/.vercel/output/static/_next/static/chunks/0b9r.-87w.lvh.js +1 -0
- package/.vercel/output/static/_next/static/chunks/0ced2tacwy8v7.js +1 -0
- package/.vercel/output/static/_next/static/chunks/0e-.zgw81gela.js +31 -0
- package/.vercel/output/static/_next/static/chunks/0gu130fpple04.js +1 -0
- package/.vercel/output/static/_next/static/chunks/0jmypv56.iwft.js +1 -0
- package/.vercel/output/static/_next/static/chunks/0krr-nvdwqdj1.js +1 -0
- package/.vercel/output/static/_next/static/chunks/0mqs00d_9jvzx.js +1 -0
- package/.vercel/output/static/_next/static/chunks/0ore4vqiwv2nx.js +1 -0
- package/.vercel/output/static/_next/static/chunks/0pqt~8bl3ukh4.js +4 -0
- package/.vercel/output/static/_next/static/chunks/0q.t7da_-e4yl.js +4 -0
- package/.vercel/output/static/_next/static/chunks/0q3rj30g1oodv.js +7 -0
- package/.vercel/output/static/_next/static/chunks/0qp3_l.t4nzzq.js +1 -0
- package/.vercel/output/static/_next/static/chunks/0qy1ci2dqfaqg.js +1 -0
- package/.vercel/output/static/_next/static/chunks/0u359llqm1_01.js +1 -0
- package/.vercel/output/static/_next/static/chunks/0u7ftv8celiqa.js +1 -0
- package/.vercel/output/static/_next/static/chunks/0~ijg-d65glam.js +1 -0
- package/.vercel/output/static/_next/static/chunks/14bsg3_-taiw4.js +1 -0
- package/.vercel/output/static/_next/static/chunks/168q2d2bi7swr.js +7 -0
- package/.vercel/output/static/_next/static/chunks/16aqsgrwba4zk.js +1 -0
- package/.vercel/output/static/_next/static/chunks/16tw8s4cce9_x.js +1 -0
- package/.vercel/output/static/_next/static/chunks/turbopack-01f1xs~cq_~si.js +1 -0
- package/.vercel/output/static/_next/static/media/4fa387ec64143e14-s.0wkzw~je483f-.woff2 +0 -0
- package/.vercel/output/static/_next/static/media/53b9e256198e5412-s.0-wfv7uh4i7h9.woff2 +0 -0
- package/.vercel/output/static/_next/static/media/5ce348bf30bf5439-s.0zgw-jeven.3w.woff2 +0 -0
- package/.vercel/output/static/_next/static/media/6306c77e7c8268e4-s.0rhz0arwfsn~5.woff2 +0 -0
- package/.vercel/output/static/_next/static/media/7178b3e590c64307-s.0nx0ww8fni_q3.woff2 +0 -0
- package/.vercel/output/static/_next/static/media/797e433ab948586e-s.p.08e28id.o-okb.woff2 +0 -0
- package/.vercel/output/static/_next/static/media/7d817b4c03b0c5f1-s.0l76wvqk9d84w.woff2 +0 -0
- package/.vercel/output/static/_next/static/media/8a480f0b521d4e75-s.0jzbimsg8vl84.woff2 +0 -0
- package/.vercel/output/static/_next/static/media/bbc41e54d2fcbd21-s.0k4k9394f2q-k.woff2 +0 -0
- package/.vercel/output/static/_next/static/media/caa3a2e1cccd8315-s.p.09~u27dqhyhd6.woff2 +0 -0
- package/.vercel/output/static/_next/static/media/favicon.0x3dzn~oxb6tn.ico +0 -0
- package/.vercel/output/static/_next/static/media/fef07dbb0973bf53-s.12tyk43_3sh9u.woff2 +0 -0
- package/.vercel/output/static/_next/static/not-found.txt +1 -0
- package/.vercel/project.json +16 -0
- package/AGENTS.md +9 -0
- package/CLAUDE.md +1 -0
- package/README.md +1 -0
- package/app/api/anet/host-supervisors/route.ts +63 -2
- package/app/api/anet/node-config/route.ts +145 -168
- package/app/api/hub/people/route.ts +48 -0
- package/app/api/hub/requirements/[id]/checklist/[itemId]/route.ts +54 -0
- package/app/api/hub/requirements/[id]/comments/route.ts +51 -0
- package/app/api/hub/requirements/[id]/route.ts +89 -0
- package/app/api/hub/requirements/events/route.ts +45 -0
- package/app/api/hub/requirements/route.ts +53 -0
- package/app/components/CreateNodeWizard.tsx +7 -2
- package/app/components/HostSupervisorPicker.tsx +76 -29
- package/app/components/NodeSettingsPanel.tsx +28 -25
- package/app/components/Sidebar.tsx +4 -0
- package/app/components/TaskChatPanel.tsx +6 -6
- package/app/components/TaskDetail.tsx +8 -7
- package/app/components/TaskList.tsx +6 -7
- package/app/components/TopoGraph.tsx +3 -2
- package/app/lib/time.ts +23 -0
- package/app/org/page.tsx +222 -0
- package/app/requirements/[id]/page.tsx +361 -0
- package/app/requirements/page.tsx +299 -0
- package/app/scheduled-tasks/page.tsx +98 -13
- package/apps/desktop/icon.png +0 -0
- package/bun.lock +1688 -0
- package/electron-builder.json +5 -1
- package/package.json +4 -2
- package/proxy.ts +1 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__0dwa10z._.js +0 -11
- package/.next/server/chunks/ssr/[root-of-the-server]__0dwa10z._.js.map +0 -1
- package/.next/server/chunks/ssr/[root-of-the-server]__202xetf._.js +0 -11
- package/.next/server/chunks/ssr/[root-of-the-server]__202xetf._.js.map +0 -1
- package/.next/static/chunks/0pton-t_-fqyu.css +0 -1
- package/.next/static/chunks/0z8vfpga444t1.js +0 -1
- package/.next/static/chunks/14c8u_tcund0g.js +0 -0
- package/.next/static/chunks/2kp8-5cyc-jbg.js +0 -1
- package/.next/static/chunks/3a53_ky07bdhz.js +0 -9
- package/.next/static/chunks/3im40-b21df3u.js +0 -2
- package/.next/static/chunks/3tnbxlq42_jjv.js +0 -1
- /package/.next/server/chunks/ssr/{app_0_s8u96._.js.map → app_07bzc6w._.js.map} +0 -0
- /package/.next/server/chunks/ssr/{app_0o4bxq0._.js.map → app_0g7oz9w._.js.map} +0 -0
- /package/.next/server/chunks/ssr/{app_0x7s72b._.js.map → app_0tt2ueo._.js.map} +0 -0
- /package/.next/server/chunks/ssr/{app_081zy6c._.js.map → app_0ugqkd7._.js.map} +0 -0
- /package/.next/server/chunks/ssr/{app_1oxcq68._.js.map → app_1e91uc-._.js.map} +0 -0
- /package/.next/server/chunks/ssr/{app_1psh956._.js.map → app_1f96aq_._.js.map} +0 -0
- /package/.next/server/chunks/ssr/{app_0_dhiwi._.js.map → app_1ua57bx._.js.map} +0 -0
- /package/.next/static/{trj9RsCWuEDMfq9BuoKfl → FEaCQpBc05SBAWTBHRt5h}/_buildManifest.js +0 -0
- /package/.next/static/{trj9RsCWuEDMfq9BuoKfl → FEaCQpBc05SBAWTBHRt5h}/_ssgManifest.js +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../app/components/TaskChatPanel.tsx","../../../../app/lib/chat-send-state.ts","../../../../app/lib/chat-drafts.ts","../../../../app/lib/task-history-pagination.ts","../../../../app/lib/useSSE.ts"],"sourcesContent":["'use client';\n\nimport { useState, useEffect, useRef, useCallback, useMemo, memo, Fragment } from 'react';\nimport { AliasAvatar } from './AliasAvatar';\nimport { AttachmentBlock, extractAttachments } from './AttachmentBlock';\nimport { isOnline as presenceIsOnline } from '../lib/presence';\nimport {\n buildTaskHistoryUrl,\n mergeTaskHistoryPage,\n oldestTaskHistoryCursor,\n type TaskHistoryCursor,\n} from '../lib/task-history-pagination';\n\ninterface ChatTask {\n task_id: string;\n from_name: string;\n to_name: string;\n status: string;\n priority: string;\n content: string;\n result: string;\n created_at: string;\n completed_at?: string;\n client_request_id?: string;\n // #492 — hub `/api/tasks` uses `SELECT *` so meta_json (raw TEXT) is\n // present when the task carried attachments. May also arrive\n // already-parsed as `meta` from other code paths (send-side optimistic).\n // Both accepted by `extractAttachments`.\n meta_json?: string | null;\n meta?: { attachments?: unknown } | null;\n}\n\ntype ChatEvent =\n | { kind: 'task'; task: ChatTask; at: string }\n | { kind: 'reply'; task: ChatTask; at: string };\n\n/* ── Loop R3 (微信式时间分组): instead of stamping every bubble with\n \"1m ago · 07/16, 09:50 AM\", messages group under centered separators\n that appear when >5min passed since the previous message — exactly the\n WeChat intuition (time context when it changes, silence when it\n doesn't). Formats are contextual: today \"14:32\", yesterday \"昨天\n 14:32\", within a week \"星期二 14:32\", this year \"7月16日 14:32\",\n older with the year. Exact per-message time survives in the bubble's\n title tooltip. */\nconst TIME_GROUP_GAP_MS = 5 * 60 * 1000;\n\n// One-line \"12 KB\" / \"3.4 MB\" formatter for attachment descriptions\n// in the visible task text. Defensive against negatives / NaN\n// (untrusted server payload) — returns \"?\" rather than crashing the\n// render or leaking a weird string.\nfunction formatBytesShort(bytes: number): string {\n if (!Number.isFinite(bytes) || bytes < 0) return '?';\n if (bytes < 1024) return `${bytes} B`;\n if (bytes < 1024 * 1024) return `${Math.round(bytes / 1024)} KB`;\n if (bytes < 1024 * 1024 * 1024) return `${(bytes / 1024 / 1024).toFixed(1)} MB`;\n return `${(bytes / 1024 / 1024 / 1024).toFixed(1)} GB`;\n}\n\nfunction eventTime(value?: string) {\n if (!value) return 0;\n return new Date(value.replace(' ', 'T') + (value.includes('T') ? '' : 'Z')).getTime() || 0;\n}\n\nfunction formatTimestamp(value?: string) {\n if (!value) return '--';\n const d = new Date(value.replace(' ', 'T') + (value.includes('T') ? '' : 'Z'));\n if (Number.isNaN(d.getTime())) return value;\n return d.toLocaleString(undefined, { month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit' });\n}\n\nfunction quotePreview(text: string, max = 140) {\n const compact = (text || '')\n .replace(/\\[Dashboard 附件[\\s\\S]*$/m, '[附件]')\n .replace(/\\s+/g, ' ')\n .trim();\n return compact.length > max ? `${compact.slice(0, max)}…` : compact;\n}\n\nfunction extractAttachmentPreviews(text: string): string[] {\n const urls: string[] = [];\n for (const line of (text || '').split('\\n')) {\n const match = line.match(/^\\s*-\\s*预览:\\s*(\\S+)\\s*$/);\n if (match?.[1]) urls.push(match[1]);\n }\n return Array.from(new Set(urls));\n}\n\n/* Loop R30 (微信长按复制的桌面版): hover-reveal copy on every bubble —\n agent replies get copied constantly (specs, commands, reports). ✓\n feedback for 1.5s; clipboard API with a textarea fallback for\n non-secure contexts. Mobile (no hover) keeps it faintly visible. */\nfunction CopyButton({ text, label }: { text: string; label: string }) {\n const [copied, setCopied] = useState(false);\n const copy = async () => {\n try {\n if (navigator.clipboard?.writeText) await navigator.clipboard.writeText(text);\n else {\n const ta = document.createElement('textarea');\n ta.value = text; document.body.appendChild(ta); ta.select();\n document.execCommand('copy'); ta.remove();\n }\n setCopied(true);\n setTimeout(() => setCopied(false), 1500);\n } catch {}\n };\n return (\n <button\n type=\"button\"\n onClick={copy}\n aria-label={label}\n title={label}\n className=\"shrink-0 rounded p-0.5 text-[10px] leading-none transition-opacity opacity-50 sm:opacity-0 sm:group-hover/bubble:opacity-70 hover:!opacity-100 text-[var(--fg-dim)] hover:text-cyan-300\"\n >\n {copied ? <span className=\"text-green-400\">✓</span> : (\n <svg className=\"h-3 w-3\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={2}>\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\" />\n </svg>\n )}\n </button>\n );\n}\n\n/* Loop R12 (微信式图片): thumbnails shimmer while loading and degrade to a\n quiet \"图片加载失败\" tile on error; tapping opens an in-panel lightbox\n (dark backdrop, fit-to-screen, Esc/tap closes) instead of navigating to\n a raw browser tab. */\nfunction ChatImage({ src, alt, thumbClass, onOpen }: { src: string; alt?: string; thumbClass: string; onOpen: (url: string) => void }) {\n const [state, setState] = useState<'loading' | 'ready' | 'error'>('loading');\n if (state === 'error') {\n return (\n <span className={`${thumbClass} flex items-center justify-center bg-black/20 border border-[var(--border)] text-[10px] text-[var(--fg-dim)]`}>\n {t('图片加载失败', 'Image failed to load')}\n </span>\n );\n }\n return (\n <button\n type=\"button\"\n data-chat-image={src}\n onClick={() => onOpen(src)}\n aria-label={alt || t('查看大图', 'View full image')}\n className={`relative block overflow-hidden ${state === 'loading' ? 'animate-pulse bg-[var(--bg-elevated)]' : ''} ${thumbClass}`}\n >\n <img\n src={src}\n alt={alt || ''}\n loading=\"lazy\"\n onLoad={() => setState('ready')}\n onError={() => setState('error')}\n className={`h-full w-full object-cover transition-opacity duration-200 ${state === 'ready' ? 'opacity-100' : 'opacity-0'}`}\n />\n </button>\n );\n}\n\nfunction ImageLightbox({ urls, initialIndex, onClose, opener }: { urls: string[]; initialIndex: number; onClose: () => void; opener: HTMLElement | null }) {\n // R21 (多图还债): navigate all images of the LOADED conversation —\n // ‹ › buttons + arrow keys, WeChat-style no-wrap ends.\n const [idx, setIdx] = useState(initialIndex);\n const url = urls[Math.min(idx, urls.length - 1)];\n const [loaded, setLoaded] = useState(false);\n const idxRef = useRef(idx);\n idxRef.current = idx;\n const step = (d: number) => {\n setIdx((i) => Math.max(0, Math.min(urls.length - 1, i + d)));\n setLoaded(false);\n };\n const stepRef = useRef(step);\n stepRef.current = step;\n const dialogRef = useRef<HTMLDivElement>(null);\n // onClose is recreated on every parent render (and the panel re-renders\n // every few seconds from soft refreshes) — a [onClose] dep would tear\n // down/re-run this effect mid-open and re-capture the \"opener\" as an\n // element INSIDE the dialog. Mount-only + ref keeps the true opener.\n const onCloseRef = useRef(onClose);\n onCloseRef.current = onClose;\n useEffect(() => {\n const onClose = () => onCloseRef.current();\n // R13 a11y debt: modal focus management — focus into the dialog, trap\n // Tab, hand focus back on close. The opener is captured by the PANEL at\n // activation time and passed in: by the time this passive effect runs,\n // the thumbnail has already been blurred (measured: activeElement was\n // <body> here), so capturing it locally restored nothing.\n const focusables = () =>\n Array.from(dialogRef.current?.querySelectorAll<HTMLElement>('a[href], button') || []);\n focusables()[0]?.focus();\n // Capture-phase so Escape closes the LIGHTBOX, not the chat panel\n // behind it (panel hosts listen for Escape too).\n const onKey = (e: KeyboardEvent) => {\n if (e.key === 'Escape') { e.stopPropagation(); onClose(); return; }\n if (e.key === 'ArrowLeft') { stepRef.current(-1); return; }\n if (e.key === 'ArrowRight') { stepRef.current(1); return; }\n if (e.key !== 'Tab') return;\n const items = focusables();\n if (items.length === 0) return;\n const first = items[0], last = items[items.length - 1];\n const active = document.activeElement;\n if (e.shiftKey && (active === first || !dialogRef.current?.contains(active))) {\n e.preventDefault(); last.focus();\n } else if (!e.shiftKey && (active === last || !dialogRef.current?.contains(active))) {\n e.preventDefault(); first.focus();\n }\n };\n window.addEventListener('keydown', onKey, true);\n return () => {\n window.removeEventListener('keydown', onKey, true);\n // After this cleanup React removes the overlay; the browser then\n // blurs to <body>. Restore on a macrotask so we run AFTER that blur.\n setTimeout(() => {\n // Soft refreshes rebuild bubble subtrees, so the opener node may be\n // detached by now (focus() on a detached node is a silent no-op) —\n // re-find its replacement by aria-label.\n let el = opener;\n if (el && !document.contains(el)) {\n const label = el.getAttribute('aria-label');\n if (label) el = document.querySelector<HTMLElement>(`[aria-label=\"${CSS.escape(label)}\"]`);\n }\n el?.focus?.();\n }, 0);\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []); // opener/onCloseRef are stable for one open\n return (\n <div ref={dialogRef} className=\"fixed inset-0 z-[100] flex items-center justify-center bg-black/85\" onClick={onClose} role=\"dialog\" aria-modal=\"true\" aria-label={t('图片预览', 'Image preview')}>\n {!loaded && <div className=\"absolute h-6 w-6 animate-spin rounded-full border-2 border-white/30 border-t-white\" />}\n <img\n key={url}\n src={url}\n alt=\"\"\n onLoad={() => setLoaded(true)}\n className={`max-h-[92vh] max-w-[92vw] rounded object-contain transition-opacity duration-150 ${loaded ? 'opacity-100' : 'opacity-0'}`}\n />\n {urls.length > 1 && (\n <>\n <span className=\"absolute left-3 top-3 text-[11px] tabular-nums text-white/70\">{idx + 1}/{urls.length}</span>\n <button\n onClick={(e) => { e.stopPropagation(); step(-1); }}\n disabled={idx === 0}\n aria-label={t('上一张', 'Previous image')}\n className=\"absolute left-1 top-1/2 flex h-11 w-11 -translate-y-1/2 items-center justify-center rounded-full text-2xl text-white/80 hover:bg-white/10 disabled:opacity-25\"\n >\n ‹\n </button>\n <button\n onClick={(e) => { e.stopPropagation(); step(1); }}\n disabled={idx === urls.length - 1}\n aria-label={t('下一张', 'Next image')}\n className=\"absolute right-1 top-1/2 flex h-11 w-11 -translate-y-1/2 items-center justify-center rounded-full text-2xl text-white/80 hover:bg-white/10 disabled:opacity-25\"\n >\n ›\n </button>\n </>\n )}\n <a\n href={url}\n target=\"_blank\"\n rel=\"noreferrer\"\n onClick={(e) => e.stopPropagation()}\n className=\"absolute right-12 top-3 text-[11px] text-white/70 underline hover:text-white\"\n >\n {t('新标签打开', 'Open in new tab')}\n </a>\n <button onClick={onClose} aria-label={t('关闭预览', 'Close preview')} className=\"absolute right-2 top-2 flex h-8 w-8 items-center justify-center text-lg text-white/80 hover:text-white\">\n ×\n </button>\n </div>\n );\n}\n\nfunction AttachmentPreviews({ text, onOpen }: { text: string; onOpen: (url: string) => void }) {\n const urls = extractAttachmentPreviews(text);\n if (urls.length === 0) return null;\n return (\n <div className=\"mt-2 grid grid-cols-2 gap-2\">\n {urls.map((url) => (\n <ChatImage key={url} src={url} alt=\"Dashboard attachment\" thumbClass=\"h-28 w-full rounded-lg border border-cyan-500/20\" onOpen={onOpen} />\n ))}\n </div>\n );\n}\n\nfunction LocalFilePreview({ file, onRemove }: { file: File; onRemove: () => void }) {\n const isImage = file.type.startsWith('image/');\n // eslint-disable-next-line react-hooks/purity -- object URL creation is\n // idempotent-per-file here; memo + revoke-on-change avoids the\n // setState-in-effect double commit. Only allocated for images —\n // non-image tiles render a file-icon + name and don't need a blob.\n const url = useMemo(() => (isImage ? URL.createObjectURL(file) : ''), [file, isImage]);\n useEffect(() => {\n if (!url) return;\n return () => URL.revokeObjectURL(url);\n }, [url]);\n\n // Short ext label for non-image tiles (\"PDF\", \"PPTX\", \"ZIP\" …).\n // Falls back to the leading MIME segment when there's no ext.\n const ext = (file.name.match(/\\.([a-zA-Z0-9]{1,5})$/)?.[1] || file.type.split('/')[1] || 'FILE')\n .toUpperCase()\n .slice(0, 5);\n\n return (\n <div\n className=\"relative h-16 w-16 overflow-hidden rounded-lg border border-cyan-500/25 bg-black/20\"\n title={file.name}\n >\n {isImage && url ? (\n <img src={url} alt={file.name} className=\"h-full w-full object-cover\" />\n ) : (\n <div className=\"flex h-full w-full flex-col items-center justify-center gap-0.5 px-1 text-center\">\n <span className=\"text-lg\">📄</span>\n <span className=\"max-w-full truncate text-[9px] font-semibold text-cyan-300\">{ext}</span>\n </div>\n )}\n <button\n type=\"button\"\n onClick={onRemove}\n className=\"absolute right-1 top-1 flex h-5 w-5 items-center justify-center rounded-full bg-black/70 text-xs text-white hover:bg-red-500\"\n aria-label={`Remove ${file.name}`}\n >\n ×\n </button>\n </div>\n );\n}\n\n// 通信龙 07-31 GAP 2nd tier: translate hub status codes into human\n// labels. The old form was `● ─ ● ─ ○ ─ ○ delivered` — a colored dot\n// progression + the raw English word. Nobody could tell \"delivered\"\n// (hub-side mark) from \"acked\" (node process received) from \"replied\"\n// (agent actually processed).\n//\n// Two things this rewrite fixes:\n//\n// 1. STATUS_STEPS was `['created','delivered','running','replied']`.\n// Neither `created` nor `running` correspond to hub-emitted terminal\n// statuses (`created` is client-side optimistic, `running` is READ\n// by hub queries but never WRITTEN — grep server/src for `= 'running'`\n// returns zero). Real hub progression is queued → delivered → acked\n// → replied, and the old third dot literally never lit up.\n//\n// 2. `delivered` was labeled as if it meant \"message reached the node\".\n// Reading hub source (server/src/index.ts:1568 + tools.ts:1080/1232)\n// shows it's set at task-insert time — same instant as delivered_at\n// (which is why delivered_at delay is empirically 0). The label now\n// says \"已推送\" and the hover explicitly disclaims node reception.\n//\n// Vocabulary — must stay in sync with hub emits:\n// queued / delivered / acked / replied / failed ← the primary 5\n// created ← client-side pre-POST\n// closed / expired / cancelled ← terminal, non-reply\n// running ← reserved (never written today)\n// <anything else> ← fail-loudly (raw + banner)\nconst STATUS_STEPS = ['queued', 'delivered', 'acked', 'replied'] as const;\ntype StatusInfo = { label: string; hover: string; color: string; icon: React.ReactNode };\nconst STATUS_INFO: Record<string, StatusInfo> = {\n created: { label: '发送中', hover: '客户端已建消息,尚未收到 hub 回执。', color: 'text-gray-400', icon: <IconSending /> },\n queued: { label: '排队中', hover: '已入队,尚未推给节点。节点可能离线、或通道拥堵。', color: 'text-gray-400', icon: <IconClock /> },\n delivered: { label: '已推送', hover: 'hub 侧已标记推送。尚未确认节点是否收到(delivered_at 是入队时刻,不代表 SSE 已到达)。', color: 'text-sky-400', icon: <IconCheck /> },\n acked: { label: '已接收', hover: '节点进程已确认收到。未必已处理——对方 agent 可能尚未唤醒。', color: 'text-gray-300', icon: <IconCheckDouble /> },\n replied: { label: '已回复', hover: '对方已针对此消息回复。', color: 'text-emerald-400', icon: <IconCheckDouble filled /> },\n failed: { label: '失败', hover: '发送失败——详细原因见消息下方文本。', color: 'text-red-400', icon: <IconWarn /> },\n closed: { label: '已关闭', hover: '会话已被关闭,不再期待回复。', color: 'text-gray-500', icon: <IconClose /> },\n expired: { label: '已超时', hover: '在期限内未收到回复,任务已超时。', color: 'text-gray-500', icon: <IconClock /> },\n cancelled: { label: '已取消', hover: '任务被主动取消。', color: 'text-gray-500', icon: <IconClose /> },\n running: { label: '处理中', hover: '节点进程正在处理(今日 hub 不写入此值,见组件注释)。', color: 'text-green-400', icon: <IconClock /> },\n};\n\nfunction StatusBar({ status, result }: { status: string; result?: string }) {\n const info = STATUS_INFO[status];\n const known = !!info;\n // Progression label list for the hover — same string appended after\n // the per-status hover so the reader gets a compact map of the flow.\n // Not per-step timestamps: hub doesn't expose queued_at / acked_at\n // separately from delivered_at, so a per-step timeline would be\n // fabricated data. See feedback_assert_the_fact_not_the_declaration.\n const idx = STATUS_STEPS.indexOf(status as typeof STATUS_STEPS[number]);\n const flow = STATUS_STEPS.map((s, i) => {\n const mark = i < idx || (i === idx && idx >= 0) ? '✓' : '○';\n return `${mark} ${STATUS_INFO[s].label}`;\n }).join(' → ');\n const hoverText = known\n ? `${info.hover}\\n\\n进度:${flow}`\n : `未知状态「${status}」——请报 bug。UI 词库没有匹配项,可能 hub 加了新 status 但前端没跟上。`;\n const label = known ? info.label : status;\n const color = known ? info.color : 'text-yellow-400';\n\n // failed inline reason — hub has no dedicated failure_reason column\n // (task table: task_id/from_*/to_*/status/content/result/... —\n // grep-verified as of 2026-07-31). We show `result` first 40 chars\n // when present. When result is empty, we explicitly say \"节点未提供\n // 原因\" rather than falling back to a generic \"未知错误\" — that\n // distinguishes \"hub has no error field\" from \"reason field exists\n // but got a bad value\".\n const failedReason = status === 'failed'\n ? ((result && result.trim()) ? result.trim().slice(0, 40) : '节点未提供原因')\n : null;\n\n return (\n <div\n data-status-key={status}\n data-status-known={known ? 'true' : 'false'}\n data-status-label={label}\n className=\"inline-flex flex-col gap-0.5 mt-1.5\"\n >\n <span\n title={hoverText}\n aria-label={known ? info.label : `未知状态 ${status}`}\n className={`inline-flex items-center gap-1.5 text-[11px] font-medium ${color}`}\n >\n {known ? info.icon : <IconQuestion />}\n <span>{label}</span>\n {(status === 'delivered' || status === 'created') && (\n <span aria-hidden className=\"inline-flex items-center gap-0.5 ml-0.5\">\n <span className=\"inline-block w-1 h-1 rounded-full bg-current opacity-70 animate-pulse\" />\n <span className=\"inline-block w-1 h-1 rounded-full bg-current opacity-70 animate-pulse\" style={{ animationDelay: '0.2s' }} />\n <span className=\"inline-block w-1 h-1 rounded-full bg-current opacity-70 animate-pulse\" style={{ animationDelay: '0.4s' }} />\n </span>\n )}\n </span>\n {failedReason !== null && (\n <span\n data-status-reason={failedReason}\n className=\"text-[10px] text-red-400/80 max-w-[260px] truncate\"\n title={result || undefined}\n >\n {failedReason}\n </span>\n )}\n </div>\n );\n}\n\n// Icon primitives — inline SVG, single-color (currentColor), sized to\n// match the 11px label text. No external icon library — keeps the\n// StatusBar self-contained and avoids a Tailwind purge/tree-shake\n// dance for icons only this component uses.\nfunction IconClock() {\n return (\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth={2} strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <circle cx=\"12\" cy=\"12\" r=\"10\" /><path d=\"M12 6v6l4 2\" />\n </svg>\n );\n}\nfunction IconCheck() {\n return (\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth={2.5} strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M4 12l6 6L20 6\" />\n </svg>\n );\n}\nfunction IconCheckDouble({ filled }: { filled?: boolean } = {}) {\n return (\n <svg width=\"14\" height=\"12\" viewBox=\"0 0 28 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth={filled ? 2.5 : 2} strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M2 12l6 6L18 6\" />\n <path d=\"M10 12l6 6L26 6\" opacity={filled ? 1 : 0.7} />\n </svg>\n );\n}\nfunction IconWarn() {\n return (\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth={2} strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M12 2L2 20h20L12 2z\" /><path d=\"M12 9v5\" /><circle cx=\"12\" cy=\"17.5\" r=\"0.6\" fill=\"currentColor\" />\n </svg>\n );\n}\nfunction IconClose() {\n return (\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth={2} strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <circle cx=\"12\" cy=\"12\" r=\"10\" /><path d=\"M8 12h8\" />\n </svg>\n );\n}\nfunction IconSending() {\n return (\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth={2} strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M4 12l16-8-6 16-3-7-7-1z\" />\n </svg>\n );\n}\nfunction IconQuestion() {\n return (\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth={2} strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <path d=\"M9.5 9.5a2.5 2.5 0 015 0c0 1.5-2.5 2-2.5 3.5\" />\n <circle cx=\"12\" cy=\"17\" r=\"0.6\" fill=\"currentColor\" />\n </svg>\n );\n}\n\n// Full markdown rendering — handles tables, headings, lists, links, code,\n// blockquotes via react-markdown + GFM. Earlier hand-rolled parser only did\n// code blocks + bold; tables / headings showed as raw `|---|` text.\nimport ReactMarkdown from 'react-markdown';\nimport remarkGfm from 'remark-gfm';\nimport { useSSE } from '../lib/useSSE';\nimport { useNetworkId } from '../lib/network-context';\nimport { useHealth } from '../lib/hooks';\nimport { useMuted } from '../lib/chat-mute';\nimport { markChatRead } from '../lib/chat-unread';\nimport { readDraft, writeDraft } from '../lib/chat-drafts';\nimport { pinyinMatch, usePinyinReady } from '../lib/pinyin-match';\nimport { formatWeChatTime } from '../lib/time';\nimport { t } from '../lib/ui-lang';\nimport { chatOutboxForAlias, chatPrivateScope, putChatOutbox, removeChatOutbox } from '../lib/chat-outbox';\nimport { newDashboardRequestId, normalizeChatSendResult, requestIdFromTaskMeta } from '../lib/chat-send-state';\n\n/* Loop R14 (气泡子树稳定性): the renderer map used to be an OBJECT LITERAL\n OF INLINE ARROWS inside MarkdownContent's JSX — every render produced new\n component types, so React unmounted and remounted the entire rendered\n markdown subtree on every soft refresh (measured: +36 ChatImage mounts in\n 45s idle; any focused element inside a bubble fell back to <body>).\n Hoisting the map to a factory + memoizing per onImageClick keeps types\n stable; memo() on MarkdownContent then skips re-render entirely while\n text is unchanged. */\nfunction buildMdComponents(onImageClick?: (url: string) => void) {\n return {\n h1: ({ children }) => <h1 className=\"text-base font-semibold text-[var(--fg)] mt-2 mb-1\">{children}</h1>,\n h2: ({ children }) => <h2 className=\"text-sm font-semibold text-[var(--fg)] mt-2 mb-1\">{children}</h2>,\n h3: ({ children }) => <h3 className=\"text-sm font-semibold text-cyan-300 mt-1.5 mb-0.5\">{children}</h3>,\n p: ({ children }) => <p className=\"my-1\">{children}</p>,\n strong: ({ children }) => <strong className=\"text-[var(--fg)] font-semibold\">{children}</strong>,\n em: ({ children }) => <em className=\"italic text-[var(--fg-muted)]\">{children}</em>,\n ul: ({ children }) => <ul className=\"list-disc pl-5 my-1 space-y-0.5\">{children}</ul>,\n ol: ({ children }) => <ol className=\"list-decimal pl-5 my-1 space-y-0.5\">{children}</ol>,\n li: ({ children }) => <li>{children}</li>,\n a: ({ href, children }) => <a href={href} target=\"_blank\" rel=\"noreferrer\" className=\"text-cyan-300 underline\">{children}</a>,\n blockquote: ({ children }) => <blockquote className=\"border-l-2 border-cyan-500/30 pl-3 my-1 text-[var(--fg-muted)] italic\">{children}</blockquote>,\n hr: () => <hr className=\"border-t border-[var(--border)] my-2\" />,\n img: ({ src, alt }) => {\n const url = typeof src === 'string' ? src : '';\n if (!url) return null;\n if (!onImageClick) return <img src={url} alt={alt || ''} loading=\"lazy\" className=\"my-1 max-h-48 rounded-lg\" />;\n return <ChatImage src={url} alt={alt} thumbClass=\"my-1 h-40 w-full max-w-[240px] rounded-lg\" onOpen={onImageClick} />;\n },\n code: ({ className, children }) => {\n const inline = !className?.startsWith('language-');\n if (inline) {\n return <code className=\"bg-[var(--code-bg)] rounded px-1.5 py-0.5 text-cyan-300 text-[11px] border border-[var(--border)]\">{children}</code>;\n }\n const lang = className?.replace(/^language-/, '') || '';\n return (\n <div className=\"my-2 rounded-lg overflow-hidden border border-[var(--border)]\">\n {lang && <div className=\"bg-[var(--code-bg)] px-3 py-1 text-[10px] text-[var(--fg-muted)] border-b border-[var(--border)]\">{lang}</div>}\n <pre className=\"bg-[var(--code-bg)] px-3 py-2 text-[11px] text-green-300 overflow-x-auto\"><code>{children}</code></pre>\n </div>\n );\n },\n table: ({ children }) => (\n <div className=\"my-2 overflow-x-auto\">\n <table className=\"w-full text-[12px] border-collapse\">{children}</table>\n </div>\n ),\n thead: ({ children }) => <thead className=\"bg-[var(--code-bg)]\">{children}</thead>,\n tbody: ({ children }) => <tbody>{children}</tbody>,\n tr: ({ children }) => <tr className=\"border-b border-[var(--border)]\">{children}</tr>,\n th: ({ children }) => <th className=\"text-left text-cyan-300 font-semibold px-2 py-1 border border-[var(--border)]\">{children}</th>,\n td: ({ children }) => <td className=\"px-2 py-1 border border-[var(--border)] align-top\">{children}</td>,\n } satisfies React.ComponentProps<typeof ReactMarkdown>['components'];\n}\n\nconst MarkdownContent = memo(function MarkdownContent({ text, onImageClick }: { text: string; onImageClick?: (url: string) => void }) {\n const components = useMemo(() => buildMdComponents(onImageClick), [onImageClick]);\n if (!text) return <span className=\"text-[var(--fg-dim)] italic\">No content</span>;\n return (\n <div className=\"break-words leading-relaxed\">\n <ReactMarkdown\n remarkPlugins={[remarkGfm]}\n components={components}\n >\n {text}\n </ReactMarkdown>\n </div>\n );\n});\n\ninterface TaskChatPanelProps {\n alias: string;\n onClose: () => void;\n /** When true, renders without outer panel chrome (for use inside CommandCenter) */\n inline?: boolean;\n /** Available nodes for @ mention */\n availableNodes?: string[];\n /** Loop R11: false for background CommandCenter tabs — pauses the 15s\n * soft-refresh AND the SSE-event soft-refresh (in-flight send patches\n * stay live). Reactivation runs one immediate catch-up. Default true. */\n active?: boolean;\n}\n\n/** P0 chat batch (Vincent: 长消息=无排版文字墙): message bodies taller than\n * ~12 rendered lines collapse behind 展开全文, with a fade-out hinting more\n * content. Height is measured post-render (scrollHeight via ResizeObserver)\n * so markdown output — code blocks, lists — counts at its real rendered\n * height rather than by newline count. Attachments render OUTSIDE the\n * collapse so a folded message never hides an image. */\nconst COLLAPSE_MAX_PX = 300; // ≈12 lines at 14px/1.65\n\nfunction CollapsibleText({ children }: { children: React.ReactNode }) {\n const ref = useRef<HTMLDivElement>(null);\n const [overflowing, setOverflowing] = useState(false);\n const [expanded, setExpanded] = useState(false);\n useEffect(() => {\n const el = ref.current;\n if (!el) return;\n const check = () => setOverflowing(el.scrollHeight > COLLAPSE_MAX_PX + 40);\n check();\n const ro = new ResizeObserver(check);\n ro.observe(el);\n return () => ro.disconnect();\n }, []);\n const collapsed = overflowing && !expanded;\n return (\n <div>\n <div\n ref={ref}\n style={collapsed ? {\n maxHeight: COLLAPSE_MAX_PX,\n overflow: 'hidden',\n maskImage: 'linear-gradient(to bottom, black 72%, transparent 100%)',\n WebkitMaskImage: 'linear-gradient(to bottom, black 72%, transparent 100%)',\n } : undefined}\n >\n {children}\n </div>\n {overflowing && (\n <button\n type=\"button\"\n onClick={() => setExpanded(e => !e)}\n className=\"mt-1 text-[12px] font-medium text-cyan-400 hover:text-cyan-300\"\n >\n {expanded ? t('收起 ⌃', 'Collapse ⌃') : t('展开全文 ⌄', 'Show full text ⌄')}\n </button>\n )}\n </div>\n );\n}\n\nexport function TaskChatPanel({ alias, onClose, inline, availableNodes, active }: TaskChatPanelProps) {\n const isActive = active !== false;\n const { networkId } = useNetworkId();\n // NetworkContext hydrates after the first client paint. Do not briefly read\n // another network's shard through an auth fallback while that happens.\n const privateStorageScope = networkId ? chatPrivateScope(networkId) : null;\n // R33 (微信聊天页头): presence via the same SSE definition as everywhere\n // (#214 \"one definition\"); useHealth is SWR-deduped with the page-level\n // poll, so this adds no extra requests while Overview is mounted.\n const { health } = useHealth();\n const chatMuted = useMuted(alias);\n const sseOnline = (() => {\n const m = health?.sse_sessions;\n if (!m) return null;\n if (m[alias]) return true;\n if (networkId && m[`${networkId}:${alias}`]) return true;\n // sse keys are `network_id:alias`; without a selected network scan by suffix\n for (const k of Object.keys(m)) if (k.endsWith(`:${alias}`)) return true;\n return false;\n })();\n const [messages, setMessages] = useState<ChatTask[]>([]);\n const [input, setInput] = useState('');\n const [attachedFiles, setAttachedFiles] = useState<File[]>([]);\n const [priority, setPriority] = useState('normal');\n const [sending, setSending] = useState(false);\n const [pollingIds, setPollingIds] = useState<Set<string>>(new Set());\n const [historyLoaded, setHistoryLoaded] = useState(false);\n const [historyError, setHistoryError] = useState(false);\n const [showMentions, setShowMentions] = useState(false);\n const [mentionIndex, setMentionIndex] = useState(0);\n // R23→R25: pinyin matching moved to the shared lib (also powers /nodes\n // and /messages search). Lazy chunk semantics unchanged.\n const pinyinReady = usePinyinReady();\n void pinyinReady; // render trigger when the lazy dict lands mid-typing\n const [attachLimitHit, setAttachLimitHit] = useState(false);\n // R39: k/n indicator while attachments upload (matters on slow links;\n // previously only the send-button spinner hinted anything).\n const [uploadProgress, setUploadProgress] = useState<{ done: number; total: number } | null>(null);\n const [mentionFilter, setMentionFilter] = useState('');\n const [mentionNodes, setMentionNodes] = useState<string[]>([]);\n const messagesEndRef = useRef<HTMLDivElement>(null);\n const textareaRef = useRef<HTMLTextAreaElement>(null);\n // #217 M4 (Vincent: 倒序加载, 上滑再拉旧的): history is paged. We load\n // only the newest PAGE on open and fetch one keyset page when the user\n // scrolls to the top. `before` + `before_task_id` preserve rows that share\n // the Hub's one-second created_at precision.\n // P0 chat batch (Vincent \"感觉是一脑子全部拉了\"): 20 tasks render up to\n // ~40 bubbles (task+reply) — a wall on open. 12 keeps the first paint to\n // roughly one viewport of conversation; scroll-up stays O(page).\n const HISTORY_PAGE = 12;\n const scrollRef = useRef<HTMLDivElement>(null);\n const skipAutoScrollRef = useRef(false);\n const anchoredRef = useRef(false);\n const [hasOlder, setHasOlder] = useState(true);\n const [loadingOlder, setLoadingOlder] = useState(false);\n // Loop R10 (微信式\"下方有新消息\"): while the user is scrolled up reading\n // history, incoming messages must NOT yank the view to the bottom —\n // they accumulate in a floating pill instead. atBottomRef mirrors the\n // user's last real scroll position (checking the DOM after an append\n // would always look \"not at bottom\" because the new content itself\n // grew the distance).\n const [newBelow, setNewBelow] = useState(0);\n const [lightbox, setLightbox] = useState<{ urls: string[]; idx: number } | null>(null);\n const [errorFor, setErrorFor] = useState<string | null>(null);\n // Loop R15 (会话内搜索): client-side filter over the LOADED window —\n // honest scope (the hint says so); load earlier messages to widen it.\n const [searchOpen, setSearchOpen] = useState(false);\n const [searchQuery, setSearchQuery] = useState('');\n const [searchIdx, setSearchIdx] = useState(0);\n const searchInputRef = useRef<HTMLInputElement>(null);\n // R44 (微信桌面版直觉): Cmd/Ctrl+F while this panel is the active chat\n // opens the in-conversation search instead of browser find — the open\n // panel IS the user's context. Closing the panel restores browser find.\n useEffect(() => {\n if (!isActive) return;\n const onKey = (e: KeyboardEvent) => {\n if ((e.metaKey || e.ctrlKey) && !e.shiftKey && !e.altKey && e.key.toLowerCase() === 'f') {\n e.preventDefault();\n setSearchOpen(true);\n setTimeout(() => searchInputRef.current?.focus(), 50);\n }\n };\n window.addEventListener('keydown', onKey, true);\n return () => window.removeEventListener('keydown', onKey, true);\n }, [isActive]);\n // 07-31 通信龙 batch (SPEC §12 header 🔍): ChatPane's search button\n // dispatches `chat:open-search` (detail.alias). Same effect as\n // Cmd/Ctrl+F, but reachable by pointer users. Filter on detail.alias\n // === alias so a search click on chat A doesn't accidentally open\n // search on chat B if both were somehow mounted.\n useEffect(() => {\n if (!isActive) return;\n const onEvent = (e: Event) => {\n const detail = (e as CustomEvent<{ alias?: string }>).detail;\n if (detail?.alias && detail.alias !== alias) return;\n setSearchOpen(true);\n setTimeout(() => searchInputRef.current?.focus(), 50);\n };\n window.addEventListener('chat:open-search', onEvent);\n return () => window.removeEventListener('chat:open-search', onEvent);\n }, [isActive, alias]);\n const lightboxOpenerRef = useRef<HTMLElement | null>(null);\n const openLightbox = useCallback((url: string) => {\n lightboxOpenerRef.current = document.activeElement as HTMLElement | null;\n // Collect every image of the loaded conversation in document order —\n // DOM-driven so it exactly matches what's rendered (markdown +\n // attachments, collapsed content included).\n const nodes = Array.from(scrollRef.current?.querySelectorAll<HTMLElement>('[data-chat-image]') || []);\n const urls = Array.from(new Set(nodes.map((n) => n.getAttribute('data-chat-image') || '').filter(Boolean)));\n const idx = Math.max(0, urls.indexOf(url));\n setLightbox({ urls: urls.length ? urls : [url], idx });\n }, []);\n const atBottomRef = useRef(true);\n const prevBubblesRef = useRef(0);\n const forceScrollRef = useRef(false);\n\n // Load available nodes for @ mention\n // alias → network_id map for send scoping (P0 network_id fix): the\n // target node's own network is the ground truth; the sidebar-selected\n // network is the fallback when the map is empty (availableNodes path).\n const aliasNetRef = useRef<Record<string, string>>({});\n useEffect(() => {\n if (availableNodes) { setMentionNodes(availableNodes); return; }\n // #515: @-mention candidates must be actually reachable, not just\n // \"hub row hasn't flipped to offline yet\". Fetch health alongside\n // status so we can filter by presence.isOnline (SSE-reachable)\n // rather than the retired `status !== 'offline'` predicate.\n Promise.all([\n fetch('/api/hub/status').then(r => r.ok ? r.json() : { sessions: [] }),\n fetch('/api/hub/health').then(r => r.ok ? r.json() : {}),\n ]).then(([d, health]: [{ sessions?: { alias: string; status: string; network_id?: string }[] }, { sse_sessions?: Record<string, number> }]) => {\n const sessions = d.sessions || [];\n const map: Record<string, string> = {};\n for (const s of sessions) if (s.network_id) map[s.alias] = s.network_id;\n aliasNetRef.current = map;\n setMentionNodes(sessions.filter(s => presenceIsOnline(s, health?.sse_sessions)).map(s => s.alias));\n }).catch(() => {});\n }, [availableNodes]);\n\n // Loop R9 (微信草稿): unsent text survives closing the panel, switching\n // conversations and refreshing, per conversation. Text only — File\n // attachments can't be serialized. The debounced write covers \"typing,\n // then refresh\"; the effect cleanup covers \"typing, then close within\n // the debounce window\" (the timer dies with the unmount, so the tail\n // would otherwise be lost). Empty input deletes the draft, so sending\n // or clearing the box leaves no stale draft behind.\n const inputRef = useRef(input);\n inputRef.current = input;\n // R17 (移动端手感): touch keyboards have no Shift — Enter-to-send made\n // multiline input impossible on phones. WeChat mobile semantics: Enter\n // inserts a newline, the send button sends. Coarse pointer = touch.\n const coarsePointerRef = useRef(false);\n useEffect(() => {\n try { coarsePointerRef.current = window.matchMedia('(pointer: coarse)').matches; } catch {}\n }, []);\n useEffect(() => {\n if (!alias || !networkId) return;\n const draft = readDraft(alias, networkId);\n if (draft) {\n setInput(draft);\n requestAnimationFrame(() => { if (textareaRef.current) autoResize(textareaRef.current); });\n }\n return () => { writeDraft(alias, inputRef.current, networkId); };\n }, [alias, networkId]);\n useEffect(() => {\n if (!networkId) return;\n const timer = setTimeout(() => writeDraft(alias, input, networkId), 300);\n return () => clearTimeout(timer);\n }, [input, alias, networkId]);\n\n useEffect(() => {\n if (!alias) return;\n markChatRead(alias, networkId);\n }, [alias, networkId]);\n\n // Load task history for this node — newest `limit` only (M4).\n // Vincent tg923 (转圈加载太久): bound each request with an AbortController so\n // a stalled hub call can't leave the panel spinning forever.\n //\n // Timeout-degrade (Vincent \"节点详情总是超时\" on the large 通信龙 session):\n // the hub query itself is NOT the bottleneck — fetching the newest 20 for\n // that session measures ~3 ms (v0.9 ships the (to_name, created_at) index\n // + `skip_stats`), so a 12 s stall is a congested *transport* (HTTP/1.1\n // head-of-line blocking behind the long-lived SSE stream), not the query.\n // Robustness here, without pretending to \"fix\" the transport:\n // • runFetch — one bounded attempt that only touches `messages`.\n // • loadInitial — a retry ladder (newest 20 @ 10 s, then a tiny newest-6\n // @ 6 s). Under congestion a smaller payload is far likelier to get\n // through, so the panel opens with *some* recent history rather than a\n // full-screen timeout. The composer below is never gated on history,\n // so the user can always send even if both attempts fail.\n const runFetch = useCallback(async (\n limit: number,\n budgetMs: number,\n cursor?: TaskHistoryCursor,\n ): Promise<boolean> => {\n const ctrl = new AbortController();\n const timer = setTimeout(() => ctrl.abort(), budgetMs);\n try {\n const res = await fetch(\n buildTaskHistoryUrl(alias, limit, cursor),\n { signal: ctrl.signal },\n );\n const data = await res.json();\n if (data.tasks) {\n const persistedRequestIds = new Set<string>();\n for (const task of data.tasks as ChatTask[]) {\n const requestId = requestIdFromTaskMeta(task.meta_json);\n if (requestId) {\n persistedRequestIds.add(requestId);\n removeChatOutbox(requestId, privateStorageScope);\n }\n }\n if (data.tasks.length < limit) setHasOlder(false);\n // Merge by identity and sort oldest-first. This preserves older pages,\n // optimistic sends, and SSE patches while a bounded newest-page refresh\n // updates current statuses.\n setMessages(prev => mergeTaskHistoryPage(prev, data.tasks, persistedRequestIds));\n }\n return true;\n } catch {\n return false;\n } finally {\n clearTimeout(timer);\n }\n }, [alias, privateStorageScope]);\n\n // Single-attempt loader used for one older keyset page.\n const loadHistory = useCallback(async (cursor: TaskHistoryCursor) => {\n const ok = await runFetch(HISTORY_PAGE, 12_000, cursor);\n setHistoryError(!ok);\n setHistoryLoaded(true);\n return ok;\n }, [runFetch]);\n\n // Initial open — retry ladder so a congested transport still opens with\n // partial history instead of a full-screen \"加载超时\".\n const loadInitial = useCallback(async () => {\n setHistoryLoaded(false);\n setHistoryError(false);\n let ok = await runFetch(HISTORY_PAGE, 10_000);\n if (!ok) {\n ok = await runFetch(6, 6_000);\n }\n setHistoryError(!ok);\n setHistoryLoaded(true);\n }, [runFetch]);\n\n useEffect(() => {\n setMessages([]);\n setHistoryLoaded(false);\n setHistoryError(false);\n anchoredRef.current = false;\n firstAnchorRef.current = true;\n atBottomRef.current = true;\n prevBubblesRef.current = 0;\n setNewBelow(0);\n setErrorFor(null);\n setHasOlder(true);\n loadInitial();\n // Text sends are persisted before POST. If the tab/app died during an\n // ambiguous request, restore the bubble instead of silently losing it;\n // tapping retry reuses the same durable request id and is safe.\n const pending = chatOutboxForAlias(alias, privateStorageScope).map((entry): ChatTask => ({\n task_id: entry.localTaskId,\n client_request_id: entry.requestId,\n from_name: 'Dashboard',\n to_name: entry.targetAlias,\n status: 'failed',\n priority: entry.priority,\n content: entry.content,\n result: '❌ 发送结果未确认,点此安全重试',\n created_at: entry.createdAt,\n }));\n if (pending.length > 0) {\n setMessages(prev => {\n const known = new Set(prev.map(item => item.task_id));\n return [...prev, ...pending.filter(item => !known.has(item.task_id))];\n });\n }\n // Focus textarea\n setTimeout(() => textareaRef.current?.focus(), 300);\n }, [alias, loadInitial, privateStorageScope]);\n\n // M4: user scrolled to the top → fetch one older page, keeping the\n // viewport anchored on the message they were looking at.\n const loadOlder = useCallback(async () => {\n if (loadingOlder || !hasOlder) return;\n const cursor = oldestTaskHistoryCursor(messages);\n if (!cursor) {\n setHasOlder(false);\n return;\n }\n setLoadingOlder(true);\n const el = scrollRef.current;\n const prevHeight = el?.scrollHeight ?? 0;\n skipAutoScrollRef.current = true;\n const loaded = await loadHistory({ task_id: cursor.task_id, created_at: cursor.created_at });\n requestAnimationFrame(() => {\n if (loaded && el) el.scrollTop += el.scrollHeight - prevHeight;\n if (!loaded) skipAutoScrollRef.current = false;\n setLoadingOlder(false);\n });\n }, [loadingOlder, hasOlder, loadHistory, messages]);\n\n const onMessagesScroll = useCallback(() => {\n const el = scrollRef.current;\n if (!el) return;\n const dist = el.scrollHeight - el.scrollTop - el.clientHeight;\n atBottomRef.current = dist < 80;\n if (atBottomRef.current) setNewBelow(0);\n // The initial bottom-anchor is a smooth scroll, so its own scroll\n // events pass through scrollTop≈0 territory. Arm the older-page\n // trigger only after the container has actually reached the bottom\n // once — everything before that is layout/auto-scroll noise.\n if (!anchoredRef.current) {\n if (dist < 80) anchoredRef.current = true;\n return;\n }\n if (el.scrollTop < 40) loadOlder();\n }, [loadOlder]);\n\n // Auto-scroll to bottom on new messages — but not when we just\n // prepended older history (that would yank the user away from what\n // they scrolled up to read). P0 chat batch: the FIRST anchor after a\n // history load is instant ('auto') — a smooth scroll from the top made\n // the whole wall visibly fly past on open, which read as \"everything\n // loaded at once\". Subsequent new-message anchors stay smooth.\n const firstAnchorRef = useRef(true);\n useEffect(() => {\n const bubbles = messages.reduce((n, m) => n + (m.result ? 2 : 1), 0);\n const prevBubbles = prevBubblesRef.current;\n prevBubblesRef.current = bubbles;\n if (skipAutoScrollRef.current) {\n skipAutoScrollRef.current = false;\n return;\n }\n if (messages.length === 0) return;\n // R10: scrolled-up readers keep their place — count the arrivals\n // into the pill instead of yanking to the bottom. Own sends\n // (forceScrollRef) and the first anchor always jump.\n if (!firstAnchorRef.current && !forceScrollRef.current && !atBottomRef.current) {\n if (bubbles > prevBubbles) setNewBelow(n => n + (bubbles - prevBubbles));\n return;\n }\n const behavior: ScrollBehavior = firstAnchorRef.current ? 'auto' : 'smooth';\n firstAnchorRef.current = false;\n forceScrollRef.current = false;\n messagesEndRef.current?.scrollIntoView({ behavior });\n }, [messages]);\n\n // SSE-driven task updates: the server pushes new_reply events to the\n // sender's alias channel (/events/<from_session>), so we just listen for\n // them and patch the matching bubble immediately. No polling needed for\n // the normal path. The polling block below remains as a safety-net for\n // SSE-unavailable environments / disconnect windows.\n // Loop R5 (实时收消息): the subscription used to be gated on\n // pollingIds>0 — an IDLE panel was deaf, so messages sent to this alias\n // by OTHERS (or replies to tasks sent before mount) only appeared on\n // reopen. R1's shared channel makes an always-on subscription free (no\n // extra connection), so:\n // · new_reply for OUR in-flight sends keeps the fast targeted patch;\n // · any other new_task/new_message/new_reply soft-refreshes the\n // window (debounced 1.5s trailing; runFetch merge-by-id keeps\n // optimistic bubbles, so a refresh never drops an in-flight send).\n const refreshTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const lastSoftRefreshRef = useRef(0);\n useEffect(() => () => { if (refreshTimerRef.current) clearTimeout(refreshTimerRef.current); }, []);\n useSSE({\n url: '/api/hub/events',\n enabled: true,\n onEvent: async (e: { type?: string; in_reply_to?: string; message_id?: string }) => {\n const t = e?.type || '';\n if (t === 'new_reply' && e.in_reply_to && pollingIds.has(e.in_reply_to)) {\n // Fast path: a reply to a task WE sent from this panel.\n try {\n const res = await fetch(`/api/hub/tasks?task_id=${encodeURIComponent(e.in_reply_to)}`);\n const data = await res.json();\n const updated = data?.tasks?.[0];\n if (!updated) return;\n setMessages(prev => prev.map(m => m.task_id === e.in_reply_to ? { ...m, ...updated } : m));\n if (['replied', 'failed', 'closed', 'expired', 'cancelled'].includes(updated.status)) {\n setPollingIds(prev => { const n = new Set(prev); n.delete(e.in_reply_to!); return n; });\n }\n } catch {}\n return; // handled — don't ALSO soft-refresh for the same event\n }\n if (!['new_task', 'new_message', 'new_reply', 'broadcast'].includes(t)) return;\n if (!historyLoaded) return; // initial load owns the first paint\n if (!isActive) return; // R11: background tabs catch up on activation instead\n // R11: floor between soft refreshes — on a busy fleet (192 agents)\n // events arrive faster than the 1.5s debounce can coalesce, and the\n // active panel refetched its window ~25×/min. One event batch every\n // ≥6s is plenty for a 12-item history window; sends still patch\n // instantly via the fast path above.\n if (refreshTimerRef.current) clearTimeout(refreshTimerRef.current);\n const wait = Math.max(1500, 6000 - (Date.now() - lastSoftRefreshRef.current));\n refreshTimerRef.current = setTimeout(() => {\n lastSoftRefreshRef.current = Date.now();\n runFetch(HISTORY_PAGE, 12_000);\n }, wait);\n },\n });\n\n // Loop R5b (honest finding): the hub only pushes events on the\n // sender's/recipient's OWN channels — a dashboard observer's channel gets\n // NOTHING for third-party traffic (verified: 12s capture during an\n // api→node send = only \"connected\"). Until the hub grows an observer\n // stream (ask filed), an OPEN panel soft-refreshes every 15s — paused\n // while the tab is hidden — so incoming messages appear without a\n // reopen. runFetch's merge-by-id keeps optimistic bubbles intact.\n // R11 (多面板降频): CommandCenter keeps EVERY tab mounted, so N tabs\n // used to mean N pollers AND N per-SSE-event soft-refreshers — measured\n // 40 history-window fetches/min with 4 tabs on a busy fleet. Only the\n // visible tab refreshes now; a tab returning to the foreground does one\n // immediate catch-up fetch so it never shows stale history.\n const wasActiveRef = useRef(isActive);\n useEffect(() => {\n if (!historyLoaded || !isActive) {\n wasActiveRef.current = isActive;\n return;\n }\n if (!wasActiveRef.current) {\n runFetch(HISTORY_PAGE, 12_000);\n // R27 (微信手感): switching back to a tab refocuses the composer —\n // desktop only (focusing on touch pops the soft keyboard uninvited).\n if (!coarsePointerRef.current) textareaRef.current?.focus();\n }\n wasActiveRef.current = true;\n const id = setInterval(() => {\n if (document.visibilityState === 'hidden') return;\n runFetch(HISTORY_PAGE, 12_000);\n }, 15_000);\n return () => clearInterval(id);\n }, [historyLoaded, isActive, runFetch]);\n\n // Polling fallback (SSE-unavailable / proxies stripping events).\n // Slow cadence so we're not the bulk of server load — SSE handles the fast path.\n useEffect(() => {\n if (pollingIds.size === 0) return;\n // 30s cadence — the SSE listener handles the fast path. Polling only\n // catches state when the SSE connection is unavailable (proxy stripping\n // events, browser HTTP/2 oddities, etc). Cap 1h to match server TTL.\n const startTime = Date.now();\n const interval = setInterval(async () => {\n if (Date.now() - startTime > 3600_000) {\n setPollingIds(new Set());\n clearInterval(interval);\n return;\n }\n for (const taskId of pollingIds) {\n try {\n const res = await fetch(`/api/hub/tasks?task_id=${encodeURIComponent(taskId)}`);\n const data = await res.json();\n if (data.tasks?.[0]) {\n const updated = data.tasks[0];\n setMessages(prev => prev.map(m => m.task_id === taskId ? { ...m, ...updated } : m));\n if (['replied', 'failed', 'closed', 'expired', 'cancelled'].includes(updated.status)) {\n setPollingIds(prev => { const n = new Set(prev); n.delete(taskId); return n; });\n }\n }\n } catch {}\n }\n }, 30_000);\n return () => clearInterval(interval);\n }, [pollingIds]);\n\n // #492 upload half — proxied to hub, Bearer server-side. The\n // returned attachment carries `file_id` (canonical hub identifier)\n // in the STRUCTURED payload only; we deliberately don't put\n // file_id anywhere copy/share-friendly (see #495: hub currently\n // doesn't enforce owner scope on `/api/files/:id`, so a leaked\n // file_id = leaked file).\n //\n // Errors surface via `throw` so `send()` catches them and paints\n // the failed-message bubble with the hub's user-visible `message`\n // (rate-limited / too-large / etc.) — never \"点了没反应\" silence.\n const uploadAttachments = async (files: File[]) => {\n const uploaded: Array<{ file_id: string; name: string; mime?: string; size?: number }> = [];\n if (files.length > 0) setUploadProgress({ done: 0, total: files.length });\n for (const file of files) {\n const form = new FormData();\n form.append('file', file);\n const res = await fetch('/api/hub/upload', { method: 'POST', body: form });\n const data = await res.json().catch(() => ({ ok: false, message: `HTTP ${res.status}` }));\n if (!res.ok || !data.ok || !data.file_id) {\n // Prefer server-provided human-readable `message`; fall back to\n // `error` code / raw status. Include filename for multi-file\n // uploads so the user knows WHICH file failed.\n const msg = data.message || data.error || `HTTP ${res.status}`;\n throw new Error(files.length > 1 ? `${file.name}: ${msg}` : msg);\n }\n uploaded.push({\n file_id: data.file_id,\n name: file.name,\n mime: data.mime || file.type,\n size: data.size ?? file.size,\n });\n setUploadProgress({ done: uploaded.length, total: files.length });\n }\n return uploaded;\n };\n\n const send = async () => {\n if ((!input.trim() && attachedFiles.length === 0) || sending) return;\n let taskContent = input.trim();\n // `alias` is the target rendered in the panel header. Do not mirror it in\n // effect-synchronised state: after switching the singleton chat popover,\n // React can render the new header one frame before that effect runs, and\n // an immediate send would otherwise be delivered to the previous node.\n let sendTo = alias;\n\n // Parse @mention at start: \"@NodeName rest of message\"\n const atMatch = taskContent.match(/^@(\\S+)\\s+([\\s\\S]+)/);\n if (atMatch) {\n const mentioned = mentionNodes.find(n => n.toLowerCase() === atMatch[1].toLowerCase());\n if (mentioned) {\n sendTo = mentioned;\n taskContent = atMatch[2];\n }\n }\n\n const filesToSend = attachedFiles;\n setSending(true);\n setInput('');\n writeDraft(alias, '', networkId);\n forceScrollRef.current = true;\n setAttachedFiles([]);\n setShowMentions(false);\n if (textareaRef.current) textareaRef.current.style.height = 'auto';\n\n // NB: user-visible attachment description only — file_id lives in\n // the structured `meta.attachments` field the LLM/agent side reads.\n // Keeping file_id out of the visible task text is deliberate\n // (#495: leaked file_id = leaked file until owner scope lands).\n const pendingAttachmentText = attachedFiles.length > 0\n ? `\\n\\n[Dashboard 附件待上传]\\n${attachedFiles.map(f => `- 附件: ${f.name}`).join('\\n')}`\n : '';\n\n // Optimistic echo first so the user always sees their message in history\n // even if the network call fails or the server returns ok:false. Earlier\n // version only added on data.ok=true → silent failures looked like\n // 'tasks get swallowed'.\n const requestId = newDashboardRequestId();\n const localTaskId = `tmp-${requestId}`;\n const optimistic: ChatTask = {\n task_id: localTaskId,\n from_name: 'Dashboard',\n to_name: sendTo,\n status: 'created',\n priority,\n content: `${taskContent}${pendingAttachmentText}`.trim(),\n result: '',\n created_at: new Date().toISOString(),\n client_request_id: requestId,\n };\n setMessages(prev => [...prev, optimistic]);\n\n // File objects cannot be restored safely after a browser/app restart.\n // Persist text-only sends; attachment retries remain available for the\n // current session through pendingFilesRef.\n if (filesToSend.length === 0) {\n putChatOutbox({\n requestId, localTaskId, panelAlias: alias, targetAlias: sendTo,\n content: taskContent, priority, networkId: aliasNetRef.current[sendTo] || networkId || '',\n createdAt: optimistic.created_at,\n }, privateStorageScope);\n }\n\n try {\n const uploaded = await uploadAttachments(filesToSend);\n if (uploaded.length > 0) {\n // Human-readable description only — no file_id in visible\n // text (see #495). Receiver's structured `meta.attachments`\n // carries the file_id for cross-host fetch.\n const attachmentText = [\n '',\n '',\n '[Dashboard 附件]',\n ...uploaded.map(f =>\n `- 附件: ${f.name}${f.size != null ? ` (${formatBytesShort(f.size)})` : ''}`,\n ),\n ].join('\\n');\n taskContent = `${taskContent}${attachmentText}`.trim();\n setMessages(prev => prev.map(m =>\n m.task_id === localTaskId ? { ...m, content: taskContent } : m,\n ));\n }\n await postTask(taskContent, sendTo, localTaskId, uploaded, requestId);\n } catch (e: unknown) {\n // Don't prefix \"network error:\" — this catch now covers semantic\n // errors thrown by uploadAttachments (rate-limited, too-large,\n // wrong content-type, ...) which already carry a Chinese\n // human-readable message. Prepending \"network error:\" mangles it\n // into \"❌ network error: 上传太频繁 — 请 30 秒后再试\" which\n // points the user at the wrong layer. If the message really IS\n // a raw fetch failure, `msg` is \"Failed to fetch\" / similar and\n // still reads truthfully without the prefix.\n const msg = e instanceof Error ? e.message : String(e);\n if (filesToSend.length > 0) pendingFilesRef.current.set(localTaskId, filesToSend);\n setMessages(prev => prev.map(m =>\n m.task_id === localTaskId ? { ...m, status: 'failed', result: `❌ ${msg}` } : m,\n ));\n }\n setSending(false);\n setUploadProgress(null);\n textareaRef.current?.focus();\n };\n\n // Core POST shared by send() and the failed-bubble retry (R4: WeChat-style\n // resend — a failed message shouldn't force the user to retype it).\n const postTask = async (taskContent: string, sendTo: string, localTaskId: string, uploaded: Array<{ file_id: string; name: string; mime?: string; size?: number }> = [], requestId?: string) => {\n try {\n const res = await fetch('/api/hub/send', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n alias: sendTo, task: taskContent, priority, attachments: uploaded,\n ...(requestId ? { request_id: requestId } : {}),\n // P0: multi-network users MUST scope the send or the hub rejects.\n ...((aliasNetRef.current[sendTo] || networkId) ? { network_id: aliasNetRef.current[sendTo] || networkId } : {}),\n }),\n });\n const data = await res.json().catch(() => ({ ok: false, error: `HTTP ${res.status}` }));\n const normalized = normalizeChatSendResult(data);\n if (normalized.accepted && normalized.messageId) {\n setMessages(prev => prev.map(m =>\n m.task_id === localTaskId ? { ...m, task_id: normalized.messageId!, status: normalized.status! } : m,\n ));\n setPollingIds(prev => new Set(prev).add(normalized.messageId!));\n if (requestId) removeChatOutbox(requestId, privateStorageScope);\n } else {\n const reason = data.error || data.detail || `send failed (status ${res.status})`;\n setMessages(prev => prev.map(m =>\n m.task_id === localTaskId ? { ...m, status: 'failed', result: `❌ ${reason}` } : m,\n ));\n }\n } catch (e: unknown) {\n // See send() catch above — \"network error:\" prefix is dropped\n // for the same reason. Even for a genuine fetch failure the raw\n // browser message (\"Failed to fetch\") already reads as\n // network-layer without the prefix.\n const msg = e instanceof Error ? e.message : String(e);\n setMessages(prev => prev.map(m =>\n m.task_id === localTaskId ? { ...m, status: 'failed', result: `❌ ${msg}` } : m,\n ));\n }\n };\n\n // R4: tap-to-retry a failed send — reset the SAME bubble to in-flight and\n // re-POST with identical content/target; no retyping (WeChat red-! flow).\n // R36 (发图流程): files whose UPLOAD failed, keyed by the optimistic\n // task id — resend re-uploads them instead of sending the\n // \"[Dashboard 附件待上传]\" placeholder text with no image (measured bug:\n // retry after an upload failure lost the attachment entirely).\n const pendingFilesRef = useRef<Map<string, File[]>>(new Map());\n const retryLockRef = useRef<Set<string>>(new Set());\n const retrySend = async (m: ChatTask) => {\n // R5 (R4 self-review debt): double-click guard — a second tap while the\n // retry POST is in flight must not fire a duplicate send.\n if (retryLockRef.current.has(m.task_id)) return;\n retryLockRef.current.add(m.task_id);\n // Strip the un-uploaded placeholder; a retry with pending files\n // re-uploads them and rebuilds the real attachment block.\n const files = pendingFilesRef.current.get(m.task_id) || [];\n const cleanContent = m.content.replace(/\\n*\\[Dashboard 附件待上传\\][\\s\\S]*$/, '').trim();\n setMessages(prev => prev.map(x =>\n x.task_id === m.task_id ? { ...x, status: 'created', result: '' } : x,\n ));\n try {\n let content = cleanContent;\n let uploaded: Awaited<ReturnType<typeof uploadAttachments>> = [];\n if (files.length > 0) {\n uploaded = await uploadAttachments(files);\n if (uploaded.length > 0) {\n content = `${content}\\n\\n[Dashboard 附件]\\n${uploaded.map(f =>\n `- 附件: ${f.name}${f.size != null ? ` (${formatBytesShort(f.size)})` : ''}`,\n ).join('\\n')}`.trim();\n setMessages(prev => prev.map(x => x.task_id === m.task_id ? { ...x, content } : x));\n }\n }\n await postTask(content, m.to_name, m.task_id, uploaded, m.client_request_id);\n pendingFilesRef.current.delete(m.task_id);\n } catch (e: unknown) {\n const msg = e instanceof Error ? e.message : String(e);\n setMessages(prev => prev.map(x =>\n x.task_id === m.task_id ? { ...x, status: 'failed', result: `❌ ${msg}` } : x,\n ));\n } finally {\n retryLockRef.current.delete(m.task_id);\n setUploadProgress(null);\n }\n };\n\n const handleKeyDown = (e: React.KeyboardEvent) => {\n // R22: while the @ mention dropdown is open the keyboard drives IT —\n // previously Enter SENT the half-typed \"@通\" as a message. ↑↓ move,\n // Enter/Tab select, Escape closes (below).\n if (showMentions && filteredMentions.length > 0) {\n if (e.key === 'ArrowDown') { e.preventDefault(); setMentionIndex((i) => (i + 1) % filteredMentions.length); return; }\n if (e.key === 'ArrowUp') { e.preventDefault(); setMentionIndex((i) => (i - 1 + filteredMentions.length) % filteredMentions.length); return; }\n if (e.key === 'Enter' || e.key === 'Tab') {\n if (!e.nativeEvent.isComposing) { e.preventDefault(); insertMention(filteredMentions[Math.min(mentionIndex, filteredMentions.length - 1)]); }\n return;\n }\n }\n // Enter sends, Shift+Enter inserts newline (standard DESKTOP chat UX —\n // users habit-pressed Enter expecting send). On touch (coarse pointer)\n // Enter inserts a newline instead: phones have no Shift, and WeChat\n // mobile sends via the button.\n if (e.key === 'Enter' && !e.shiftKey && !e.nativeEvent.isComposing) {\n if (coarsePointerRef.current) return; // mobile: newline\n e.preventDefault();\n send();\n }\n if (e.key === 'Escape') setShowMentions(false);\n };\n\n const handleInputChange = (value: string) => {\n setInput(value);\n // Check if user just typed @\n const lastAt = value.lastIndexOf('@');\n if (lastAt >= 0 && (lastAt === 0 || value[lastAt - 1] === ' ' || value[lastAt - 1] === '\\n')) {\n const after = value.slice(lastAt + 1);\n if (!after.includes(' ') && !after.includes('\\n')) {\n setMentionFilter(after.toLowerCase());\n setMentionIndex(0);\n setShowMentions(true);\n return;\n }\n }\n setShowMentions(false);\n };\n\n // #492 — accept any file type (not just images). The hub enforces\n // a 12 MiB per-file cap; we don't pre-reject on the client because\n // (a) the hub is the single source of truth for the limit,\n // (b) even oversize files should attempt the upload so the user\n // sees the hub's \"文件超过 12 MB 上限\" message rather than\n // silent client-side rejection.\n const addFiles = (files: FileList | File[]) => {\n const picked = Array.from(files);\n if (picked.length === 0) return;\n if (attachedFiles.length + picked.length > 6) {\n setAttachLimitHit(true);\n setTimeout(() => setAttachLimitHit(false), 3000);\n }\n setAttachedFiles(prev => [...prev, ...picked].slice(0, 6));\n };\n\n const handlePaste = (e: React.ClipboardEvent<HTMLTextAreaElement>) => {\n const files = Array.from(e.clipboardData.files || []);\n if (files.length > 0) {\n addFiles(files);\n e.preventDefault();\n }\n };\n\n const insertMention = (nodeName: string) => {\n const lastAt = input.lastIndexOf('@');\n const before = input.slice(0, lastAt);\n setInput(`${before}@${nodeName} `);\n setShowMentions(false);\n textareaRef.current?.focus();\n };\n\n const filteredMentions = mentionNodes.filter(n =>\n n !== alias && pinyinMatch(n, mentionFilter)\n ).slice(0, 8);\n\n const autoResize = (el: HTMLTextAreaElement) => {\n el.style.height = 'auto';\n el.style.height = Math.min(el.scrollHeight, 150) + 'px';\n };\n\n const chatEvents: ChatEvent[] = messages\n .flatMap((task): ChatEvent[] => {\n const events: ChatEvent[] = [{ kind: 'task', task, at: task.created_at }];\n // R19: a FAILED send stores its error in `result` — that must not\n // masquerade as an agent reply bubble; the red ! badge carries it.\n if (task.result && task.status !== 'failed') events.push({ kind: 'reply', task, at: task.completed_at || task.created_at });\n return events;\n })\n .sort((a, b) => {\n const delta = eventTime(a.at) - eventTime(b.at);\n if (delta !== 0) return delta;\n if (a.task.task_id !== b.task.task_id) return a.task.task_id.localeCompare(b.task.task_id);\n return a.kind === 'task' ? -1 : 1;\n });\n\n const query = searchQuery.trim().toLowerCase();\n const searchMatches = query\n ? chatEvents\n .filter((ev) => {\n const text = ev.kind === 'reply' ? ev.task.result : ev.task.content;\n return (text || '').toLowerCase().includes(query);\n })\n .map((ev) => `${ev.task.task_id}:${ev.kind}`)\n : [];\n const currentMatchKey = searchMatches.length ? searchMatches[Math.min(searchIdx, searchMatches.length - 1)] : null;\n // New query starts at the NEWEST match (WeChat searches backwards in time).\n useEffect(() => { setSearchIdx(Math.max(0, searchMatches.length - 1)); /* eslint-disable-line react-hooks/exhaustive-deps */ }, [query]);\n useEffect(() => {\n if (!currentMatchKey) return;\n const el = scrollRef.current?.querySelector(`[data-ev=\"${CSS.escape(currentMatchKey)}\"]`);\n el?.scrollIntoView({ block: 'center', behavior: 'smooth' });\n }, [currentMatchKey]);\n const stepMatch = (delta: number) => {\n if (!searchMatches.length) return;\n setSearchIdx((i) => (i + delta + searchMatches.length) % searchMatches.length);\n };\n const closeSearch = () => { setSearchOpen(false); setSearchQuery(''); };\n\n // Inline mode: just the chat content, no panel chrome\n const chatContent = (\n <>\n {/* Messages area */}\n {/* R12 of #190 mobile polish: the chat scroll surface used\n space-y-3 between task+reply pairs at mobile = 12 px, which\n in a long thread (the panel's bread-and-butter use case)\n adds up to a significant scroll length. Drop to space-y-2 at\n mobile and the per-pair grouping (line 540) from space-y-2\n to space-y-1.5 so messages read denser without losing the\n speaker-turn rhythm. Desktop unchanged at sm: and up. */}\n <div ref={scrollRef} onScroll={onMessagesScroll} data-testid=\"chat-messages-scroll\" className=\"flex-1 overflow-y-auto px-3 py-3 sm:px-4 sm:py-4 space-y-2 sm:space-y-4\">\n {searchOpen ? (\n <div className=\"sticky top-0 z-20 -mx-1 flex items-center gap-2 rounded-lg border border-[var(--border)] bg-[var(--bg-elevated)]/95 px-2 py-1.5 shadow-lg shadow-black/30 backdrop-blur\">\n <input\n ref={searchInputRef}\n value={searchQuery}\n onChange={(e) => setSearchQuery(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === 'Escape') { e.stopPropagation(); closeSearch(); }\n else if (e.key === 'Enter' && e.shiftKey) { e.preventDefault(); stepMatch(1); }\n else if (e.key === 'Enter') { e.preventDefault(); stepMatch(-1); }\n }}\n placeholder={t('搜索会话…', 'Search conversation…')}\n className=\"min-w-0 flex-1 bg-transparent text-xs text-[var(--fg)] placeholder-[var(--fg-dim)] focus:outline-none\"\n />\n <span className=\"shrink-0 text-[10px] tabular-nums text-[var(--fg-dim)]\">\n {searchMatches.length ? `${Math.min(searchIdx, searchMatches.length - 1) + 1}/${searchMatches.length}` : searchQuery.trim() ? t('0 条', '0 found') : t(`${chatEvents.length} 条内`, `in ${chatEvents.length}`)}\n </span>\n <button type=\"button\" onClick={() => stepMatch(-1)} aria-label={t('上一条(更早)', 'Previous (older)')} className=\"shrink-0 rounded px-1 text-[var(--fg-dim)] hover:text-cyan-300\">↑</button>\n <button type=\"button\" onClick={() => stepMatch(1)} aria-label={t('下一条(更新)', 'Next (newer)')} className=\"shrink-0 rounded px-1 text-[var(--fg-dim)] hover:text-cyan-300\">↓</button>\n <button type=\"button\" onClick={closeSearch} aria-label={t('关闭搜索', 'Close search')} className=\"shrink-0 rounded px-1 text-[var(--fg-dim)] hover:text-[var(--fg)]\">×</button>\n </div>\n ) : (\n <div className=\"sticky top-0 z-20 flex justify-end pointer-events-none -mb-8\">\n <button\n type=\"button\"\n onClick={() => { setSearchOpen(true); setTimeout(() => searchInputRef.current?.focus(), 50); }}\n aria-label={t('搜索会话', 'Search conversation')}\n className=\"pointer-events-auto inline-flex min-h-[40px] min-w-[40px] items-center justify-center rounded-full border border-[var(--border)] bg-[var(--bg-elevated)]/80 text-[var(--fg-dim)] shadow hover:text-cyan-300 sm:min-h-0 sm:min-w-0 sm:p-1.5\"\n >\n <svg className=\"h-3.5 w-3.5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={2}>\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M21 21l-4.35-4.35M17 11a6 6 0 11-12 0 6 6 0 0112 0z\" />\n </svg>\n </button>\n </div>\n )}\n {!historyLoaded && (\n <div className=\"flex justify-center py-8\">\n <div className=\"w-5 h-5 border-2 border-cyan-500/30 border-t-cyan-500 rounded-full animate-spin\" />\n </div>\n )}\n {/* M4: top-of-thread row — scroll-to-top auto-loads older, and\n the row is also tappable for short threads that don't\n overflow (nothing to scroll). Quiet \"beginning\" marker\n once history is exhausted. */}\n {historyLoaded && hasOlder && messages.length > 0 && (\n <button\n type=\"button\"\n onClick={loadOlder}\n className=\"w-full flex justify-center py-2 text-[11px] text-[var(--fg-dim)] hover:text-[var(--fg-muted)]\"\n >\n {loadingOlder ? (\n <span className=\"w-4 h-4 border-2 border-cyan-500/30 border-t-cyan-500 rounded-full animate-spin\" />\n ) : (\n <span>↑ Load earlier messages</span>\n )}\n </button>\n )}\n {historyLoaded && !hasOlder && messages.length > 0 && (\n <div className=\"text-center text-[10px] text-[var(--fg-dim)] py-1\">— beginning of history —</div>\n )}\n {historyLoaded && !historyError && messages.length === 0 && (\n <div className=\"text-center py-12\">\n <div className=\"text-3xl mb-3\">💬</div>\n <div className=\"text-[var(--fg-muted)] text-sm\">Start a conversation</div>\n <div className=\"text-[var(--fg-dim)] text-xs mt-1\">Send a task to {alias}</div>\n </div>\n )}\n {/* Vincent tg923 + timeout-degrade: both bounded attempts failed —\n usually a congested transport, not the query. Degrade to a calm\n \"slow connection\" message and, crucially, tell the user the\n composer below still works so a stuck history never blocks\n sending. Retry re-runs the full ladder (20 → 6). */}\n {historyLoaded && historyError && messages.length === 0 && (\n <div className=\"text-center py-12\">\n <div className=\"text-[var(--fg-muted)] text-sm\">连接较慢,暂未加载出历史</div>\n <div className=\"text-[var(--fg-dim)] text-xs mt-1\">你仍可在下方直接给 {alias} 发消息</div>\n <button\n type=\"button\"\n onClick={() => loadInitial()}\n className=\"mt-3 text-xs text-cyan-400 hover:text-cyan-300 underline\"\n >\n 重试加载历史\n </button>\n </div>\n )}\n\n {chatEvents.map((event, i) => {\n const m = event.task;\n // WeChat-style time separator: first message, or >5min gap.\n const prevAt = i > 0 ? chatEvents[i - 1].at : null;\n const showSep = !prevAt || eventTime(event.at) - eventTime(prevAt) > TIME_GROUP_GAP_MS;\n const sepEl = showSep ? (\n <div className=\"flex justify-center py-1.5\">\n <span className=\"text-[10px] text-[var(--fg-dim)] bg-[var(--bg-elevated)] rounded px-2 py-0.5\">{formatWeChatTime(event.at)}</span>\n </div>\n ) : null;\n // Distinguish task source so users can tell when a peer agent\n // forwarded a task vs when they themselves sent it from Dashboard.\n const fromUser = !m.from_name || m.from_name === 'Dashboard' || m.from_name === 'api' || m.from_name === 'hub';\n const senderLabel = fromUser ? 'You' : m.from_name;\n const senderBadge = fromUser\n ? null\n : <span className=\"inline-flex items-center gap-1 px-1.5 py-0.5 rounded bg-purple-500/15 border border-purple-500/30 text-[9px] text-purple-300 font-medium\">↳ {m.from_name}</span>;\n if (event.kind === 'reply') {\n return (\n <Fragment key={`${m.task_id}:reply`}>\n {sepEl}\n <div className=\"flex justify-start\" data-ev={`${m.task_id}:reply`}>\n <div title={event.at} className={`group/bubble max-w-[92%] sm:max-w-[min(85%,56ch)] bg-green-500/8 border border-green-500/15 rounded-2xl rounded-bl-md px-3 py-2.5 sm:px-4 shadow-sm ${currentMatchKey === `${m.task_id}:reply` ? 'ring-2 ring-yellow-400/60' : ''}`}>\n <div className=\"flex items-center justify-between gap-2 mb-2\">\n <div className=\"flex items-center gap-1.5 min-w-0\">\n {m.to_name && <AliasAvatar alias={m.to_name} size={14} />}\n <span className=\"text-[10px] text-[var(--fg)] font-medium truncate\">{m.to_name}</span>\n <span className=\"text-[9px] text-green-300/70\">replied</span>\n </div>\n <CopyButton text={m.result || ''} label={t('复制回复', 'Copy reply')} />\n </div>\n <div className=\"mb-2 rounded-lg border-l-2 border-cyan-400/40 bg-black/20 px-2.5 py-1.5\">\n <div className=\"text-[9px] text-cyan-300/80\">\n 引用 {senderLabel} 的任务 · {formatTimestamp(m.created_at)}\n </div>\n <div className=\"mt-0.5 max-h-10 overflow-hidden text-[11px] leading-5 text-[var(--fg-muted)]\">\n {quotePreview(m.content) || 'No content'}\n </div>\n </div>\n <div className=\"text-[14px] leading-[1.65] text-[var(--fg)]\">\n <CollapsibleText><MarkdownContent text={m.result} onImageClick={openLightbox} /></CollapsibleText>\n <AttachmentPreviews text={m.result} onOpen={openLightbox} />\n {/* #492: structured attachments from meta.attachments —\n hub delivers file_id + name/mime/size and the\n <AttachmentBlock> click path fetches via the\n `/api/hub/files/<id>` proxy (Bearer added\n server-side; no token in URL/logs). Historical\n messages render automatic because meta is in the\n persisted task row, not on the wire event. */}\n {extractAttachments(m).map((att, i) => (\n <AttachmentBlock key={`att-r-${att.file_id ?? att.path ?? i}`} attachment={att} />\n ))}\n </div>\n </div>\n </div>\n </Fragment>\n );\n }\n return (\n <Fragment key={`${m.task_id}:task`}>\n {sepEl}\n <div className=\"space-y-1.5 sm:space-y-2\">\n {/* Outgoing task — labeled with origin so peer-forwarded tasks are obvious */}\n <div className=\"flex items-center justify-end gap-1.5\" data-ev={`${m.task_id}:task`}>\n {m.status === 'failed' && fromUser && (\n <button\n type=\"button\"\n onClick={() => setErrorFor((cur) => (cur === m.task_id ? null : m.task_id))}\n title={(m.result || '').replace(/^❌\\s*/, '') || t('发送失败', 'Send failed')}\n aria-label={t('发送失败,点击查看原因', 'Send failed — tap for reason')}\n aria-expanded={errorFor === m.task_id}\n className=\"flex h-[18px] w-[18px] shrink-0 items-center justify-center rounded-full bg-red-500 text-[11px] font-bold leading-none text-white\"\n >\n !\n </button>\n )}\n <div title={m.created_at} className={`group/bubble max-w-[92%] sm:max-w-[min(85%,56ch)] bg-cyan-500/8 border border-cyan-500/15 rounded-2xl rounded-br-md px-3 py-2.5 sm:px-4 shadow-sm ${currentMatchKey === `${m.task_id}:task` ? 'ring-2 ring-yellow-400/60' : ''}`}>\n <div className=\"flex items-center gap-2 mb-1\">\n <span className={`text-[10px] font-medium ${fromUser ? 'text-cyan-400' : 'text-purple-300'}`}>{senderLabel}</span>\n {!fromUser && <span className=\"text-[9px] text-[var(--fg-dim)]\">forwarded to {m.to_name}</span>}\n <span className=\"flex-1\" />\n <CopyButton text={m.content || ''} label={t('复制内容', 'Copy message')} />\n </div>\n <div className=\"text-[14px] leading-[1.65] text-[var(--fg)]\">\n <CollapsibleText><MarkdownContent text={m.content} onImageClick={openLightbox} /></CollapsibleText>\n <AttachmentPreviews text={m.content} onOpen={openLightbox} />\n {/* #492: outbound-task attachments render too — user\n uploads with a task carry file_id in meta_json;\n showing them here means the send-side and\n receive-side see the same clickable blocks. */}\n {extractAttachments(m).map((att, i) => (\n <AttachmentBlock key={`att-t-${att.file_id ?? att.path ?? i}`} attachment={att} />\n ))}\n </div>\n <div className=\"flex flex-wrap items-center justify-between mt-1.5 gap-2 sm:gap-3\">\n <StatusBar status={m.status} result={m.result} />\n <div className=\"flex items-center gap-2 shrink-0\">\n {/* R4: WeChat send-feedback loop — spinner while the\n optimistic bubble is still in flight; tap-to-resend\n on failure (same bubble, no retyping). */}\n {m.task_id.startsWith('tmp-') && m.status !== 'failed' && (\n <span aria-label={t('发送中', 'Sending')} className=\"inline-block h-3 w-3 animate-spin rounded-full border-2 border-cyan-500/30 border-t-cyan-400\" />\n )}\n {m.status === 'failed' && fromUser && (\n <button\n type=\"button\"\n onClick={() => retrySend(m)}\n className=\"inline-flex items-center gap-1 rounded-md border border-red-500/40 bg-red-500/10 px-1.5 py-0.5 text-[10px] font-medium text-red-300 hover:bg-red-500/20\"\n >\n <span aria-hidden>↻</span> {t('重发', 'Resend')}\n </button>\n )}\n {senderBadge}\n </div>\n </div>\n </div>\n </div>\n\n {m.status === 'failed' && errorFor === m.task_id && (\n <div className=\"flex justify-end\">\n <div className=\"max-w-[92%] rounded-lg border border-red-500/30 bg-red-500/10 px-2.5 py-1.5 text-[11px] leading-5 text-red-300\">\n {(m.result || '').replace(/^❌\\s*/, '') || t('发送失败', 'Send failed')}\n </div>\n </div>\n )}\n\n {/* Typing indicator when running */}\n {m.status === 'running' && !m.result && (\n <div className=\"flex justify-start\">\n <div className=\"bg-[var(--bg-secondary)] border border-[var(--border)] rounded-2xl rounded-bl-md px-4 py-3\">\n <div className=\"flex gap-1\">\n <span className=\"w-2 h-2 rounded-full bg-gray-500 animate-bounce\" style={{ animationDelay: '0s' }} />\n <span className=\"w-2 h-2 rounded-full bg-gray-500 animate-bounce\" style={{ animationDelay: '0.15s' }} />\n <span className=\"w-2 h-2 rounded-full bg-gray-500 animate-bounce\" style={{ animationDelay: '0.3s' }} />\n </div>\n </div>\n </div>\n )}\n </div>\n </Fragment>\n );\n })}\n <div ref={messagesEndRef} />\n {newBelow > 0 && (\n <div className=\"sticky bottom-1 z-10 flex justify-center pointer-events-none\">\n <button\n type=\"button\"\n onClick={() => {\n setNewBelow(0);\n atBottomRef.current = true;\n messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });\n }}\n className=\"pointer-events-auto flex items-center gap-1 rounded-full border border-cyan-500/30 bg-[var(--bg-elevated)] px-3 py-1 text-[11px] text-cyan-300 shadow-lg shadow-black/40 hover:bg-cyan-500/10\"\n >\n ↓ {t(`${newBelow} 条新消息`, `${newBelow} new message${newBelow > 1 ? 's' : ''}`)}\n </button>\n </div>\n )}\n </div>\n\n {/* Input area */}\n <div className=\"border-t border-[var(--border)] bg-[var(--bg-secondary)] px-3 py-3 pb-[calc(0.75rem+env(safe-area-inset-bottom))] sm:px-4\">\n <div className=\"flex items-end gap-2\">\n <div className=\"flex-1 relative\">\n {/* @ mention dropdown */}\n {showMentions && filteredMentions.length > 0 && (\n <div className=\"absolute bottom-full left-0 right-0 mb-1 bg-[var(--bg-secondary)] border border-[var(--border)] rounded-lg shadow-xl shadow-black/50 overflow-hidden z-10 max-h-48 overflow-y-auto\">\n {filteredMentions.map((node, i) => (\n <button key={node} onClick={() => insertMention(node)}\n onMouseEnter={() => setMentionIndex(i)}\n aria-selected={i === mentionIndex}\n className={`w-full flex items-center gap-2 px-3 py-2 text-xs text-left transition-colors ${i === mentionIndex ? 'bg-cyan-500/10' : 'hover:bg-cyan-500/10'}`}>\n <AliasAvatar alias={node} size={16} />\n <span className=\"text-[var(--fg-muted)]\">{node}</span>\n </button>\n ))}\n </div>\n )}\n <textarea\n ref={textareaRef}\n value={input}\n onChange={e => { handleInputChange(e.target.value); autoResize(e.target); }}\n onKeyDown={handleKeyDown}\n onPaste={handlePaste}\n placeholder={`Message ${alias}...`}\n rows={1}\n className=\"w-full bg-[var(--bg-secondary)] border border-[var(--border)] rounded-xl px-3 py-2.5 pr-24 text-base sm:px-4 sm:text-sm text-[var(--fg)] placeholder-[var(--fg-dim)] focus:border-cyan-500/40 focus:outline-none resize-none transition-colors\"\n />\n <div className=\"absolute right-2 bottom-1.5 flex items-center gap-1\">\n <label className=\"inline-flex min-h-[44px] min-w-[44px] -my-3 -mx-1.5 items-center justify-center sm:min-h-0 sm:min-w-0 sm:m-0 sm:p-1 text-[var(--fg-dim)] hover:text-cyan-300 cursor-pointer rounded hover:bg-cyan-500/10\" title={t('附加文件', 'Attach file')}>\n <input\n type=\"file\"\n multiple\n className=\"hidden\"\n onChange={e => { if (e.target.files) addFiles(e.target.files); e.currentTarget.value = ''; }}\n />\n <svg className=\"w-3.5 h-3.5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={2}>\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M16.5 6.5l-7.78 7.78a3 3 0 104.24 4.24l8.49-8.49a5 5 0 00-7.07-7.07L5.89 11.45a7 7 0 109.9 9.9l7.07-7.07\" />\n </svg>\n </label>\n <select value={priority} onChange={e => setPriority(e.target.value)}\n className=\"bg-transparent text-[9px] text-[var(--fg-dim)] focus:outline-none cursor-pointer\">\n <option value=\"normal\">N</option>\n <option value=\"high\">H</option>\n <option value=\"low\">L</option>\n </select>\n </div>\n </div>\n {/* R17 of #190: send button was p-2.5 + w-5 icon = ~40 x 40\n hit zone, 4 px short of the iOS 44 px guideline on\n the short axis. Bump to inline-flex + min-h/w 44. */}\n <button onClick={send} aria-label=\"Send message\" disabled={sending || (!input.trim() && attachedFiles.length === 0)}\n className=\"inline-flex min-h-[44px] min-w-[44px] items-center justify-center bg-cyan-600 hover:bg-cyan-500 disabled:bg-[var(--border)] disabled:text-[var(--fg-dim)] text-[var(--fg)] rounded-xl transition-all shrink-0 active:scale-95\">\n {sending ? (\n <div className=\"w-5 h-5 border-2 border-white/30 border-t-white rounded-full animate-spin\" />\n ) : (\n <svg className=\"w-5 h-5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={2}>\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M6 12L3.269 3.126A59.768 59.768 0 0121.485 12 59.77 59.77 0 013.27 20.876L5.999 12zm0 0h7.5\" />\n </svg>\n )}\n </button>\n </div>\n {uploadProgress && (\n <div className=\"mt-1 flex items-center gap-1.5 text-[10px] text-cyan-300\" role=\"status\">\n <span className=\"inline-block h-2.5 w-2.5 animate-spin rounded-full border-2 border-cyan-500/30 border-t-cyan-400\" />\n {t(`上传附件 ${uploadProgress.done}/${uploadProgress.total}…`, `Uploading ${uploadProgress.done}/${uploadProgress.total}…`)}\n </div>\n )}\n {attachLimitHit && (\n <div className=\"mt-1 text-[10px] text-amber-400\" role=\"status\">{t('最多同时附带 6 个附件', 'Up to 6 attachments at a time')}</div>\n )}\n {attachedFiles.length > 0 && (\n <div className=\"mt-2 flex flex-wrap gap-2\">\n {attachedFiles.map((file, index) => (\n <LocalFilePreview\n key={`${file.name}-${file.size}-${index}`}\n file={file}\n onRemove={() => setAttachedFiles(prev => prev.filter((_, i) => i !== index))}\n />\n ))}\n </div>\n )}\n <div className=\"hidden sm:flex justify-between text-[9px] text-[var(--fg-dim)] mt-1.5\">\n <span>{input.includes('@') ? `Sending to: ${alias}` : `Type @ to mention another node`}</span>\n <span>Enter to send · paste image</span>\n </div>\n </div>\n {lightbox && <ImageLightbox urls={lightbox.urls} initialIndex={lightbox.idx} opener={lightboxOpenerRef.current} onClose={() => setLightbox(null)} />}\n </>\n );\n\n if (inline) {\n return <div className=\"flex flex-col h-full\">{chatContent}</div>;\n }\n\n return (\n <>\n <div className=\"fixed inset-0 bg-black/30 z-40 lg:hidden anet-fade-in\" onClick={onClose} />\n <div className=\"fixed top-0 right-0 h-[100dvh] w-full lg:w-[640px] xl:w-[760px] 2xl:w-[860px] bg-[var(--bg)] border-l border-[var(--border)] z-50 flex flex-col shadow-2xl shadow-black/60 animate-slide-in\">\n {/* Header */}\n <div className=\"flex items-center justify-between px-4 py-3 border-b border-[var(--border)] bg-[var(--bg-secondary)]\">\n <div className=\"flex items-center gap-3\">\n <AliasAvatar alias={alias} size={32} />\n <div>\n <div className=\"flex items-center gap-1.5 text-sm font-semibold text-[var(--fg)]\">\n <span>{alias}</span>\n {chatMuted && (\n <svg aria-label={t('已开启免打扰', 'Muted')} role=\"img\" className=\"h-3.5 w-3.5 text-[var(--fg-dim)]\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={1.8}>\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M9.88 4.12A6 6 0 0118 9v3.6l1.5 2.4H12M6.3 6.3A5.98 5.98 0 006 9v3.6L4.5 15H13M10 19a2 2 0 004 0M3 3l18 18\" />\n </svg>\n )}\n </div>\n <div className=\"flex items-center gap-1.5 text-[10px] text-[var(--fg-muted)]\">\n {sseOnline !== null && (\n <span aria-hidden className={`inline-block h-1.5 w-1.5 rounded-full ${sseOnline ? 'bg-green-400' : 'bg-gray-600'}`} />\n )}\n <span>\n {pollingIds.size > 0\n ? t('处理中…', 'Processing…')\n : sseOnline === null ? 'Ready' : sseOnline ? t('在线', 'Online') : t('离线', 'Offline')}\n </span>\n </div>\n </div>\n </div>\n {/* R16 of #190: was p-1.5 + w-5 h-5 svg = ~32 px tap target.\n The chat panel close is high-frequency on mobile (user\n dismisses to scroll the underlying page); bump to a\n uniform 44 x 44 hit zone via inline-flex + min-h/w. */}\n <button onClick={onClose} aria-label=\"Close chat\" className=\"inline-flex min-h-[44px] min-w-[44px] items-center justify-center text-[var(--fg-muted)] hover:text-[var(--fg)] rounded-lg hover:bg-[var(--bg-elevated)]\">\n <svg className=\"w-5 h-5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" strokeWidth={2}>\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M6 18L18 6M6 6l12 12\" />\n </svg>\n </button>\n </div>\n {chatContent}\n </div>\n </>\n );\n}\n","export interface ChatSendResult {\n accepted: boolean;\n messageId?: string;\n status?: string;\n}\n\nexport function newDashboardRequestId(cryptoImpl: Crypto = globalThis.crypto): string {\n if (typeof cryptoImpl.randomUUID === 'function') {\n return `dreq_${cryptoImpl.randomUUID().replace(/-/g, '')}`;\n }\n // randomUUID is secure-context-only in some browsers/webviews, while\n // getRandomValues remains available on LAN HTTP deployments.\n const bytes = cryptoImpl.getRandomValues(new Uint8Array(16));\n return `dreq_${Array.from(bytes, byte => byte.toString(16).padStart(2, '0')).join('')}`;\n}\n\nexport function normalizeChatSendResult(data: unknown): ChatSendResult {\n if (!data || typeof data !== 'object') return { accepted: false };\n const value = data as Record<string, unknown>;\n const messageId = typeof value.message_id === 'string' && value.message_id ? value.message_id : undefined;\n if (!messageId || (value.ok !== true && value.queued !== true)) return { accepted: false };\n return {\n accepted: true,\n messageId,\n status: value.queued === true\n ? 'queued'\n : (typeof value.task_status === 'string' && value.task_status ? value.task_status : 'delivered'),\n };\n}\n\nexport function requestIdFromTaskMeta(metaJson: unknown): string | null {\n if (typeof metaJson !== 'string' || !metaJson) return null;\n try {\n const parsed = JSON.parse(metaJson);\n const value = parsed?.client_request_id;\n return typeof value === 'string' && /^dreq_[A-Za-z0-9_-]{16,96}$/.test(value) ? value : null;\n } catch {\n return null;\n }\n}\n","'use client';\n\nimport { useSyncExternalStore } from 'react';\nimport { CHAT_DRAFT_PREFIX, chatPrivateScope } from './chat-outbox';\n\n// Loop R10 (微信草稿闭环): draft storage shared between the chat panel\n// (write/restore) and conversation-list surfaces (the \"[草稿]\" mark).\n// Same-tab reactivity via a custom event, cross-tab via the storage event.\nconst DRAFT_EVENT = 'anet-chat-draft-updated';\n\nfunction draftKey(scope: string, alias: string) { return `${CHAT_DRAFT_PREFIX}${scope}:${encodeURIComponent(alias)}`; }\n\nexport function readDraft(alias?: string | null, networkId?: string | null): string {\n if (typeof window === 'undefined' || !alias) return '';\n try {\n const scope = chatPrivateScope(networkId);\n return scope ? window.localStorage.getItem(draftKey(scope, alias)) || '' : '';\n } catch {\n return '';\n }\n}\n\n/** Empty/whitespace text deletes the draft — sending or clearing the box\n * leaves no stale key behind. */\nexport function writeDraft(alias: string, text: string, networkId?: string | null) {\n if (typeof window === 'undefined' || !alias) return;\n try {\n const scope = chatPrivateScope(networkId);\n if (!scope) return;\n const key = draftKey(scope, alias);\n if (text.trim()) window.localStorage.setItem(key, text);\n else window.localStorage.removeItem(key);\n window.dispatchEvent(new CustomEvent(DRAFT_EVENT, { detail: { alias } }));\n } catch {}\n}\n\nfunction subscribe(callback: () => void) {\n window.addEventListener(DRAFT_EVENT, callback);\n window.addEventListener('storage', callback);\n return () => {\n window.removeEventListener(DRAFT_EVENT, callback);\n window.removeEventListener('storage', callback);\n };\n}\n\nexport function useHasDraft(alias?: string | null): boolean {\n return useSyncExternalStore(\n subscribe,\n () => (alias ? Boolean(readDraft(alias)) : false),\n () => false,\n );\n}\n","export interface TaskHistoryRow {\n task_id: string;\n created_at: string;\n client_request_id?: string;\n}\n\nexport interface TaskHistoryCursor {\n task_id: string;\n created_at: string;\n}\n\nexport function buildTaskHistoryUrl(\n alias: string,\n limit: number,\n cursor?: TaskHistoryCursor,\n): string {\n const query = new URLSearchParams({ to_name: alias, limit: String(limit) });\n if (cursor) {\n query.set('before', cursor.created_at);\n query.set('before_task_id', cursor.task_id);\n }\n return `/api/hub/tasks?${query.toString()}`;\n}\n\nexport function oldestTaskHistoryCursor(\n oldestFirstRows: readonly TaskHistoryRow[],\n): TaskHistoryCursor | null {\n const row = oldestFirstRows.find((task) =>\n task.task_id\n && !task.task_id.startsWith('tmp-')\n && !task.client_request_id\n && task.created_at,\n );\n return row ? { task_id: row.task_id, created_at: row.created_at } : null;\n}\n\nfunction rowTime(value: string): number {\n const normalized = value.includes('T') ? value : `${value.replace(' ', 'T')}Z`;\n const timestamp = Date.parse(normalized);\n return Number.isFinite(timestamp) ? timestamp : 0;\n}\n\nexport function mergeTaskHistoryPage<T extends TaskHistoryRow>(\n current: readonly T[],\n newestFirstPage: readonly T[],\n persistedRequestIds: ReadonlySet<string> = new Set(),\n): T[] {\n const fetchedIds = new Set(newestFirstPage.map((task) => task.task_id));\n const retained = current.filter((task) =>\n !fetchedIds.has(task.task_id)\n && (!task.client_request_id || !persistedRequestIds.has(task.client_request_id)),\n );\n return [...newestFirstPage, ...retained].sort((a, b) => {\n const timeDelta = rowTime(a.created_at) - rowTime(b.created_at);\n return timeDelta || a.task_id.localeCompare(b.task_id);\n });\n}\n","'use client';\n\nimport { useEffect, useRef, useState } from 'react';\n\nexport interface SSEEvent {\n type: string;\n [key: string]: unknown;\n}\n\ninterface UseSSEOptions {\n /** SSE endpoint URL */\n url: string;\n /** Callback for each event */\n onEvent?: (event: SSEEvent) => void;\n /** Auto-reconnect delay in ms (default 3000) */\n reconnectDelay?: number;\n /** Enable/disable (default true) */\n enabled?: boolean;\n}\n\n/* ────────────────────────────────────────────────────────────────────\n WeChat-optimization loop R1 (性能主线 · HOL 根治第一步):\n\n Previously every mounted consumer owned its own EventSource — Overview\n plus EACH open chat panel/tab meant N+1 long-lived connections. On\n HTTP/1.1 the browser caps ~6 connections per host, so a few chat tabs\n saturated the pool and every later fetch (chat history, RSC payloads,\n SWR polls) queued behind them → the \"整页超时\" class of jank.\n\n Now a module-level CHANNEL is shared per URL: one probe, one\n EventSource, one reconnect loop — any number of subscribers. The hook\n keeps its exact public API ({connected, lastEvent, supported}), so\n consumers are untouched. The channel tears down when the last\n subscriber unmounts (refcount), preserving the old leak-free\n navigation behavior.\n ──────────────────────────────────────────────────────────────────── */\n\ntype ChannelState = {\n es: EventSource | null;\n probeAbort: AbortController | null;\n reconnectTimer: ReturnType<typeof setTimeout> | null;\n unsupported: boolean;\n connected: boolean;\n supported: boolean | null;\n reconnectDelay: number;\n subscribers: Set<{\n onEvent?: (e: SSEEvent) => void;\n onStatus: (connected: boolean, supported: boolean | null) => void;\n }>;\n};\n\nconst channels = new Map<string, ChannelState>();\n\nfunction broadcastStatus(ch: ChannelState) {\n for (const s of ch.subscribers) s.onStatus(ch.connected, ch.supported);\n}\n\nfunction connectChannel(url: string) {\n const ch = channels.get(url);\n if (!ch || ch.unsupported || ch.subscribers.size === 0) return;\n if (ch.es) { ch.es.close(); ch.es = null; }\n if (ch.probeAbort) ch.probeAbort.abort();\n\n const probeUrl = url.includes('?') ? `${url}&probe=1` : `${url}?probe=1`;\n const probeController = new AbortController();\n ch.probeAbort = probeController;\n const probeTimeout = setTimeout(() => probeController.abort(), 5000);\n\n fetch(probeUrl, { method: 'HEAD', cache: 'no-store', signal: probeController.signal })\n .finally(() => clearTimeout(probeTimeout))\n .then((res) => {\n if (ch.subscribers.size === 0) return; // everyone left mid-probe\n if (res.headers.get('x-anet-sse-available') !== 'true') {\n ch.unsupported = true;\n ch.connected = false;\n ch.supported = false;\n broadcastStatus(ch);\n return;\n }\n ch.supported = true;\n const es = new EventSource(url);\n ch.es = es;\n\n es.onopen = () => { ch.connected = true; broadcastStatus(ch); };\n\n es.onmessage = (e) => {\n try {\n const data: SSEEvent = JSON.parse(e.data);\n for (const s of ch.subscribers) s.onEvent?.(data);\n } catch {}\n };\n\n es.onerror = () => {\n ch.connected = false;\n broadcastStatus(ch);\n es.close();\n ch.es = null;\n if (ch.subscribers.size > 0) {\n ch.reconnectTimer = setTimeout(() => connectChannel(url), ch.reconnectDelay);\n }\n };\n })\n .catch(() => {\n if (ch.subscribers.size === 0) return;\n ch.connected = false;\n ch.supported = false;\n broadcastStatus(ch);\n });\n}\n\nfunction teardownChannel(url: string) {\n const ch = channels.get(url);\n if (!ch) return;\n if (ch.probeAbort) { ch.probeAbort.abort(); ch.probeAbort = null; }\n if (ch.es) { ch.es.close(); ch.es = null; }\n if (ch.reconnectTimer) { clearTimeout(ch.reconnectTimer); ch.reconnectTimer = null; }\n channels.delete(url);\n}\n\n/**\n * Hook to subscribe to CommHub SSE events.\n * Falls back gracefully — if SSE fails, SWR polling continues working.\n * All subscribers to the same URL share ONE EventSource (see header note).\n */\nexport function useSSE({ url, onEvent, reconnectDelay = 3000, enabled = true }: UseSSEOptions) {\n const [connected, setConnected] = useState(false);\n const [lastEvent, setLastEvent] = useState<SSEEvent | null>(null);\n const [supported, setSupported] = useState<boolean | null>(null);\n\n // Hold onEvent in a ref so callers can pass an inline callback without it\n // resubscribing every render (page.tsx re-renders on each SWR mutate —\n // pre-fix this churned real connections; now it would only churn the\n // subscriber entry, but stability still costs nothing to keep).\n const onEventRef = useRef(onEvent);\n useEffect(() => { onEventRef.current = onEvent; }, [onEvent]);\n\n useEffect(() => {\n if (!enabled || !url) {\n return;\n }\n\n let ch = channels.get(url);\n if (!ch) {\n ch = {\n es: null, probeAbort: null, reconnectTimer: null,\n unsupported: false, connected: false, supported: null,\n reconnectDelay, subscribers: new Set(),\n };\n channels.set(url, ch);\n }\n\n const sub = {\n onEvent: (e: SSEEvent) => { setLastEvent(e); onEventRef.current?.(e); },\n onStatus: (c: boolean, s: boolean | null) => { setConnected(c); setSupported(s); },\n };\n ch.subscribers.add(sub);\n // reflect current channel state immediately (late joiners) — one-shot\n // sync FROM the external channel store at subscribe time.\n // eslint-disable-next-line react-hooks/set-state-in-effect\n setConnected(ch.connected);\n // eslint-disable-next-line react-hooks/set-state-in-effect\n setSupported(ch.supported);\n\n const needsConnect = !ch.es && !ch.probeAbort && !ch.unsupported;\n if (needsConnect) connectChannel(url);\n\n return () => {\n const c = channels.get(url);\n if (!c) return;\n c.subscribers.delete(sub);\n if (c.subscribers.size === 0) teardownChannel(url);\n };\n }, [url, enabled, reconnectDelay]);\n\n // Disabled/urlless hooks report a derived quiet state instead of writing\n // it back via setState-in-effect (lint: react-hooks/set-state-in-effect).\n const active = enabled && !!url;\n return { connected: active ? connected : false, lastEvent, supported: active ? supported : (enabled ? null : false) };\n}\n"],"names":["newDashboardRequestId","cryptoImpl","globalThis","crypto","randomUUID","replace","bytes","getRandomValues","Uint8Array","Array","from","byte","toString","padStart","join","normalizeChatSendResult","data","accepted","value","messageId","message_id","undefined","ok","queued","status","task_status","requestIdFromTaskMeta","metaJson","parsed","JSON","parse","client_request_id","test","DRAFT_EVENT","draftKey","scope","alias","encodeURIComponent","readDraft","networkId","writeDraft","text","subscribe","callback","window","addEventListener","removeEventListener","useHasDraft","Boolean","buildTaskHistoryUrl","limit","cursor","query","URLSearchParams","to_name","String","set","created_at","task_id","oldestTaskHistoryCursor","oldestFirstRows","row","find","task","startsWith","rowTime","normalized","includes","timestamp","Date","Number","isFinite","mergeTaskHistoryPage","current","newestFirstPage","persistedRequestIds","Set","fetchedIds","map","retained","filter","has","sort","a","b","timeDelta","localeCompare"],"mappings":"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"}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
module.exports=[1720,a=>{"use strict";var b=a.i(87924),c=a.i(72131),d=a.i(34507);let e=[180,200,220,270,300,330,30,90];function f(a){let b=0;for(let c=0;c<a.length;c++)b=31*b+a.charCodeAt(c)>>>0;let c=e[b%e.length];return{bg:`hsl(${c} 55% 22%)`,ring:`hsl(${c} 60% 45%)`,text:`hsl(${c} 80% 78%)`}}function g(a){return a?(a.trim().match(/[\p{L}\p{N}]/u)?.[0]||a.trim()[0]||"·").toUpperCase():"·"}a.s(["AliasAvatar",0,function({alias:a,size:e=28,className:h=""}){let i=(0,d.useAvatarUrl)(a),[j,k]=(0,c.useState)("loading"),[l,m]=(0,c.useState)(i);if(i!==l&&(m(i),k("loading")),i&&"error"!==j)return(0,b.jsx)("span",{className:`anet-alias-avatar relative inline-flex shrink-0 overflow-hidden rounded-full border border-[var(--border)] ${"loading"===j?"animate-pulse bg-[var(--bg-elevated)]":""} ${h}`,style:{width:e,height:e},title:a,"aria-hidden":!0,children:(0,b.jsx)("img",{src:i,alt:"",loading:"lazy",onLoad:()=>k("ready"),onError:()=>k("error"),className:`h-full w-full rounded-full object-cover transition-opacity duration-150 ${"ready"===j?"opacity-100":"opacity-0"}`})});if(/\bgrok\b|grok-build|grok测试员|grok-demo/i.test(a))return(0,b.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 ${h}`,style:{width:e,height:e,backgroundImage:"url(/vendors/grok.svg)",backgroundPosition:"center",backgroundRepeat:"no-repeat",backgroundSize:"68% 68%"},title:a,"aria-hidden":!0});let n=f(a),o=Math.max(9,Math.round(.42*e));return(0,b.jsx)("span",{className:`anet-alias-avatar inline-flex items-center justify-center rounded-full border shrink-0 font-semibold ${h}`,style:{width:e,height:e,fontSize:o,backgroundColor:n.bg,borderColor:n.ring,color:n.text},title:a,"aria-hidden":!0,children:g(a)})},"aliasAvatarColors",0,f,"aliasInitial",0,g])},53142,a=>{"use strict";var b=a.i(87924),c=a.i(72131),d=a.i(38246);let e={nodes:{title:"No agents in this network",sub:"Agent sessions will appear here once they connect to the CommHub."},tasks:{title:"No tasks yet",sub:"Tasks will appear here when agents send them via CommHub."},messages:{title:"No messages",sub:"Messages between agents will appear here."},logs:{title:"No audit logs",sub:"Events will appear here when users register, login, or perform actions."},tokens:{title:"No API tokens",sub:"Create one to authenticate CLI tools and external integrations."},networks:{title:"No networks found",sub:"Create one or sign in with V3 auth to see your networks."},generic:{title:"Nothing here yet",sub:"Data will appear here once available."}};function f({variant:a,size:c}){let d={width:c,height:c},e={fill:"none",stroke:"currentColor",strokeWidth:1.25,strokeLinecap:"round",strokeLinejoin:"round"};switch(a){case"nodes":return(0,b.jsx)("svg",{viewBox:"0 0 64 64",...d,children:(0,b.jsxs)("g",{...e,children:[(0,b.jsx)("circle",{cx:"32",cy:"14",r:"4"}),(0,b.jsx)("circle",{cx:"14",cy:"44",r:"4"}),(0,b.jsx)("circle",{cx:"50",cy:"44",r:"4"}),(0,b.jsx)("line",{x1:"32",y1:"18",x2:"14",y2:"40",strokeDasharray:"3 3",opacity:"0.6"}),(0,b.jsx)("line",{x1:"32",y1:"18",x2:"50",y2:"40",strokeDasharray:"3 3",opacity:"0.6"}),(0,b.jsx)("line",{x1:"18",y1:"44",x2:"46",y2:"44",strokeDasharray:"3 3",opacity:"0.6"})]})});case"tasks":return(0,b.jsx)("svg",{viewBox:"0 0 64 64",...d,children:(0,b.jsxs)("g",{...e,children:[(0,b.jsx)("rect",{x:"14",y:"14",width:"36",height:"6",rx:"1.5"}),(0,b.jsx)("rect",{x:"14",y:"26",width:"36",height:"6",rx:"1.5",opacity:"0.6"}),(0,b.jsx)("rect",{x:"14",y:"38",width:"36",height:"6",rx:"1.5",opacity:"0.35"})]})});case"messages":return(0,b.jsx)("svg",{viewBox:"0 0 64 64",...d,children:(0,b.jsxs)("g",{...e,children:[(0,b.jsx)("path",{d:"M14 18 h36 a3 3 0 0 1 3 3 v18 a3 3 0 0 1 -3 3 h-18 l-8 6 v-6 h-10 a3 3 0 0 1 -3 -3 v-18 a3 3 0 0 1 3 -3 z"}),(0,b.jsx)("line",{x1:"22",y1:"28",x2:"42",y2:"28",opacity:"0.5"}),(0,b.jsx)("line",{x1:"22",y1:"34",x2:"36",y2:"34",opacity:"0.5"})]})});case"logs":return(0,b.jsx)("svg",{viewBox:"0 0 64 64",...d,children:(0,b.jsxs)("g",{...e,children:[(0,b.jsx)("path",{d:"M18 12 h22 l8 8 v32 a2 2 0 0 1 -2 2 h-28 a2 2 0 0 1 -2 -2 v-38 a2 2 0 0 1 2 -2 z"}),(0,b.jsx)("path",{d:"M40 12 v8 h8",opacity:"0.6"}),(0,b.jsx)("line",{x1:"24",y1:"32",x2:"40",y2:"32",opacity:"0.55"}),(0,b.jsx)("line",{x1:"24",y1:"38",x2:"40",y2:"38",opacity:"0.4"}),(0,b.jsx)("line",{x1:"24",y1:"44",x2:"34",y2:"44",opacity:"0.25"})]})});case"tokens":return(0,b.jsx)("svg",{viewBox:"0 0 64 64",...d,children:(0,b.jsxs)("g",{...e,children:[(0,b.jsx)("circle",{cx:"22",cy:"32",r:"8"}),(0,b.jsx)("line",{x1:"30",y1:"32",x2:"54",y2:"32"}),(0,b.jsx)("line",{x1:"44",y1:"32",x2:"44",y2:"38"}),(0,b.jsx)("line",{x1:"50",y1:"32",x2:"50",y2:"40"})]})});case"networks":return(0,b.jsx)("svg",{viewBox:"0 0 64 64",...d,children:(0,b.jsxs)("g",{...e,children:[(0,b.jsx)("circle",{cx:"32",cy:"32",r:"18"}),(0,b.jsx)("ellipse",{cx:"32",cy:"32",rx:"18",ry:"9",opacity:"0.55"}),(0,b.jsx)("line",{x1:"14",y1:"32",x2:"50",y2:"32",opacity:"0.55"}),(0,b.jsx)("line",{x1:"32",y1:"14",x2:"32",y2:"50",opacity:"0.55"})]})});default:return(0,b.jsx)("svg",{viewBox:"0 0 64 64",...d,children:(0,b.jsxs)("g",{...e,children:[(0,b.jsx)("circle",{cx:"32",cy:"32",r:"14",strokeDasharray:"3 3",opacity:"0.6"}),(0,b.jsx)("circle",{cx:"32",cy:"32",r:"3"})]})})}}function g({variant:a="generic",title:c,sub:h,cta:i,compact:j=!1}){let k=e[a],l=c??k.title,m=h??k.sub;return(0,b.jsxs)("div",{className:`text-center ${j?"py-8":"py-16"} px-4`,role:"status",children:[(0,b.jsx)("div",{className:"anet-empty-glyph inline-flex items-center justify-center mb-4 text-gray-500","aria-hidden":!0,children:(0,b.jsx)(f,{variant:a,size:j?40:56})}),(0,b.jsx)("h3",{className:`font-medium text-gray-300 ${j?"text-sm":"text-base"}`,children:l}),m&&(0,b.jsx)("p",{className:`text-gray-500 ${j?"text-xs mt-1.5":"text-sm mt-2"} max-w-md mx-auto leading-relaxed`,children:m}),i&&(0,b.jsx)("div",{className:"mt-4",children:i.href?(0,b.jsxs)(d.default,{href:i.href,className:"inline-flex items-center gap-1.5 text-sm font-medium text-cyan-400 hover:text-cyan-300",children:[i.label,(0,b.jsx)("span",{"aria-hidden":!0,children:"→"})]}):(0,b.jsxs)("button",{onClick:i.onClick,className:"inline-flex items-center gap-1.5 text-sm font-medium text-cyan-400 hover:text-cyan-300",children:[i.label,(0,b.jsx)("span",{"aria-hidden":!0,children:"→"})]})})]})}function h({children:a}){return(0,b.jsx)("div",{className:"max-w-2xl mx-auto rounded-xl border border-[#26262b] bg-[#161618] shadow-lg shadow-black/20",children:a})}function i({cmd:a}){let[d,e]=(0,c.useState)(!1),f=async()=>{try{await navigator.clipboard.writeText(a),e(!0),setTimeout(()=>e(!1),1800)}catch{}};return(0,b.jsxs)("div",{className:"anet-empty-cmd flex items-start sm:items-center gap-2 bg-[#0e0e10] border border-[#26262b] rounded-lg pl-4 pr-1.5 py-1.5 text-xs sm:text-sm",children:[(0,b.jsx)("code",{className:"text-cyan-300 font-mono select-all min-w-0 break-all sm:break-normal",children:a}),(0,b.jsx)("button",{type:"button",onClick:f,"aria-label":d?"Copied":"Copy command",className:"shrink-0 rounded-md px-2 py-1.5 text-[11px] text-gray-500 hover:text-gray-200 hover:bg-[#1c1c1f] transition-colors",children:d?(0,b.jsxs)("span",{className:"flex items-center gap-1 text-green-400",children:[(0,b.jsx)("svg",{width:"12",height:"12",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:(0,b.jsx)("path",{d:"M20 6 9 17l-5-5"})}),"Copied"]}):(0,b.jsxs)("span",{className:"flex items-center gap-1",children:[(0,b.jsxs)("svg",{width:"12",height:"12",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round",children:[(0,b.jsx)("rect",{x:"9",y:"9",width:"13",height:"13",rx:"2",ry:"2"}),(0,b.jsx)("path",{d:"M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"})]}),"Copy"]})})]})}a.s(["EmptyState",0,g,"NodesEmptyState",0,function({hint:a,taskHistoryCount:c=0}){return a?.global_count?(0,b.jsx)(h,{children:(0,b.jsx)(g,{variant:"nodes",title:"No agents in this network",sub:`Server has ${a.global_count} nodes globally, but none are registered to the current network. Switch network or contact admin.`})}):c>0?(0,b.jsx)(h,{children:(0,b.jsx)(g,{variant:"nodes",title:"No agents online",sub:`Every agent in this network is currently offline. ${c.toLocaleString()} task${1===c?"":"s"} in history — they may have finished their work or disconnected.`,cta:{label:"View task history",href:"/tasks"}})}):(0,b.jsx)(h,{children:(0,b.jsxs)("div",{className:"text-center py-16 px-4",role:"status",children:[(0,b.jsx)("div",{className:"anet-empty-glyph inline-flex items-center justify-center mb-4 text-gray-500","aria-hidden":!0,children:(0,b.jsx)("svg",{viewBox:"0 0 64 64",width:56,height:56,children:(0,b.jsxs)("g",{stroke:"currentColor",strokeWidth:"1.5",fill:"none",children:[(0,b.jsx)("rect",{x:"10",y:"20",width:"44",height:"28",rx:"2"}),(0,b.jsx)("rect",{x:"20",y:"32",width:"6",height:"8",opacity:"0.5"}),(0,b.jsx)("rect",{x:"32",y:"32",width:"6",height:"8",opacity:"0.5"}),(0,b.jsx)("rect",{x:"44",y:"32",width:"4",height:"8",opacity:"0.5"}),(0,b.jsx)("line",{x1:"10",y1:"26",x2:"54",y2:"26",opacity:"0.4"}),(0,b.jsx)("circle",{cx:"14",cy:"23",r:"0.8",fill:"currentColor"})]})})}),(0,b.jsx)("h3",{className:"font-medium text-gray-300 text-base",children:"Spin up your first agent"}),(0,b.jsx)("p",{className:"text-gray-500 text-sm mt-2 max-w-md mx-auto leading-relaxed",children:"Run this in a fresh terminal to register an agent with this CommHub:"}),(0,b.jsx)("div",{className:"mt-4 inline-block",children:(0,b.jsx)(i,{cmd:"npx --yes @sleep2agi/agent-network init"})}),(0,b.jsx)("p",{className:"text-gray-600 text-xs mt-3 max-w-md mx-auto",children:"Once the agent connects, it appears here automatically within a few seconds — no refresh needed."}),(0,b.jsx)("div",{className:"mt-3",children:(0,b.jsxs)("a",{href:"https://anet.sh",target:"_blank",rel:"noopener noreferrer",className:"inline-flex items-center gap-1.5 text-xs font-medium text-gray-500 hover:text-cyan-300",children:["Full quickstart guide",(0,b.jsx)("span",{"aria-hidden":!0,children:"→"})]})})]})})}])},43515,a=>{"use strict";var b=a.i(89706);a.s(["previewContent",0,function(a){return a&&a.replace(/!\[([^\]]*)\]\([^)]*\)/g,"$1").replace(/\[([^\]]+)\]\([^)]*\)/g,"$1").replace(/`([^`]+)`/g,"$1").replace(/\s+/g," ").trim()||"--"},"timeAgo",0,function(a){return(0,b.relativeAgo)(a)??"--"}])},114,a=>{"use strict";a.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"]])},40083,a=>{"use strict";var b=a.i(87924),c=a.i(72131),d=a.i(16177);a.s(["default",0,function({params:a}){let{id:e}=(0,c.use)(a);return(0,b.jsx)(d.TasksView,{initialSelectedId:(0,d.decodeIdSegment)(e)})}])}];
|
|
2
2
|
|
|
3
|
-
//# sourceMappingURL=
|
|
3
|
+
//# sourceMappingURL=app_1ua57bx._.js.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
module.exports=[42588,a=>{"use strict";var b=a.i(87924),c=a.i(50944),d=a.i(38246),e=a.i(76194),f=a.i(72131),g=a.i(72596),h=a.i(22397),i=a.i(69237),j=a.i(44332),k=a.i(6439),l=a.i(5537);let m=["expanded","collapsed","icon-rail"],n="anet-sidebar-mode",o={expanded:"展开",collapsed:"折叠","icon-rail":"图标"},p=a=>fetch(a).then(a=>a.ok?a.json():{networks:[]}),q=[{href:"/nodes",label:"Nodes",icon:"M5 12h14M5 12a2 2 0 01-2-2V6a2 2 0 012-2h14a2 2 0 012 2v4a2 2 0 01-2 2M5 12a2 2 0 00-2 2v4a2 2 0 002 2h14a2 2 0 002-2v-4a2 2 0 00-2-2m-2-4h.01M17 16h.01"},{href:"/",label:"Overview",icon:"M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6"},{href:"/scheduled-tasks",label:"Schedules",icon:"M12 6v6l4 2m5-2a9 9 0 11-18 0 9 9 0 0118 0z"},{href:"/skillhub",label:"SkillHub",icon:"M12 6.253v13m0-13C10.832 5.477 9.246 5 7.5 5S4.168 5.477 3 6.253v13C4.168 18.477 5.754 18 7.5 18s3.332.477 4.5 1.253m0-13C13.168 5.477 14.754 5 16.5 5s3.332.477 4.5 1.253v13C19.832 18.477 18.246 18 16.5 18s-3.332.477-4.5 1.253"},{href:"/tasks",label:"Tasks",icon:"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"},{href:"/servers",label:"Servers",icon:"M4 6.5A2.5 2.5 0 016.5 4h11A2.5 2.5 0 0120 6.5v1A2.5 2.5 0 0117.5 10h-11A2.5 2.5 0 014 7.5v-1zM4 16.5A2.5 2.5 0 016.5 14h11a2.5 2.5 0 012.5 2.5v1a2.5 2.5 0 01-2.5 2.5h-11A2.5 2.5 0 014 17.5v-1zM7 7h.01M7 17h.01"},{href:"/providers",label:"Providers",icon:"M9 3v2m6-2v2M9 19v2m6-2v2M5 9H3m2 6H3m18-6h-2m2 6h-2M7 19h10a2 2 0 002-2V7a2 2 0 00-2-2H7a2 2 0 00-2 2v10a2 2 0 002 2zM9 9h6v6H9V9z"},{href:"/admin",label:"Admin",icon:"M12 4.354a4 4 0 110 5.292M15 21H3v-1a6 6 0 0112 0v1zm0 0h6v-1a6 6 0 00-9-5.197M13 7a4 4 0 11-8 0 4 4 0 018 0z"},{href:"/settings",label:"Settings",icon:"M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.066 2.573c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.573 1.066c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.066-2.573c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z M15 12a3 3 0 11-6 0 3 3 0 016 0z"}],r={owner:"⭐",admin:"🔧",member:"👤",viewer:"👁"};function s(){let a=(0,c.usePathname)(),[i,j]=(0,f.useState)("expanded");(0,f.useEffect)(()=>{try{let a=localStorage.getItem(n);a&&m.includes(a)&&j(a)}catch{}},[]);let s="expanded"!==i,v="icon-rail"===i,{totalUnread:w}=(0,k.useChatUnread)(),x={"/nodes":w},y=["cyber","light","slack"],z={cyber:"深色",light:"浅色",slack:"Slack"},[A,B]=(0,f.useState)("cyber");(0,f.useEffect)(()=>{try{let a=localStorage.getItem("anet-theme");a&&z[a]&&B(a)}catch{}},[]);let[C,D]=(0,f.useState)(!1),[E,F]=(0,f.useState)(!1),G=(0,f.useRef)(null),{networkId:H,setNetworkId:I}=(0,h.useNetworkId)(),{data:J}=(0,g.default)("/api/hub/networks",p,{refreshInterval:15e3,dedupingInterval:1e4}),{data:K}=(0,g.default)("/api/hub/status",t,{refreshInterval:15e3,dedupingInterval:1e4}),L=J?.networks||[],M=(()=>{let a=new Map;for(let b of K?.sessions||[])b.network_id&&a.set(b.network_id,(a.get(b.network_id)||0)+1);let b=new Set(L.map(a=>a.network_id)),c=[...L,...[...a.keys()].filter(a=>!b.has(a)).map(a=>({network_id:a,network_name:a}))].map(b=>({...b,agentCount:a.get(b.network_id)||0})),d=new Map;for(let a of c)d.set(a.network_name,(d.get(a.network_name)||0)+1);return c.map(a=>({...a,displayName:(d.get(a.network_name)||0)>1?`${a.network_name} \xb7 ${a.network_id.replace(/^net_/,"").slice(0,6)}`:a.network_name})).sort((a,b)=>(b.agentCount||0)-(a.agentCount||0))})(),N=M.find(a=>a.network_id===H)||M[0];(0,f.useEffect)(()=>{if(!E)return;let a=a=>{G.current&&!G.current.contains(a.target)&&F(!1)},b=a=>{"Escape"===a.key&&F(!1)};return document.addEventListener("mousedown",a),document.addEventListener("keydown",b),()=>{document.removeEventListener("mousedown",a),document.removeEventListener("keydown",b)}},[E]);let O=(0,b.jsx)("nav",{className:`flex flex-col ${v?"gap-2 px-0 py-2 items-center":"gap-1 px-2 py-4"}`,"data-sidebar-nav":!0,children:q.map(c=>{var e;let f=v?x[c.href]??0:0,g="/"===(e=c.href)?"/"===a:"/settings"===e?"/settings"===a:a.startsWith(e);return v?(0,b.jsxs)(d.default,{href:c.href,prefetch:!1,onClick:()=>D(!1),title:c.label,"aria-label":c.label,"data-nav-item":!0,"data-nav-href":c.href,"data-nav-active":g?"true":void 0,"data-badge":f>0?String(f):void 0,className:"relative flex items-center justify-center w-11 h-11 group anet-nav-item-rail",children:[g&&(0,b.jsx)("span",{"aria-hidden":!0,"data-nav-active-bar":!0,className:"absolute left-0 top-1/2 -translate-y-1/2 w-[3px] h-5 rounded-[2px] bg-[var(--hl)]"}),(0,b.jsx)("span",{className:`flex items-center justify-center w-10 h-10 rounded-lg transition-colors ${g?"bg-[rgba(125,211,252,0.12)] text-[var(--hl)]":"text-[var(--fg-dim)] hover:text-[var(--fg)] hover:bg-[rgba(255,255,255,0.04)]"}`,children:(0,b.jsx)("svg",{className:"w-6 h-6 shrink-0",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:1.5,children:(0,b.jsx)("path",{strokeLinecap:"round",strokeLinejoin:"round",d:c.icon})})}),f>0&&(0,b.jsx)("span",{"aria-label":`${c.label} — ${(0,k.badgeLabel)(f)} unread`,"data-nav-badge":!0,className:"absolute top-0 right-0 min-w-[16px] h-4 px-1 rounded-full bg-red-500 text-white text-[9px] font-semibold leading-4 text-center pointer-events-none",children:(0,k.badgeLabel)(f)})]},c.href):(0,b.jsxs)(d.default,{href:c.href,prefetch:!1,onClick:()=>D(!1),title:s?c.label:void 0,"aria-label":c.label,"data-nav-item":!0,"data-nav-href":c.href,"data-nav-active":g?"true":void 0,className:`relative flex items-center gap-3 rounded-lg text-sm transition-colors active:bg-[#232327] ${g?"bg-cyan-500/10 text-cyan-300 border border-cyan-500/20 anet-nav-active":"text-gray-400 hover:text-gray-200 hover:bg-[#1c1c1f]"} ${s?"justify-center px-0 py-3":"px-3 py-3"}`,children:[(0,b.jsx)("svg",{className:"w-5 h-5 shrink-0",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:1.5,children:(0,b.jsx)("path",{strokeLinecap:"round",strokeLinejoin:"round",d:c.icon})}),!s&&(0,b.jsx)("span",{children:c.label})]},c.href)})});return(0,b.jsxs)(b.Fragment,{children:[(0,b.jsx)("button",{onClick:()=>D(!C),className:"fixed top-3 left-3 z-50 lg:hidden bg-[#161618] border border-[#26262b] rounded-lg p-3 min-h-[44px] min-w-[44px] inline-flex items-center justify-center text-gray-400 hover:text-white active:bg-[#232327]","aria-label":"Toggle menu",children:(0,b.jsx)("svg",{className:"w-5 h-5",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:2,children:C?(0,b.jsx)("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M6 18L18 6M6 6l12 12"}):(0,b.jsx)("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M4 6h16M4 12h16M4 18h16"})})}),C&&(0,b.jsx)("div",{className:"fixed inset-0 bg-black/50 z-30 lg:hidden anet-fade-in",onClick:()=>D(!1)}),(0,b.jsxs)("aside",{"data-anet-sidebar":"true","data-sidebar-mode":i,"data-total-unread":w,className:`
|
|
1
|
+
module.exports=[42588,a=>{"use strict";var b=a.i(87924),c=a.i(50944),d=a.i(38246),e=a.i(76194),f=a.i(72131),g=a.i(72596),h=a.i(22397),i=a.i(69237),j=a.i(44332),k=a.i(6439),l=a.i(5537);let m=["expanded","collapsed","icon-rail"],n="anet-sidebar-mode",o={expanded:"展开",collapsed:"折叠","icon-rail":"图标"},p=a=>fetch(a).then(a=>a.ok?a.json():{networks:[]}),q=[{href:"/nodes",label:"Nodes",icon:"M5 12h14M5 12a2 2 0 01-2-2V6a2 2 0 012-2h14a2 2 0 012 2v4a2 2 0 01-2 2M5 12a2 2 0 00-2 2v4a2 2 0 002 2h14a2 2 0 002-2v-4a2 2 0 00-2-2m-2-4h.01M17 16h.01"},{href:"/",label:"Overview",icon:"M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6"},{href:"/scheduled-tasks",label:"Schedules",icon:"M12 6v6l4 2m5-2a9 9 0 11-18 0 9 9 0 0118 0z"},{href:"/skillhub",label:"SkillHub",icon:"M12 6.253v13m0-13C10.832 5.477 9.246 5 7.5 5S4.168 5.477 3 6.253v13C4.168 18.477 5.754 18 7.5 18s3.332.477 4.5 1.253m0-13C13.168 5.477 14.754 5 16.5 5s3.332.477 4.5 1.253v13C19.832 18.477 18.246 18 16.5 18s-3.332.477-4.5 1.253"},{href:"/tasks",label:"Tasks",icon:"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"},{href:"/requirements",label:"Requirements",icon:"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2M9 9h6M9 13h6M9 17h3"},{href:"/org",label:"Organization",icon:"M17 20h5v-2a4 4 0 00-3-3.87M9 20H4v-2a4 4 0 013-3.87m6-1.13a4 4 0 10-4-4 4 4 0 004 4zm6 0a3 3 0 10-2.6-4.5M9 7a3 3 0 10-2.6 4.5"},{href:"/servers",label:"Servers",icon:"M4 6.5A2.5 2.5 0 016.5 4h11A2.5 2.5 0 0120 6.5v1A2.5 2.5 0 0117.5 10h-11A2.5 2.5 0 014 7.5v-1zM4 16.5A2.5 2.5 0 016.5 14h11a2.5 2.5 0 012.5 2.5v1a2.5 2.5 0 01-2.5 2.5h-11A2.5 2.5 0 014 17.5v-1zM7 7h.01M7 17h.01"},{href:"/providers",label:"Providers",icon:"M9 3v2m6-2v2M9 19v2m6-2v2M5 9H3m2 6H3m18-6h-2m2 6h-2M7 19h10a2 2 0 002-2V7a2 2 0 00-2-2H7a2 2 0 00-2 2v10a2 2 0 002 2zM9 9h6v6H9V9z"},{href:"/admin",label:"Admin",icon:"M12 4.354a4 4 0 110 5.292M15 21H3v-1a6 6 0 0112 0v1zm0 0h6v-1a6 6 0 00-9-5.197M13 7a4 4 0 11-8 0 4 4 0 018 0z"},{href:"/settings",label:"Settings",icon:"M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.066 2.573c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.573 1.066c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.066-2.573c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z M15 12a3 3 0 11-6 0 3 3 0 016 0z"}],r={owner:"⭐",admin:"🔧",member:"👤",viewer:"👁"};function s(){let a=(0,c.usePathname)(),[i,j]=(0,f.useState)("expanded");(0,f.useEffect)(()=>{try{let a=localStorage.getItem(n);a&&m.includes(a)&&j(a)}catch{}},[]);let s="expanded"!==i,v="icon-rail"===i,{totalUnread:w}=(0,k.useChatUnread)(),x={"/nodes":w},y=["cyber","light","slack"],z={cyber:"深色",light:"浅色",slack:"Slack"},[A,B]=(0,f.useState)("cyber");(0,f.useEffect)(()=>{try{let a=localStorage.getItem("anet-theme");a&&z[a]&&B(a)}catch{}},[]);let[C,D]=(0,f.useState)(!1),[E,F]=(0,f.useState)(!1),G=(0,f.useRef)(null),{networkId:H,setNetworkId:I}=(0,h.useNetworkId)(),{data:J}=(0,g.default)("/api/hub/networks",p,{refreshInterval:15e3,dedupingInterval:1e4}),{data:K}=(0,g.default)("/api/hub/status",t,{refreshInterval:15e3,dedupingInterval:1e4}),L=J?.networks||[],M=(()=>{let a=new Map;for(let b of K?.sessions||[])b.network_id&&a.set(b.network_id,(a.get(b.network_id)||0)+1);let b=new Set(L.map(a=>a.network_id)),c=[...L,...[...a.keys()].filter(a=>!b.has(a)).map(a=>({network_id:a,network_name:a}))].map(b=>({...b,agentCount:a.get(b.network_id)||0})),d=new Map;for(let a of c)d.set(a.network_name,(d.get(a.network_name)||0)+1);return c.map(a=>({...a,displayName:(d.get(a.network_name)||0)>1?`${a.network_name} \xb7 ${a.network_id.replace(/^net_/,"").slice(0,6)}`:a.network_name})).sort((a,b)=>(b.agentCount||0)-(a.agentCount||0))})(),N=M.find(a=>a.network_id===H)||M[0];(0,f.useEffect)(()=>{if(!E)return;let a=a=>{G.current&&!G.current.contains(a.target)&&F(!1)},b=a=>{"Escape"===a.key&&F(!1)};return document.addEventListener("mousedown",a),document.addEventListener("keydown",b),()=>{document.removeEventListener("mousedown",a),document.removeEventListener("keydown",b)}},[E]);let O=(0,b.jsx)("nav",{className:`flex flex-col ${v?"gap-2 px-0 py-2 items-center":"gap-1 px-2 py-4"}`,"data-sidebar-nav":!0,children:q.map(c=>{var e;let f=v?x[c.href]??0:0,g="/"===(e=c.href)?"/"===a:"/settings"===e?"/settings"===a:a.startsWith(e);return v?(0,b.jsxs)(d.default,{href:c.href,prefetch:!1,onClick:()=>D(!1),title:c.label,"aria-label":c.label,"data-nav-item":!0,"data-nav-href":c.href,"data-nav-active":g?"true":void 0,"data-badge":f>0?String(f):void 0,className:"relative flex items-center justify-center w-11 h-11 group anet-nav-item-rail",children:[g&&(0,b.jsx)("span",{"aria-hidden":!0,"data-nav-active-bar":!0,className:"absolute left-0 top-1/2 -translate-y-1/2 w-[3px] h-5 rounded-[2px] bg-[var(--hl)]"}),(0,b.jsx)("span",{className:`flex items-center justify-center w-10 h-10 rounded-lg transition-colors ${g?"bg-[rgba(125,211,252,0.12)] text-[var(--hl)]":"text-[var(--fg-dim)] hover:text-[var(--fg)] hover:bg-[rgba(255,255,255,0.04)]"}`,children:(0,b.jsx)("svg",{className:"w-6 h-6 shrink-0",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:1.5,children:(0,b.jsx)("path",{strokeLinecap:"round",strokeLinejoin:"round",d:c.icon})})}),f>0&&(0,b.jsx)("span",{"aria-label":`${c.label} — ${(0,k.badgeLabel)(f)} unread`,"data-nav-badge":!0,className:"absolute top-0 right-0 min-w-[16px] h-4 px-1 rounded-full bg-red-500 text-white text-[9px] font-semibold leading-4 text-center pointer-events-none",children:(0,k.badgeLabel)(f)})]},c.href):(0,b.jsxs)(d.default,{href:c.href,prefetch:!1,onClick:()=>D(!1),title:s?c.label:void 0,"aria-label":c.label,"data-nav-item":!0,"data-nav-href":c.href,"data-nav-active":g?"true":void 0,className:`relative flex items-center gap-3 rounded-lg text-sm transition-colors active:bg-[#232327] ${g?"bg-cyan-500/10 text-cyan-300 border border-cyan-500/20 anet-nav-active":"text-gray-400 hover:text-gray-200 hover:bg-[#1c1c1f]"} ${s?"justify-center px-0 py-3":"px-3 py-3"}`,children:[(0,b.jsx)("svg",{className:"w-5 h-5 shrink-0",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:1.5,children:(0,b.jsx)("path",{strokeLinecap:"round",strokeLinejoin:"round",d:c.icon})}),!s&&(0,b.jsx)("span",{children:c.label})]},c.href)})});return(0,b.jsxs)(b.Fragment,{children:[(0,b.jsx)("button",{onClick:()=>D(!C),className:"fixed top-3 left-3 z-50 lg:hidden bg-[#161618] border border-[#26262b] rounded-lg p-3 min-h-[44px] min-w-[44px] inline-flex items-center justify-center text-gray-400 hover:text-white active:bg-[#232327]","aria-label":"Toggle menu",children:(0,b.jsx)("svg",{className:"w-5 h-5",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",strokeWidth:2,children:C?(0,b.jsx)("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M6 18L18 6M6 6l12 12"}):(0,b.jsx)("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M4 6h16M4 12h16M4 18h16"})})}),C&&(0,b.jsx)("div",{className:"fixed inset-0 bg-black/50 z-30 lg:hidden anet-fade-in",onClick:()=>D(!1)}),(0,b.jsxs)("aside",{"data-anet-sidebar":"true","data-sidebar-mode":i,"data-total-unread":w,className:`
|
|
2
2
|
fixed top-0 left-0 h-full z-40 flex flex-col
|
|
3
3
|
transition-transform duration-200 ease-out
|
|
4
4
|
${"expanded"===i?"w-52 bg-[#111113] border-r border-[#26262b]":"icon-rail"===i?"w-14 bg-[#0A0C14]":"w-16 bg-[#111113] border-r border-[#26262b]"}
|