@sleep2agi/agent-network-dashboard 0.4.6-preview.17 → 0.4.6-preview.170
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.next/BUILD_ID +1 -1
- package/.next/app-path-routes-manifest.json +1 -0
- package/.next/build-manifest.json +3 -3
- package/.next/diagnostics/route-bundle-stats.json +41 -41
- package/.next/fallback-build-manifest.json +3 -3
- package/.next/prerender-manifest.json +3 -3
- package/.next/routes-manifest.json +6 -0
- package/.next/server/app/_global-error.html +1 -1
- package/.next/server/app/_global-error.rsc +1 -1
- package/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/.next/server/app/_not-found.html +2 -2
- package/.next/server/app/_not-found.rsc +12 -12
- package/.next/server/app/_not-found.segments/_full.segment.rsc +12 -12
- package/.next/server/app/_not-found.segments/_head.segment.rsc +4 -4
- package/.next/server/app/_not-found.segments/_index.segment.rsc +7 -7
- package/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +2 -2
- package/.next/server/app/_not-found.segments/_not-found.segment.rsc +3 -3
- package/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/admin/page_client-reference-manifest.js +1 -1
- package/.next/server/app/admin.html +2 -2
- package/.next/server/app/admin.rsc +14 -14
- package/.next/server/app/admin.segments/_full.segment.rsc +14 -14
- package/.next/server/app/admin.segments/_head.segment.rsc +4 -4
- package/.next/server/app/admin.segments/_index.segment.rsc +7 -7
- package/.next/server/app/admin.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/admin.segments/admin/__PAGE__.segment.rsc +4 -4
- package/.next/server/app/admin.segments/admin.segment.rsc +3 -3
- package/.next/server/app/api/hub/servers/route/app-paths-manifest.json +3 -0
- package/.next/server/app/api/hub/servers/route/build-manifest.json +9 -0
- package/.next/server/app/api/hub/servers/route/server-reference-manifest.json +4 -0
- package/.next/server/app/api/hub/servers/route.js +7 -0
- package/.next/server/app/api/hub/servers/route.js.map +5 -0
- package/.next/server/app/api/hub/servers/route.js.nft.json +1 -0
- package/.next/server/app/api/hub/servers/route_client-reference-manifest.js +3 -0
- package/.next/server/app/index.html +2 -2
- package/.next/server/app/index.rsc +14 -14
- package/.next/server/app/index.segments/__PAGE__.segment.rsc +4 -4
- package/.next/server/app/index.segments/_full.segment.rsc +14 -14
- package/.next/server/app/index.segments/_head.segment.rsc +4 -4
- package/.next/server/app/index.segments/_index.segment.rsc +7 -7
- package/.next/server/app/index.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/login/page_client-reference-manifest.js +1 -1
- package/.next/server/app/login.html +2 -2
- package/.next/server/app/login.rsc +14 -14
- package/.next/server/app/login.segments/_full.segment.rsc +14 -14
- package/.next/server/app/login.segments/_head.segment.rsc +4 -4
- package/.next/server/app/login.segments/_index.segment.rsc +7 -7
- package/.next/server/app/login.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/login.segments/login/__PAGE__.segment.rsc +4 -4
- package/.next/server/app/login.segments/login.segment.rsc +3 -3
- package/.next/server/app/logs/page_client-reference-manifest.js +1 -1
- package/.next/server/app/logs.html +2 -2
- package/.next/server/app/logs.rsc +14 -14
- package/.next/server/app/logs.segments/_full.segment.rsc +14 -14
- package/.next/server/app/logs.segments/_head.segment.rsc +4 -4
- package/.next/server/app/logs.segments/_index.segment.rsc +7 -7
- package/.next/server/app/logs.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/logs.segments/logs/__PAGE__.segment.rsc +4 -4
- package/.next/server/app/logs.segments/logs.segment.rsc +3 -3
- package/.next/server/app/messages/page_client-reference-manifest.js +1 -1
- package/.next/server/app/messages.html +2 -2
- package/.next/server/app/messages.rsc +14 -14
- package/.next/server/app/messages.segments/_full.segment.rsc +14 -14
- package/.next/server/app/messages.segments/_head.segment.rsc +4 -4
- package/.next/server/app/messages.segments/_index.segment.rsc +7 -7
- package/.next/server/app/messages.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/messages.segments/messages/__PAGE__.segment.rsc +4 -4
- package/.next/server/app/messages.segments/messages.segment.rsc +3 -3
- package/.next/server/app/node/page_client-reference-manifest.js +1 -1
- package/.next/server/app/node.html +2 -2
- package/.next/server/app/node.rsc +14 -14
- package/.next/server/app/node.segments/_full.segment.rsc +14 -14
- package/.next/server/app/node.segments/_head.segment.rsc +4 -4
- package/.next/server/app/node.segments/_index.segment.rsc +7 -7
- package/.next/server/app/node.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/node.segments/node/__PAGE__.segment.rsc +4 -4
- package/.next/server/app/node.segments/node.segment.rsc +3 -3
- package/.next/server/app/nodes/page_client-reference-manifest.js +1 -1
- package/.next/server/app/nodes.html +2 -2
- package/.next/server/app/nodes.rsc +14 -14
- package/.next/server/app/nodes.segments/_full.segment.rsc +14 -14
- package/.next/server/app/nodes.segments/_head.segment.rsc +4 -4
- package/.next/server/app/nodes.segments/_index.segment.rsc +7 -7
- package/.next/server/app/nodes.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/nodes.segments/nodes/__PAGE__.segment.rsc +4 -4
- package/.next/server/app/nodes.segments/nodes.segment.rsc +3 -3
- package/.next/server/app/page_client-reference-manifest.js +1 -1
- package/.next/server/app/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 +14 -14
- package/.next/server/app/server-logs.segments/_full.segment.rsc +14 -14
- package/.next/server/app/server-logs.segments/_head.segment.rsc +4 -4
- package/.next/server/app/server-logs.segments/_index.segment.rsc +7 -7
- package/.next/server/app/server-logs.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/server-logs.segments/server-logs/__PAGE__.segment.rsc +4 -4
- package/.next/server/app/server-logs.segments/server-logs.segment.rsc +3 -3
- package/.next/server/app/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 +14 -14
- package/.next/server/app/settings/networks.segments/_full.segment.rsc +14 -14
- package/.next/server/app/settings/networks.segments/_head.segment.rsc +4 -4
- package/.next/server/app/settings/networks.segments/_index.segment.rsc +7 -7
- package/.next/server/app/settings/networks.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/settings/networks.segments/settings/networks/__PAGE__.segment.rsc +4 -4
- package/.next/server/app/settings/networks.segments/settings/networks.segment.rsc +3 -3
- package/.next/server/app/settings/networks.segments/settings.segment.rsc +3 -3
- package/.next/server/app/settings/page_client-reference-manifest.js +1 -1
- package/.next/server/app/settings/tokens/page_client-reference-manifest.js +1 -1
- package/.next/server/app/settings/tokens.html +2 -2
- package/.next/server/app/settings/tokens.rsc +14 -14
- package/.next/server/app/settings/tokens.segments/_full.segment.rsc +14 -14
- package/.next/server/app/settings/tokens.segments/_head.segment.rsc +4 -4
- package/.next/server/app/settings/tokens.segments/_index.segment.rsc +7 -7
- package/.next/server/app/settings/tokens.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/settings/tokens.segments/settings/tokens/__PAGE__.segment.rsc +4 -4
- package/.next/server/app/settings/tokens.segments/settings/tokens.segment.rsc +3 -3
- package/.next/server/app/settings/tokens.segments/settings.segment.rsc +3 -3
- package/.next/server/app/settings.html +2 -2
- package/.next/server/app/settings.rsc +14 -14
- package/.next/server/app/settings.segments/_full.segment.rsc +14 -14
- package/.next/server/app/settings.segments/_head.segment.rsc +4 -4
- package/.next/server/app/settings.segments/_index.segment.rsc +7 -7
- package/.next/server/app/settings.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/settings.segments/settings/__PAGE__.segment.rsc +4 -4
- package/.next/server/app/settings.segments/settings.segment.rsc +3 -3
- package/.next/server/app/tasks/[id]/page_client-reference-manifest.js +1 -1
- package/.next/server/app/tasks/page_client-reference-manifest.js +1 -1
- package/.next/server/app/tasks.html +2 -2
- package/.next/server/app/tasks.rsc +14 -14
- package/.next/server/app/tasks.segments/_full.segment.rsc +14 -14
- package/.next/server/app/tasks.segments/_head.segment.rsc +4 -4
- package/.next/server/app/tasks.segments/_index.segment.rsc +7 -7
- package/.next/server/app/tasks.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/tasks.segments/tasks/__PAGE__.segment.rsc +4 -4
- package/.next/server/app/tasks.segments/tasks.segment.rsc +3 -3
- package/.next/server/app-paths-manifest.json +1 -0
- package/.next/server/chunks/0ykm__next-internal_server_app_api_hub_servers_route_actions_08-m-cs.js +3 -0
- package/.next/server/chunks/0ykm__next-internal_server_app_api_hub_servers_route_actions_08-m-cs.js.map +1 -0
- package/.next/server/chunks/[root-of-the-server]__0tx8s8i._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__0tx8s8i._.js.map +1 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__03b.f76._.js +1 -1
- package/.next/server/chunks/ssr/[root-of-the-server]__03b.f76._.js.map +1 -1
- package/.next/server/chunks/ssr/[root-of-the-server]__0fhoq8i._.js +1 -1
- package/.next/server/chunks/ssr/[root-of-the-server]__0fhoq8i._.js.map +1 -1
- package/.next/server/chunks/ssr/[root-of-the-server]__0nw~zhp._.js +1 -1
- package/.next/server/chunks/ssr/[root-of-the-server]__0nw~zhp._.js.map +1 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_09kk21a._.js +4 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_09kk21a._.js.map +1 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_app_01jhlxz._.js +1 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_app_01jhlxz._.js.map +1 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_app_057q.ne._.js +1 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_app_057q.ne._.js.map +1 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_app_09d29my._.js +1 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_app_09d29my._.js.map +1 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_app_0_d45-d._.js +1 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_app_0_d45-d._.js.map +1 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_app_0i3759l._.js +1 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_app_0i3759l._.js.map +1 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_app_0xgney8._.js +1 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_app_0xgney8._.js.map +1 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_app_10hjgv4._.js +1 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_app_10hjgv4._.js.map +1 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_app_1153xeb._.js +1 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_app_1153xeb._.js.map +1 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_app_12l4oto._.js +1 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_app_12l4oto._.js.map +1 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_app_components_0mvyi-4._.js +1 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_app_components_0mvyi-4._.js.map +1 -1
- package/.next/server/middleware-build-manifest.js +3 -3
- package/.next/server/pages/404.html +2 -2
- package/.next/server/pages/500.html +1 -1
- package/.next/server/server-reference-manifest.js +1 -1
- package/.next/server/server-reference-manifest.json +1 -1
- package/.next/static/chunks/0-mpa_947ipeq.js +1 -0
- package/.next/static/chunks/01lmbsd37fybu.js +1 -0
- package/.next/static/chunks/03o.h6kvmw4l_.js +1 -0
- package/.next/static/chunks/03~~oirxz7~vc.js +1 -0
- package/.next/static/chunks/050s9ndkk07i9.js +1 -0
- package/.next/static/chunks/05uk96gc~9mni.js +1 -0
- package/.next/static/chunks/08kf-.bgs10ze.js +1 -0
- package/.next/static/chunks/0d7u.7_u.l9sh.js +4 -0
- package/.next/static/chunks/0ggj5ummw2a84.js +7 -0
- package/.next/static/chunks/0glmrdj9112tc.js +7 -0
- package/.next/static/chunks/0gvra4akqlit0.js +1 -0
- package/.next/static/chunks/0otgjhpse~amj.css +2 -0
- package/.next/static/chunks/0rxrez_cjn.eh.js +1 -0
- package/.next/static/chunks/0x8x.29hkju5a.js +1 -0
- package/.next/static/chunks/174re5ar~kxne.js +1 -0
- package/.next/trace +2 -2
- package/.next/trace-build +1 -1
- package/.next/types/routes.d.ts +2 -1
- package/.next/types/validator.ts +9 -0
- package/app/api/hub/servers/route.ts +39 -0
- package/app/components/ChatPopover.tsx +38 -2
- package/app/components/CommandPalette.tsx +107 -0
- package/app/components/HelpOverlay.tsx +126 -0
- package/app/components/ServersDrawer.tsx +64 -27
- package/app/components/TopoGraph.tsx +3338 -241
- package/app/components/utils.ts +8 -7
- package/app/globals.css +75 -5
- package/app/lib/time.ts +36 -0
- package/package.json +1 -1
- package/scripts/help-overlay-topo-test.mjs +44 -0
- package/scripts/servers-drawer-live-test.mjs +96 -0
- package/scripts/topo-active-filter-pill-test.mjs +101 -0
- package/scripts/topo-active-links-chip-hover-test.mjs +103 -0
- package/scripts/topo-active-links-chip-nav-test.mjs +117 -0
- package/scripts/topo-active-links-chip-test.mjs +73 -0
- package/scripts/topo-active-links-freshness-test.mjs +113 -0
- package/scripts/topo-active-links-tooltip-test.mjs +79 -0
- package/scripts/topo-arrival-ping-test.mjs +87 -0
- package/scripts/topo-arrow-tier-test.mjs +61 -0
- package/scripts/topo-auto-fit-test.mjs +73 -0
- package/scripts/topo-canvas-aria-test.mjs +108 -0
- package/scripts/topo-chat-focus-ring-test.mjs +77 -0
- package/scripts/topo-chat-target-breath-test.mjs +84 -0
- package/scripts/topo-chip-focus-test.mjs +95 -0
- package/scripts/topo-chip-pin-mirror-test.mjs +113 -0
- package/scripts/topo-chrome-a11y-test.mjs +107 -0
- package/scripts/topo-click-ripple-test.mjs +66 -0
- package/scripts/topo-cmdk-edge-clear-test.mjs +109 -0
- package/scripts/topo-cmdk-layout-view-test.mjs +108 -0
- package/scripts/topo-cmdk-pin-test.mjs +123 -0
- package/scripts/topo-cmdk-vendor-clear-test.mjs +133 -0
- package/scripts/topo-cmdk-vendor-pin-test.mjs +103 -0
- package/scripts/topo-cwd-tooltip-test.mjs +64 -0
- package/scripts/topo-dblclick-reset-test.mjs +74 -0
- package/scripts/topo-dispatch-pulse-test.mjs +83 -0
- package/scripts/topo-edge-badge-click-pin-test.mjs +94 -0
- package/scripts/topo-edge-badge-hot-test.mjs +115 -0
- package/scripts/topo-edge-badge-hover-test.mjs +85 -0
- package/scripts/topo-edge-count-badge-test.mjs +86 -0
- package/scripts/topo-edge-endpoint-highlight-test.mjs +111 -0
- package/scripts/topo-edge-focus-test.mjs +113 -0
- package/scripts/topo-edge-hover-test.mjs +93 -0
- package/scripts/topo-edge-pill-hot-test.mjs +129 -0
- package/scripts/topo-edge-pill-test.mjs +105 -0
- package/scripts/topo-edge-tooltip-test.mjs +70 -0
- package/scripts/topo-endpoint-ring-test.mjs +93 -0
- package/scripts/topo-esc-clears-pin-test.mjs +98 -0
- package/scripts/topo-filter-pill-aliases-test.mjs +121 -0
- package/scripts/topo-filter-pill-body-click-test.mjs +112 -0
- package/scripts/topo-filter-pill-count-test.mjs +110 -0
- package/scripts/topo-filter-pill-mobile-test.mjs +90 -0
- package/scripts/topo-fit-key-test.mjs +106 -0
- package/scripts/topo-freshness-chip-test.mjs +74 -0
- package/scripts/topo-group-box-pinned-state-test.mjs +95 -0
- package/scripts/topo-group-count-test.mjs +68 -0
- package/scripts/topo-group-hover-test.mjs +82 -0
- package/scripts/topo-group-label-a11y-test.mjs +113 -0
- package/scripts/topo-group-label-hover-test.mjs +119 -0
- package/scripts/topo-group-label-tint-test.mjs +99 -0
- package/scripts/topo-group-label-title-test.mjs +83 -0
- package/scripts/topo-group-pin-test.mjs +119 -0
- package/scripts/topo-group-status-pips-test.mjs +103 -0
- package/scripts/topo-groupbox-hover-lift-test.mjs +127 -0
- package/scripts/topo-groupbox-live-test.mjs +100 -0
- package/scripts/topo-groupbox-march-busyness-test.mjs +155 -0
- package/scripts/topo-groupbox-test.mjs +4 -2
- package/scripts/topo-help-overlay-r109-test.mjs +67 -0
- package/scripts/topo-help-overlay-r118-test.mjs +69 -0
- package/scripts/topo-help-overlay-r123-test.mjs +69 -0
- package/scripts/topo-help-overlay-r134-test.mjs +74 -0
- package/scripts/topo-help-overlay-r137-test.mjs +81 -0
- package/scripts/topo-help-overlay-r141-test.mjs +86 -0
- package/scripts/topo-help-overlay-r153-test.mjs +85 -0
- package/scripts/topo-help-overlay-r59-test.mjs +67 -0
- package/scripts/topo-help-overlay-r65-test.mjs +64 -0
- package/scripts/topo-help-overlay-r70-test.mjs +63 -0
- package/scripts/topo-help-overlay-r78-test.mjs +59 -0
- package/scripts/topo-help-overlay-r81-test.mjs +58 -0
- package/scripts/topo-help-overlay-r87-test.mjs +64 -0
- package/scripts/topo-help-overlay-r91-test.mjs +65 -0
- package/scripts/topo-hub-a11y-test.mjs +112 -0
- package/scripts/topo-hub-busyness-test.mjs +100 -0
- package/scripts/topo-hub-click-fit-test.mjs +137 -0
- package/scripts/topo-hub-hover-ring-test.mjs +82 -0
- package/scripts/topo-hub-title-test.mjs +93 -0
- package/scripts/topo-hub-working-count-test.mjs +99 -0
- package/scripts/topo-ingroup-edge-test.mjs +103 -0
- package/scripts/topo-label-lift-test.mjs +119 -0
- package/scripts/topo-label-scale-test.mjs +78 -0
- package/scripts/topo-lastseen-tooltip-test.mjs +59 -0
- package/scripts/topo-layout-key-test.mjs +91 -0
- package/scripts/topo-layout-toggle-test.mjs +131 -0
- package/scripts/topo-legend-count-test.mjs +88 -0
- package/scripts/topo-legend-hover-test.mjs +113 -0
- package/scripts/topo-legend-panel-header-test.mjs +83 -0
- package/scripts/topo-legend-pin-test.mjs +128 -0
- package/scripts/topo-legend-row-hover-lift-test.mjs +109 -0
- package/scripts/topo-legend-row-tint-test.mjs +95 -0
- package/scripts/topo-legend-row-title-test.mjs +102 -0
- package/scripts/topo-minimap-a11y-test.mjs +101 -0
- package/scripts/topo-minimap-test.mjs +68 -0
- package/scripts/topo-mobile-chips-test.mjs +103 -0
- package/scripts/topo-node-a11y-test.mjs +107 -0
- package/scripts/topo-node-hover-lift-test.mjs +85 -0
- package/scripts/topo-node-title-peers-test.mjs +107 -0
- package/scripts/topo-node-title-test.mjs +101 -0
- package/scripts/topo-offline-dim-test.mjs +70 -0
- package/scripts/topo-online-chip-nav-test.mjs +143 -0
- package/scripts/topo-orbit-busyness-test.mjs +96 -0
- package/scripts/topo-overlap-test.mjs +32 -5
- package/scripts/topo-pan-cursor-test.mjs +62 -0
- package/scripts/topo-panel-elevation-test.mjs +76 -0
- package/scripts/topo-panel-hover-elevation-test.mjs +118 -0
- package/scripts/topo-particle-stagger-test.mjs +82 -0
- package/scripts/topo-pin-intersection-empty-test.mjs +129 -0
- package/scripts/topo-pin-intersection-test.mjs +121 -0
- package/scripts/topo-pin-persistence-test.mjs +105 -0
- package/scripts/topo-popover-meta-test.mjs +78 -0
- package/scripts/topo-pressure-bar-test.mjs +69 -0
- package/scripts/topo-pressure-hover-test.mjs +123 -0
- package/scripts/topo-pressure-pin-test.mjs +119 -0
- package/scripts/topo-pressure-seg-tooltip-test.mjs +98 -0
- package/scripts/topo-pulse-rate-test.mjs +71 -0
- package/scripts/topo-recent-panel-count-freshness-test.mjs +109 -0
- package/scripts/topo-recent-panel-count-test.mjs +72 -0
- package/scripts/topo-recent-panel-hot-header-test.mjs +132 -0
- package/scripts/topo-recent-panel-more-nav-test.mjs +127 -0
- package/scripts/topo-recent-panel-more-test.mjs +106 -0
- package/scripts/topo-recent-row-freshness-test.mjs +102 -0
- package/scripts/topo-recent-row-hot-test.mjs +110 -0
- package/scripts/topo-recent-row-hover-lift-test.mjs +128 -0
- package/scripts/topo-recent-row-hover-test.mjs +122 -0
- package/scripts/topo-recent-row-pin-test.mjs +126 -0
- package/scripts/topo-recent-row-tint-test.mjs +91 -0
- package/scripts/topo-recent-row-title-test.mjs +112 -0
- package/scripts/topo-recent-row-ts-test.mjs +95 -0
- package/scripts/topo-recent-row-typography-test.mjs +119 -0
- package/scripts/topo-recent-signal-empty-hint-test.mjs +73 -0
- package/scripts/topo-recent-signal-empty-test.mjs +63 -0
- package/scripts/topo-reduced-motion-test.mjs +77 -0
- package/scripts/topo-spoke-busyness-test.mjs +110 -0
- package/scripts/topo-status-chip-hover-test.mjs +101 -0
- package/scripts/topo-status-chip-tooltip-test.mjs +95 -0
- package/scripts/topo-svg-focus-test.mjs +112 -0
- package/scripts/topo-sweep-busyness-test.mjs +94 -0
- package/scripts/topo-tier-ring-occupancy-test.mjs +87 -0
- package/scripts/topo-tier-ring-test.mjs +69 -0
- package/scripts/topo-tier-ring-tint-test.mjs +110 -0
- package/scripts/topo-tier-stagger-test.mjs +89 -0
- package/scripts/topo-tz-ghost-test.mjs +69 -0
- package/scripts/topo-vendor-chip-hover-test.mjs +111 -0
- package/scripts/topo-vendor-letter-tooltip-test.mjs +92 -0
- package/scripts/topo-vendor-pill-test.mjs +125 -0
- package/scripts/topo-vendor-pin-test.mjs +125 -0
- package/scripts/topo-wheel-zoom-test.mjs +79 -0
- package/scripts/topo-working-chip-pin-test.mjs +148 -0
- package/scripts/topo-working-halo-breath-test.mjs +86 -0
- package/scripts/topo-zoom-keys-test.mjs +89 -0
- package/.next/static/chunks/0-7iowzu4.798.js +0 -1
- package/.next/static/chunks/02t5jr4shh.hy.js +0 -1
- package/.next/static/chunks/096hkjkwj4hb3.js +0 -1
- package/.next/static/chunks/0_qfg5s5uzs7..js +0 -7
- package/.next/static/chunks/0d6xn54cd2zo-.js +0 -1
- package/.next/static/chunks/0elalb9n_.~di.js +0 -1
- package/.next/static/chunks/0fqy_0wj_1xa7.js +0 -7
- package/.next/static/chunks/0iv2-b3po~sbg.js +0 -1
- package/.next/static/chunks/0j_q__o8p6g83.js +0 -1
- package/.next/static/chunks/0jl6_w50zh4l5.js +0 -1
- package/.next/static/chunks/0r4q73.-1bkyl.js +0 -1
- package/.next/static/chunks/0r_c8eccg3z2o.js +0 -1
- package/.next/static/chunks/10oi7l-tycgl9.js +0 -1
- package/.next/static/chunks/11uk1izuv3~0t.js +0 -1
- package/.next/static/chunks/13vw-ubg-9pjp.css +0 -2
- /package/.next/static/{TBtREVf7o4zYSqGqq3QT5 → m3FtdjT1mdUIOaZp0o9gq}/_buildManifest.js +0 -0
- /package/.next/static/{TBtREVf7o4zYSqGqq3QT5 → m3FtdjT1mdUIOaZp0o9gq}/_clientMiddlewareManifest.js +0 -0
- /package/.next/static/{TBtREVf7o4zYSqGqq3QT5 → m3FtdjT1mdUIOaZp0o9gq}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/* Round 143 verification: recent-signal panel rows lift 1px on
|
|
2
|
+
* hover or pin. Closes the "interactive surface elevates" idiom
|
|
3
|
+
* across four nested canvas-region scopes:
|
|
4
|
+
* R51 node hover-lift (canvas element) → translateY(-2px)
|
|
5
|
+
* R135 overlay panels (canvas chrome) → drop-shadow boost
|
|
6
|
+
* R142 group boxes (canvas-side per-team) → drop-shadow filter
|
|
7
|
+
* R143 recent-signal rows (panel content) → translateY(-1px)
|
|
8
|
+
*
|
|
9
|
+
* Smaller layer = smaller lift (1px row, 2px node, drop-shadow
|
|
10
|
+
* panel/box). Each layer signals interactivity in its own
|
|
11
|
+
* vocabulary.
|
|
12
|
+
*
|
|
13
|
+
* States:
|
|
14
|
+
* 1. Idle row: data-recent-row-lifted="false", no transform
|
|
15
|
+
* 2. Hover row → lifted=true, transform contains translateY(-1px)
|
|
16
|
+
* 3. Leave hover → restored to flat
|
|
17
|
+
* 4. Click to pin → lifted=true (pin keeps the lift)
|
|
18
|
+
* 5. Esc → cleared back to flat
|
|
19
|
+
*/
|
|
20
|
+
import { chromium } from 'playwright';
|
|
21
|
+
import { readFileSync } from 'node:fs';
|
|
22
|
+
|
|
23
|
+
const TOKEN = JSON.parse(readFileSync('/home/vansin/.anet/config.json', 'utf8')).token;
|
|
24
|
+
const browser = await chromium.launch({ headless: true });
|
|
25
|
+
|
|
26
|
+
const ctx = await browser.newContext({ viewport: { width: 1400, height: 1500 } });
|
|
27
|
+
await ctx.addCookies([{ name: 'anet_dashboard_session', value: `v3:${TOKEN}`, domain: '127.0.0.1', path: '/' }]);
|
|
28
|
+
await ctx.addInitScript(() => {
|
|
29
|
+
try { localStorage.setItem('anet-theme', 'cyber'); sessionStorage.setItem('anet_v3_auth', '1'); } catch {}
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
const fresh = new Date(Date.now() - 60 * 1000).toISOString();
|
|
33
|
+
await ctx.route('**/api/hub/status*', async (route) => {
|
|
34
|
+
const r = await route.fetch();
|
|
35
|
+
const b = await r.json();
|
|
36
|
+
const nid = (b.sessions || [])[0]?.network_id || 'default';
|
|
37
|
+
const mk = (alias, status) => ({
|
|
38
|
+
alias, status, model: 'claude-opus-4', runtime: 'cli-claude-code',
|
|
39
|
+
network_id: nid, project_dir: null,
|
|
40
|
+
created_at: fresh, updated_at: fresh, last_seen_at: fresh,
|
|
41
|
+
});
|
|
42
|
+
await route.fulfill({ response: r, json: { ...b, sessions: [
|
|
43
|
+
mk('alpha', 'working'), mk('beta', 'working'), mk('gamma', 'idle'),
|
|
44
|
+
] } });
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
const now = Date.now();
|
|
48
|
+
const msgs = [];
|
|
49
|
+
// 3 distinct pairs → 3 recent-signal rows
|
|
50
|
+
const pairs = [['alpha', 'beta'], ['beta', 'gamma'], ['gamma', 'alpha']];
|
|
51
|
+
pairs.forEach(([from, to], i) => {
|
|
52
|
+
msgs.push({
|
|
53
|
+
id: `m${i}`,
|
|
54
|
+
from_alias: from,
|
|
55
|
+
to_alias: to,
|
|
56
|
+
content: 'hi',
|
|
57
|
+
network_id: 'default',
|
|
58
|
+
created_at: new Date(now - (20000 + i * 1000)).toISOString(),
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
await ctx.route('**/api/hub/messages*', (route) => route.fulfill({ json: { messages: msgs } }));
|
|
62
|
+
await ctx.route('**/api/hub/tasks*', (route) => route.fulfill({ json: { tasks: [] } }));
|
|
63
|
+
|
|
64
|
+
const page = await ctx.newPage();
|
|
65
|
+
await page.goto('http://127.0.0.1:3000/', { waitUntil: 'domcontentloaded' });
|
|
66
|
+
await page.waitForFunction(() => document.querySelectorAll('g[data-node]').length === 3, { timeout: 30000 });
|
|
67
|
+
await page.waitForSelector('[data-recent-row="alpha->beta"]', { timeout: 10000 });
|
|
68
|
+
await page.waitForTimeout(400);
|
|
69
|
+
|
|
70
|
+
const inspect = (key) => page.evaluate((k) => {
|
|
71
|
+
const row = document.querySelector(`[data-recent-row="${k}"]`);
|
|
72
|
+
return {
|
|
73
|
+
lifted: row?.getAttribute('data-recent-row-lifted'),
|
|
74
|
+
hovered: row?.getAttribute('data-recent-row-hovered'),
|
|
75
|
+
pinned: row?.getAttribute('data-recent-row-pinned'),
|
|
76
|
+
transform: row?.getAttribute('style')?.match(/translateY\([^)]+\)/)?.[0],
|
|
77
|
+
};
|
|
78
|
+
}, key);
|
|
79
|
+
|
|
80
|
+
// State 1: idle baseline (no hover, no pin)
|
|
81
|
+
const s1 = await inspect('alpha->beta');
|
|
82
|
+
|
|
83
|
+
// State 2: hover alpha->beta row
|
|
84
|
+
await page.locator('[data-recent-row="alpha->beta"]').hover();
|
|
85
|
+
await page.waitForTimeout(250);
|
|
86
|
+
const s2_hovered = await inspect('alpha->beta');
|
|
87
|
+
const s2_other = await inspect('beta->gamma');
|
|
88
|
+
|
|
89
|
+
// State 3: leave hover (mouse far away to clear all panel hovers)
|
|
90
|
+
await page.mouse.move(700, 350);
|
|
91
|
+
await page.waitForTimeout(250);
|
|
92
|
+
const s3 = await inspect('alpha->beta');
|
|
93
|
+
|
|
94
|
+
// State 4: click row to pin
|
|
95
|
+
await page.locator('[data-recent-row="alpha->beta"]').click();
|
|
96
|
+
await page.waitForTimeout(250);
|
|
97
|
+
// Move mouse away so only pin lifts the row (not hover)
|
|
98
|
+
await page.mouse.move(700, 350);
|
|
99
|
+
await page.waitForTimeout(250);
|
|
100
|
+
const s4 = await inspect('alpha->beta');
|
|
101
|
+
|
|
102
|
+
// State 5: Esc clears pin
|
|
103
|
+
await page.keyboard.press('Escape');
|
|
104
|
+
await page.waitForTimeout(250);
|
|
105
|
+
const s5 = await inspect('alpha->beta');
|
|
106
|
+
|
|
107
|
+
await browser.close();
|
|
108
|
+
|
|
109
|
+
const liftStr = 'translateY(-1px)';
|
|
110
|
+
const results = {
|
|
111
|
+
s1_idleFlat: s1.lifted === 'false' && !s1.transform,
|
|
112
|
+
|
|
113
|
+
s2_hoveredLifted: s2_hovered.hovered === 'true' && s2_hovered.lifted === 'true',
|
|
114
|
+
s2_hoveredTransform: s2_hovered.transform === liftStr,
|
|
115
|
+
s2_otherStillFlat: s2_other.lifted === 'false' && !s2_other.transform,
|
|
116
|
+
|
|
117
|
+
s3_restored: s3.lifted === 'false' && !s3.transform,
|
|
118
|
+
|
|
119
|
+
s4_pinnedLifted: s4.pinned === 'true' && s4.lifted === 'true',
|
|
120
|
+
s4_pinnedTransform: s4.transform === liftStr,
|
|
121
|
+
|
|
122
|
+
s5_clearedAfterEsc: s5.lifted === 'false' && !s5.transform,
|
|
123
|
+
};
|
|
124
|
+
const ok = Object.values(results).every(Boolean);
|
|
125
|
+
console.log(`${ok ? '✅' : '❌'} recent-row hover lift:`, JSON.stringify(results),
|
|
126
|
+
`\n s1=`, s1, `\n s2_hovered=`, s2_hovered, ` s2_other=`, s2_other,
|
|
127
|
+
`\n s3=`, s3, `\n s4=`, s4, `\n s5=`, s5);
|
|
128
|
+
process.exit(ok ? 0 : 1);
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/* Round 56 verification: hovering a recent-signal panel row sets
|
|
2
|
+
* hoveredEdgeKey to that link, which fires the R50 edge-focus +
|
|
3
|
+
* R49 endpoint-highlight ladders against the canvas.
|
|
4
|
+
*
|
|
5
|
+
* Sessions: alpha, beta, gamma, delta, epsilon, zeta (all idle).
|
|
6
|
+
* Messages create three deduped flow links in this order:
|
|
7
|
+
* alpha → beta
|
|
8
|
+
* gamma → delta
|
|
9
|
+
* epsilon → zeta
|
|
10
|
+
* Hover the FIRST recent-signal row (alpha→beta):
|
|
11
|
+
* - alpha→beta visible edge: opacity boosts ≥1.5× baseline (R50)
|
|
12
|
+
* - other edges (γ→δ, ε→ζ): opacity dims < 0.6× baseline
|
|
13
|
+
* - alpha + beta nodes: stay bright (≥0.55) — endpoint highlight (R49)
|
|
14
|
+
* - gamma/delta/epsilon/zeta nodes: dim (<0.4)
|
|
15
|
+
* Release → all restore.
|
|
16
|
+
*/
|
|
17
|
+
import { chromium } from 'playwright';
|
|
18
|
+
import { readFileSync } from 'node:fs';
|
|
19
|
+
|
|
20
|
+
const TOKEN = JSON.parse(readFileSync('/home/vansin/.anet/config.json', 'utf8')).token;
|
|
21
|
+
const browser = await chromium.launch({ headless: true });
|
|
22
|
+
|
|
23
|
+
const ctx = await browser.newContext({ viewport: { width: 1400, height: 1500 } });
|
|
24
|
+
await ctx.addCookies([{ name: 'anet_dashboard_session', value: `v3:${TOKEN}`, domain: '127.0.0.1', path: '/' }]);
|
|
25
|
+
await ctx.addInitScript(() => {
|
|
26
|
+
try {
|
|
27
|
+
localStorage.setItem('anet-theme', 'cyber');
|
|
28
|
+
localStorage.setItem('anet-topo-layout', 'ring');
|
|
29
|
+
sessionStorage.setItem('anet_v3_auth', '1');
|
|
30
|
+
} catch {}
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
const fresh = new Date(Date.now() - 60 * 1000).toISOString();
|
|
34
|
+
await ctx.route('**/api/hub/status*', async (route) => {
|
|
35
|
+
const r = await route.fetch();
|
|
36
|
+
const b = await r.json();
|
|
37
|
+
const nid = (b.sessions || [])[0]?.network_id || 'default';
|
|
38
|
+
const sessions = ['alpha', 'beta', 'gamma', 'delta', 'epsilon', 'zeta'].map(a => ({
|
|
39
|
+
alias: a, status: 'idle', network_id: nid, project_dir: null,
|
|
40
|
+
created_at: fresh, updated_at: fresh, last_seen_at: fresh,
|
|
41
|
+
}));
|
|
42
|
+
await route.fulfill({ response: r, json: { ...b, sessions } });
|
|
43
|
+
});
|
|
44
|
+
const now = new Date().toISOString();
|
|
45
|
+
await ctx.route('**/api/hub/messages*', (route) => route.fulfill({ json: { messages: [
|
|
46
|
+
{ from_alias: 'alpha', to_alias: 'beta', content: 'm', created_at: now },
|
|
47
|
+
{ from_alias: 'gamma', to_alias: 'delta', content: 'm', created_at: now },
|
|
48
|
+
{ from_alias: 'epsilon', to_alias: 'zeta', content: 'm', created_at: now },
|
|
49
|
+
] } }));
|
|
50
|
+
await ctx.route('**/api/hub/tasks*', (route) => route.fulfill({ json: { tasks: [] } }));
|
|
51
|
+
const page = await ctx.newPage();
|
|
52
|
+
await page.goto('http://127.0.0.1:3000/', { waitUntil: 'domcontentloaded' });
|
|
53
|
+
await page.waitForFunction(() => document.querySelectorAll('g[data-node]').length === 6, { timeout: 30000 });
|
|
54
|
+
await page.waitForTimeout(600);
|
|
55
|
+
|
|
56
|
+
const readState = () => page.evaluate(() => {
|
|
57
|
+
const svg = document.querySelector('svg[viewBox="0 0 1000 680"]');
|
|
58
|
+
const edges = {};
|
|
59
|
+
for (const g of svg.querySelectorAll(':scope > g > g')) {
|
|
60
|
+
const t = g.querySelector('path[data-edge-hitbox] title');
|
|
61
|
+
if (!t) continue;
|
|
62
|
+
const route = (t.textContent || '').split('\n')[0];
|
|
63
|
+
const base = [...g.querySelectorAll(':scope > path')].find(
|
|
64
|
+
p => !p.hasAttribute('data-edge-hitbox') && p.hasAttribute('marker-end')
|
|
65
|
+
);
|
|
66
|
+
if (base) edges[route] = +base.getAttribute('opacity');
|
|
67
|
+
}
|
|
68
|
+
const nodes = {};
|
|
69
|
+
for (const a of ['alpha', 'beta', 'gamma', 'delta', 'epsilon', 'zeta']) {
|
|
70
|
+
const n = document.querySelector(`g[data-node="${a}"]`);
|
|
71
|
+
nodes[a] = n ? +(n.style.opacity || '1') : null;
|
|
72
|
+
}
|
|
73
|
+
return { edges, nodes };
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
const before = await readState();
|
|
77
|
+
|
|
78
|
+
// Hover the first recent-signal row — its key is "alpha->beta".
|
|
79
|
+
const rowRect = await page.evaluate(() => {
|
|
80
|
+
const g = document.querySelector('g[data-recent-row="alpha->beta"]');
|
|
81
|
+
if (!g) return null;
|
|
82
|
+
const r = g.getBoundingClientRect();
|
|
83
|
+
return { x: r.x + r.width / 2, y: r.y + r.height / 2 };
|
|
84
|
+
});
|
|
85
|
+
if (!rowRect) { console.log('❌ recent-signal row alpha->beta not found'); process.exit(1); }
|
|
86
|
+
await page.mouse.move(10, 10);
|
|
87
|
+
await page.mouse.move(rowRect.x, rowRect.y);
|
|
88
|
+
await page.waitForTimeout(350);
|
|
89
|
+
const during = await readState();
|
|
90
|
+
|
|
91
|
+
await page.mouse.move(10, 10);
|
|
92
|
+
await page.waitForTimeout(350);
|
|
93
|
+
const after = await readState();
|
|
94
|
+
|
|
95
|
+
await browser.close();
|
|
96
|
+
|
|
97
|
+
const baseEdgeOp = before.edges['alpha → beta'];
|
|
98
|
+
const eAB = during.edges['alpha → beta'];
|
|
99
|
+
const eGD = during.edges['gamma → delta'];
|
|
100
|
+
const eEZ = during.edges['epsilon → zeta'];
|
|
101
|
+
|
|
102
|
+
const bright = (v) => v != null && v >= 0.55;
|
|
103
|
+
const dim = (v) => v != null && v < 0.4;
|
|
104
|
+
const results = {
|
|
105
|
+
baselineEqual: Math.abs(before.edges['alpha → beta'] - before.edges['gamma → delta']) < 0.001
|
|
106
|
+
&& Math.abs(before.edges['alpha → beta'] - before.edges['epsilon → zeta']) < 0.001,
|
|
107
|
+
hoverBrightensTargetEdge: eAB > baseEdgeOp * 1.5,
|
|
108
|
+
hoverDimsOtherEdges: eGD < baseEdgeOp * 0.6 && eEZ < baseEdgeOp * 0.6,
|
|
109
|
+
endpointsStayBright: bright(during.nodes.alpha) && bright(during.nodes.beta),
|
|
110
|
+
nonEndpointsDim: dim(during.nodes.gamma) && dim(during.nodes.delta)
|
|
111
|
+
&& dim(during.nodes.epsilon) && dim(during.nodes.zeta),
|
|
112
|
+
releaseRestoresEdges: Math.abs(after.edges['alpha → beta'] - baseEdgeOp) < 0.05
|
|
113
|
+
&& Math.abs(after.edges['gamma → delta'] - baseEdgeOp) < 0.05,
|
|
114
|
+
releaseRestoresNodes: bright(after.nodes.alpha) && bright(after.nodes.gamma) && bright(after.nodes.epsilon),
|
|
115
|
+
};
|
|
116
|
+
const ok = Object.values(results).every(Boolean);
|
|
117
|
+
console.log(`${ok ? '✅' : '❌'} recent-row hover:`, JSON.stringify(results),
|
|
118
|
+
`\n baseline α→β=${baseEdgeOp}`,
|
|
119
|
+
`\n during α→β=${eAB} γ→δ=${eGD} ε→ζ=${eEZ}`,
|
|
120
|
+
`\n during nodes=`, during.nodes,
|
|
121
|
+
`\n after edges=`, after.edges);
|
|
122
|
+
process.exit(ok ? 0 : 1);
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/* Round 116 verification: recent-signal row click pins the edge.
|
|
2
|
+
* R56 made hover transient; R116 makes click sticky — survives
|
|
3
|
+
* mouseleave, releases on second click or Esc. activeEdgeKey =
|
|
4
|
+
* hoveredEdgeKey ?? pinnedEdgeKey, so hover-while-pinned previews
|
|
5
|
+
* another edge transiently and mouseleave falls back to the pin.
|
|
6
|
+
*
|
|
7
|
+
* Drives 2 flow rows. Click row 0 → row's aria-pressed=true,
|
|
8
|
+
* data-recent-row-pinned=true, the edge stays bright after mouseleave
|
|
9
|
+
* (non-endpoints stay dim, endpoint ring stays). Click row 0 again
|
|
10
|
+
* → release. Pin row 0, hover row 1 → row-1 preview wins; leave →
|
|
11
|
+
* row-0 pin restores. Esc clears.
|
|
12
|
+
*/
|
|
13
|
+
import { chromium } from 'playwright';
|
|
14
|
+
import { readFileSync } from 'node:fs';
|
|
15
|
+
|
|
16
|
+
const TOKEN = JSON.parse(readFileSync('/home/vansin/.anet/config.json', 'utf8')).token;
|
|
17
|
+
const browser = await chromium.launch({ headless: true });
|
|
18
|
+
|
|
19
|
+
const ctx = await browser.newContext({ viewport: { width: 1400, height: 1500 } });
|
|
20
|
+
await ctx.addCookies([{ name: 'anet_dashboard_session', value: `v3:${TOKEN}`, domain: '127.0.0.1', path: '/' }]);
|
|
21
|
+
await ctx.addInitScript(() => {
|
|
22
|
+
try { localStorage.setItem('anet-theme', 'cyber'); sessionStorage.setItem('anet_v3_auth', '1'); } catch {}
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
const fresh = new Date(Date.now() - 60 * 1000).toISOString();
|
|
26
|
+
await ctx.route('**/api/hub/status*', async (route) => {
|
|
27
|
+
const r = await route.fetch();
|
|
28
|
+
const b = await r.json();
|
|
29
|
+
const nid = (b.sessions || [])[0]?.network_id || 'default';
|
|
30
|
+
const mk = (alias) => ({
|
|
31
|
+
alias, status: 'idle', model: 'claude-opus-4', runtime: 'cli-claude-code',
|
|
32
|
+
network_id: nid, project_dir: null,
|
|
33
|
+
created_at: fresh, updated_at: fresh, last_seen_at: fresh,
|
|
34
|
+
});
|
|
35
|
+
await route.fulfill({ response: r, json: { ...b, sessions: [mk('alpha'), mk('beta'), mk('gamma'), mk('delta')] } });
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
const now = Date.now();
|
|
39
|
+
const mkMsg = (id, from_alias, to_alias, ageMs) => ({
|
|
40
|
+
id, from_alias, to_alias, content: 'hi', network_id: 'default',
|
|
41
|
+
created_at: new Date(now - ageMs).toISOString(),
|
|
42
|
+
});
|
|
43
|
+
await ctx.route('**/api/hub/messages*', (route) => route.fulfill({ json: { messages: [
|
|
44
|
+
mkMsg('m1', 'alpha', 'beta', 30 * 1000),
|
|
45
|
+
mkMsg('m2', 'gamma', 'delta', 60 * 1000),
|
|
46
|
+
] } }));
|
|
47
|
+
await ctx.route('**/api/hub/tasks*', (route) => route.fulfill({ json: { tasks: [] } }));
|
|
48
|
+
const page = await ctx.newPage();
|
|
49
|
+
await page.goto('http://127.0.0.1:3000/', { waitUntil: 'domcontentloaded' });
|
|
50
|
+
await page.waitForFunction(() => document.querySelectorAll('g[data-node]').length === 4, { timeout: 30000 });
|
|
51
|
+
await page.waitForSelector('[data-recent-row]', { timeout: 10000 });
|
|
52
|
+
await page.waitForTimeout(400);
|
|
53
|
+
|
|
54
|
+
const rowState = (key) => page.evaluate((k) => {
|
|
55
|
+
const g = document.querySelector(`[data-recent-row="${k}"]`);
|
|
56
|
+
return {
|
|
57
|
+
pinned: g?.getAttribute('data-recent-row-pinned') || '',
|
|
58
|
+
aria: g?.getAttribute('aria-pressed') || '',
|
|
59
|
+
};
|
|
60
|
+
}, key);
|
|
61
|
+
const endpointRingFor = (alias) => page.evaluate((a) => {
|
|
62
|
+
const g = document.querySelector(`g[data-node="${a}"]`);
|
|
63
|
+
return !!g?.querySelector('[data-edge-endpoint-ring]');
|
|
64
|
+
}, alias);
|
|
65
|
+
|
|
66
|
+
const before = await rowState('alpha->beta');
|
|
67
|
+
|
|
68
|
+
// Click row 0 → pin.
|
|
69
|
+
await page.locator('[data-recent-row="alpha->beta"]').click();
|
|
70
|
+
await page.mouse.move(10, 10);
|
|
71
|
+
await page.waitForTimeout(300);
|
|
72
|
+
const afterPin = await rowState('alpha->beta');
|
|
73
|
+
const alphaRingPin = await endpointRingFor('alpha');
|
|
74
|
+
const betaRingPin = await endpointRingFor('beta');
|
|
75
|
+
const gammaRingPin = await endpointRingFor('gamma');
|
|
76
|
+
|
|
77
|
+
// Click again → release.
|
|
78
|
+
await page.locator('[data-recent-row="alpha->beta"]').click();
|
|
79
|
+
await page.mouse.move(10, 10);
|
|
80
|
+
await page.waitForTimeout(300);
|
|
81
|
+
const afterRelease = await rowState('alpha->beta');
|
|
82
|
+
const alphaRingRelease = await endpointRingFor('alpha');
|
|
83
|
+
|
|
84
|
+
// Pin row 0 again, hover row 1 — preview wins.
|
|
85
|
+
await page.locator('[data-recent-row="alpha->beta"]').click();
|
|
86
|
+
await page.mouse.move(10, 10);
|
|
87
|
+
await page.waitForTimeout(200);
|
|
88
|
+
await page.locator('[data-recent-row="gamma->delta"]').hover();
|
|
89
|
+
await page.waitForTimeout(300);
|
|
90
|
+
const alphaWhileHoverGamma = await endpointRingFor('alpha');
|
|
91
|
+
const gammaWhileHover = await endpointRingFor('gamma');
|
|
92
|
+
|
|
93
|
+
// Leave gamma row — row-0 pin restores.
|
|
94
|
+
await page.mouse.move(10, 10);
|
|
95
|
+
await page.waitForTimeout(300);
|
|
96
|
+
const alphaAfterLeave = await endpointRingFor('alpha');
|
|
97
|
+
const gammaAfterLeave = await endpointRingFor('gamma');
|
|
98
|
+
|
|
99
|
+
// Esc clears.
|
|
100
|
+
await page.keyboard.press('Escape');
|
|
101
|
+
await page.waitForTimeout(300);
|
|
102
|
+
const afterEsc = await rowState('alpha->beta');
|
|
103
|
+
const alphaAfterEsc = await endpointRingFor('alpha');
|
|
104
|
+
|
|
105
|
+
await browser.close();
|
|
106
|
+
|
|
107
|
+
const results = {
|
|
108
|
+
before_notPinned: before.pinned === 'false' && before.aria === 'false',
|
|
109
|
+
pin_attrTrue: afterPin.pinned === 'true' && afterPin.aria === 'true',
|
|
110
|
+
pin_endpointsLit: alphaRingPin === true && betaRingPin === true,
|
|
111
|
+
pin_nonEndpointDark: gammaRingPin === false,
|
|
112
|
+
releaseAfterReclick: afterRelease.pinned === 'false' && alphaRingRelease === false,
|
|
113
|
+
hoverPreview_gammaLit: gammaWhileHover === true,
|
|
114
|
+
hoverPreview_alphaDark: alphaWhileHoverGamma === false,
|
|
115
|
+
leave_pinRestored: alphaAfterLeave === true && gammaAfterLeave === false,
|
|
116
|
+
esc_clearsPin: afterEsc.pinned === 'false' && alphaAfterEsc === false,
|
|
117
|
+
};
|
|
118
|
+
const ok = Object.values(results).every(Boolean);
|
|
119
|
+
console.log(`${ok ? '✅' : '❌'} recent-row pin:`, JSON.stringify(results),
|
|
120
|
+
`\n afterPin=`, afterPin,
|
|
121
|
+
`\n rings@pin: alpha=`, alphaRingPin, ' beta=', betaRingPin, ' gamma=', gammaRingPin,
|
|
122
|
+
`\n afterRelease=`, afterRelease,
|
|
123
|
+
`\n hoverPreview: alpha=`, alphaWhileHoverGamma, ' gamma=', gammaWhileHover,
|
|
124
|
+
`\n afterLeave: alpha=`, alphaAfterLeave, ' gamma=', gammaAfterLeave,
|
|
125
|
+
`\n afterEsc=`, afterEsc);
|
|
126
|
+
process.exit(ok ? 0 : 1);
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/* Round 104 verification: recent-signal panel rows get a subtle
|
|
2
|
+
* row-background tint on hover. R56 already brightens the matching
|
|
3
|
+
* edge on the canvas, but the panel row itself stayed flat — the
|
|
4
|
+
* row now has visible feedback at the source surface.
|
|
5
|
+
*
|
|
6
|
+
* Driver: 3 flow rows. Initial state — all hitbox rects are
|
|
7
|
+
* transparent. Hover row 0 — its rect fills with the accent colour
|
|
8
|
+
* at low alpha + data-recent-row-hovered="true"; the other two rows
|
|
9
|
+
* stay transparent + "false". Mouseleave — back to all-false.
|
|
10
|
+
*/
|
|
11
|
+
import { chromium } from 'playwright';
|
|
12
|
+
import { readFileSync } from 'node:fs';
|
|
13
|
+
|
|
14
|
+
const TOKEN = JSON.parse(readFileSync('/home/vansin/.anet/config.json', 'utf8')).token;
|
|
15
|
+
const browser = await chromium.launch({ headless: true });
|
|
16
|
+
|
|
17
|
+
const ctx = await browser.newContext({ viewport: { width: 1400, height: 1500 } });
|
|
18
|
+
await ctx.addCookies([{ name: 'anet_dashboard_session', value: `v3:${TOKEN}`, domain: '127.0.0.1', path: '/' }]);
|
|
19
|
+
await ctx.addInitScript(() => {
|
|
20
|
+
try { localStorage.setItem('anet-theme', 'cyber'); sessionStorage.setItem('anet_v3_auth', '1'); } catch {}
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
const fresh = new Date(Date.now() - 60 * 1000).toISOString();
|
|
24
|
+
await ctx.route('**/api/hub/status*', async (route) => {
|
|
25
|
+
const r = await route.fetch();
|
|
26
|
+
const b = await r.json();
|
|
27
|
+
const nid = (b.sessions || [])[0]?.network_id || 'default';
|
|
28
|
+
const mk = (alias) => ({
|
|
29
|
+
alias, status: 'idle', model: 'claude-opus-4', runtime: 'cli-claude-code',
|
|
30
|
+
network_id: nid, project_dir: null,
|
|
31
|
+
created_at: fresh, updated_at: fresh, last_seen_at: fresh,
|
|
32
|
+
});
|
|
33
|
+
await route.fulfill({ response: r, json: { ...b, sessions: [mk('alpha'), mk('beta'), mk('gamma'), mk('delta')] } });
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
const now = Date.now();
|
|
37
|
+
const mkMsg = (id, from_alias, to_alias, ageMs) => ({
|
|
38
|
+
id, from_alias, to_alias, content: 'hi', network_id: 'default',
|
|
39
|
+
created_at: new Date(now - ageMs).toISOString(),
|
|
40
|
+
});
|
|
41
|
+
await ctx.route('**/api/hub/messages*', (route) => route.fulfill({ json: { messages: [
|
|
42
|
+
mkMsg('m1', 'alpha', 'beta', 20 * 1000),
|
|
43
|
+
mkMsg('m2', 'gamma', 'delta', 30 * 1000),
|
|
44
|
+
mkMsg('m3', 'alpha', 'gamma', 40 * 1000),
|
|
45
|
+
] } }));
|
|
46
|
+
await ctx.route('**/api/hub/tasks*', (route) => route.fulfill({ json: { tasks: [] } }));
|
|
47
|
+
const page = await ctx.newPage();
|
|
48
|
+
await page.goto('http://127.0.0.1:3000/', { waitUntil: 'domcontentloaded' });
|
|
49
|
+
await page.waitForFunction(() => document.querySelectorAll('g[data-node]').length === 4, { timeout: 30000 });
|
|
50
|
+
await page.waitForSelector('[data-recent-row]', { timeout: 10000 });
|
|
51
|
+
await page.waitForTimeout(400);
|
|
52
|
+
|
|
53
|
+
const readRows = () => page.evaluate(() => {
|
|
54
|
+
return [...document.querySelectorAll('[data-recent-row]')].map(g => {
|
|
55
|
+
const rect = g.querySelector('rect');
|
|
56
|
+
return {
|
|
57
|
+
key: g.getAttribute('data-recent-row'),
|
|
58
|
+
hovered: g.getAttribute('data-recent-row-hovered'),
|
|
59
|
+
rectFill: rect?.getAttribute('fill') || '',
|
|
60
|
+
rectOpac: rect?.getAttribute('opacity') || '',
|
|
61
|
+
};
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
const before = await readRows();
|
|
66
|
+
|
|
67
|
+
// Hover the first row.
|
|
68
|
+
await page.locator('[data-recent-row]').first().hover();
|
|
69
|
+
await page.waitForTimeout(250);
|
|
70
|
+
const duringHover = await readRows();
|
|
71
|
+
|
|
72
|
+
// Move pointer away.
|
|
73
|
+
await page.mouse.move(10, 10);
|
|
74
|
+
await page.waitForTimeout(250);
|
|
75
|
+
const afterLeave = await readRows();
|
|
76
|
+
|
|
77
|
+
await browser.close();
|
|
78
|
+
|
|
79
|
+
const results = {
|
|
80
|
+
before_allTransparent: before.every(r => r.rectFill === 'transparent' && r.hovered === 'false'),
|
|
81
|
+
hover_firstRowTinted: duringHover[0]?.hovered === 'true' && duringHover[0]?.rectFill !== 'transparent',
|
|
82
|
+
hover_otherRowsUnchanged: duringHover.slice(1).every(r => r.hovered === 'false' && r.rectFill === 'transparent'),
|
|
83
|
+
hover_opacityVisibleButLow: duringHover[0] && parseFloat(duringHover[0].rectOpac) > 0 && parseFloat(duringHover[0].rectOpac) < 0.3,
|
|
84
|
+
leave_restored: afterLeave.every(r => r.rectFill === 'transparent' && r.hovered === 'false'),
|
|
85
|
+
};
|
|
86
|
+
const ok = Object.values(results).every(Boolean);
|
|
87
|
+
console.log(`${ok ? '✅' : '❌'} recent-row tint:`, JSON.stringify(results),
|
|
88
|
+
`\n before=`, before,
|
|
89
|
+
`\n duringHover=`, duringHover,
|
|
90
|
+
`\n afterLeave=`, afterLeave);
|
|
91
|
+
process.exit(ok ? 0 : 1);
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/* Round 148 verification: recent-signal row gains a <title> tooltip
|
|
2
|
+
* exposing full message context — the row text truncates aliases to
|
|
3
|
+
* 6 chars (R127) and content to 8, useful for scan-density but
|
|
4
|
+
* obscures detail. Native SVG <title> reveals the full alias /
|
|
5
|
+
* content / timestamp on hover. Pinned vs unpinned switches the
|
|
6
|
+
* click-hint so the user knows the next gesture's effect.
|
|
7
|
+
*
|
|
8
|
+
* Mirrors R98's enriched node tooltip at the per-row scope.
|
|
9
|
+
*
|
|
10
|
+
* Fleet: alpha sends 12 msgs to beta-with-long-name (HOT), and
|
|
11
|
+
* beta-with-long-name sends 4 msgs to gamma (warm). Content is
|
|
12
|
+
* a long string to verify untruncated display.
|
|
13
|
+
*
|
|
14
|
+
* States tested:
|
|
15
|
+
* - hot row: title contains full from / to / msg count + "hot lane"
|
|
16
|
+
* marker + full content + ISO timestamp + pin hint
|
|
17
|
+
* - warm row: same shape minus the "hot lane" marker
|
|
18
|
+
* - pinned: click-hint flips to "click to release pin"
|
|
19
|
+
*/
|
|
20
|
+
import { chromium } from 'playwright';
|
|
21
|
+
import { readFileSync } from 'node:fs';
|
|
22
|
+
|
|
23
|
+
const TOKEN = JSON.parse(readFileSync('/home/vansin/.anet/config.json', 'utf8')).token;
|
|
24
|
+
const browser = await chromium.launch({ headless: true });
|
|
25
|
+
|
|
26
|
+
const ctx = await browser.newContext({ viewport: { width: 1400, height: 1500 } });
|
|
27
|
+
await ctx.addCookies([{ name: 'anet_dashboard_session', value: `v3:${TOKEN}`, domain: '127.0.0.1', path: '/' }]);
|
|
28
|
+
await ctx.addInitScript(() => {
|
|
29
|
+
try { localStorage.setItem('anet-theme', 'cyber'); sessionStorage.setItem('anet_v3_auth', '1'); } catch {}
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
// Aliases longer than the row truncation cap (6) so the title's
|
|
33
|
+
// untruncated form is meaningfully different from what's painted.
|
|
34
|
+
const aliasA = 'alpha-runner';
|
|
35
|
+
const aliasB = 'beta-with-long-name';
|
|
36
|
+
const aliasC = 'gamma';
|
|
37
|
+
const longContent = 'this is the full long message body that the row truncates';
|
|
38
|
+
|
|
39
|
+
const fresh = new Date(Date.now() - 60 * 1000).toISOString();
|
|
40
|
+
await ctx.route('**/api/hub/status*', async (route) => {
|
|
41
|
+
const r = await route.fetch();
|
|
42
|
+
const b = await r.json();
|
|
43
|
+
const nid = (b.sessions || [])[0]?.network_id || 'default';
|
|
44
|
+
const mk = (alias, status) => ({
|
|
45
|
+
alias, status, model: 'claude-opus-4', runtime: 'cli-claude-code',
|
|
46
|
+
network_id: nid, project_dir: null,
|
|
47
|
+
created_at: fresh, updated_at: fresh, last_seen_at: fresh,
|
|
48
|
+
});
|
|
49
|
+
await route.fulfill({ response: r, json: { ...b, sessions: [
|
|
50
|
+
mk(aliasA, 'working'), mk(aliasB, 'working'), mk(aliasC, 'idle'),
|
|
51
|
+
] } });
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
const now = Date.now();
|
|
55
|
+
const mkMsg = (id, from, to, ageMs) => ({
|
|
56
|
+
id, from_alias: from, to_alias: to, content: longContent,
|
|
57
|
+
network_id: 'default', created_at: new Date(now - ageMs).toISOString(),
|
|
58
|
+
});
|
|
59
|
+
const msgs = [];
|
|
60
|
+
// 12 alpha→beta = HOT
|
|
61
|
+
for (let i = 0; i < 12; i++) msgs.push(mkMsg(`a${i}`, aliasA, aliasB, 20000 + i * 500));
|
|
62
|
+
// 4 beta→gamma = warm
|
|
63
|
+
for (let i = 0; i < 4; i++) msgs.push(mkMsg(`b${i}`, aliasB, aliasC, 30000 + i * 500));
|
|
64
|
+
await ctx.route('**/api/hub/messages*', (route) => route.fulfill({ json: { messages: msgs } }));
|
|
65
|
+
await ctx.route('**/api/hub/tasks*', (route) => route.fulfill({ json: { tasks: [] } }));
|
|
66
|
+
|
|
67
|
+
const page = await ctx.newPage();
|
|
68
|
+
await page.goto('http://127.0.0.1:3000/', { waitUntil: 'domcontentloaded' });
|
|
69
|
+
await page.waitForFunction(() => document.querySelectorAll('g[data-node]').length === 3, { timeout: 30000 });
|
|
70
|
+
await page.waitForSelector(`[data-recent-row="${aliasA}->${aliasB}"]`, { timeout: 10000 });
|
|
71
|
+
await page.waitForTimeout(400);
|
|
72
|
+
|
|
73
|
+
const readTitle = (key) => page.evaluate((k) => {
|
|
74
|
+
const row = document.querySelector(`[data-recent-row="${k}"]`);
|
|
75
|
+
return row?.querySelector('title')?.textContent || '';
|
|
76
|
+
}, key);
|
|
77
|
+
|
|
78
|
+
const hotTitle = await readTitle(`${aliasA}->${aliasB}`);
|
|
79
|
+
const warmTitle = await readTitle(`${aliasB}->${aliasC}`);
|
|
80
|
+
|
|
81
|
+
// Pin the hot row → title's click-hint flips
|
|
82
|
+
await page.locator(`[data-recent-row="${aliasA}->${aliasB}"]`).click();
|
|
83
|
+
await page.waitForTimeout(200);
|
|
84
|
+
const pinnedTitle = await readTitle(`${aliasA}->${aliasB}`);
|
|
85
|
+
|
|
86
|
+
await browser.close();
|
|
87
|
+
|
|
88
|
+
const results = {
|
|
89
|
+
// Hot row
|
|
90
|
+
hot_hasFullFrom: hotTitle.includes(aliasA),
|
|
91
|
+
hot_hasFullTo: hotTitle.includes(aliasB),
|
|
92
|
+
hot_hasCount12: hotTitle.includes('12 msgs'),
|
|
93
|
+
hot_hasHotMarker: hotTitle.includes('hot lane'),
|
|
94
|
+
hot_hasFullContent: hotTitle.includes(longContent),
|
|
95
|
+
hot_hasTimestamp: /last: \d/.test(hotTitle),
|
|
96
|
+
hot_pinHint: hotTitle.includes('click to pin'),
|
|
97
|
+
|
|
98
|
+
// Warm row
|
|
99
|
+
warm_hasCount4: warmTitle.includes('4 msgs'),
|
|
100
|
+
warm_noHotMarker: !warmTitle.includes('hot lane'),
|
|
101
|
+
warm_pinHint: warmTitle.includes('click to pin'),
|
|
102
|
+
|
|
103
|
+
// Pinned row's title flips hint
|
|
104
|
+
pinned_releaseHint: pinnedTitle.includes('click to release pin'),
|
|
105
|
+
pinned_noPinHint: !pinnedTitle.includes('click to pin · hover to preview'),
|
|
106
|
+
};
|
|
107
|
+
const ok = Object.values(results).every(Boolean);
|
|
108
|
+
console.log(`${ok ? '✅' : '❌'} recent-row title:`, JSON.stringify(results),
|
|
109
|
+
`\n hotTitle:\n${hotTitle}`,
|
|
110
|
+
`\n warmTitle:\n${warmTitle}`,
|
|
111
|
+
`\n pinnedTitle:\n${pinnedTitle}`);
|
|
112
|
+
process.exit(ok ? 0 : 1);
|