@sleep2agi/agent-network-dashboard 0.4.6 → 0.5.0
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 +2 -0
- package/.next/build-manifest.json +3 -3
- package/.next/diagnostics/route-bundle-stats.json +31 -31
- package/.next/fallback-build-manifest.json +3 -3
- package/.next/prerender-manifest.json +3 -3
- package/.next/routes-manifest.json +16 -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/server/[hostname]/agents/route/app-paths-manifest.json +3 -0
- package/.next/server/app/api/hub/server/[hostname]/agents/route/build-manifest.json +9 -0
- package/.next/server/app/api/hub/server/[hostname]/agents/route/server-reference-manifest.json +4 -0
- package/.next/server/app/api/hub/server/[hostname]/agents/route.js +7 -0
- package/.next/server/app/api/hub/server/[hostname]/agents/route.js.map +5 -0
- package/.next/server/app/api/hub/server/[hostname]/agents/route.js.nft.json +1 -0
- package/.next/server/app/api/hub/server/[hostname]/agents/route_client-reference-manifest.js +3 -0
- package/.next/server/app/api/hub/server/[hostname]/health/route/app-paths-manifest.json +3 -0
- package/.next/server/app/api/hub/server/[hostname]/health/route/build-manifest.json +9 -0
- package/.next/server/app/api/hub/server/[hostname]/health/route/server-reference-manifest.json +4 -0
- package/.next/server/app/api/hub/server/[hostname]/health/route.js +7 -0
- package/.next/server/app/api/hub/server/[hostname]/health/route.js.map +5 -0
- package/.next/server/app/api/hub/server/[hostname]/health/route.js.nft.json +1 -0
- package/.next/server/app/api/hub/server/[hostname]/health/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 +2 -0
- package/.next/server/chunks/0dk5_next-internal_server_app_api_hub_server_[hostname]_agents_route_actions_0vr92s4.js +3 -0
- package/.next/server/chunks/0dk5_next-internal_server_app_api_hub_server_[hostname]_agents_route_actions_0vr92s4.js.map +1 -0
- package/.next/server/chunks/0dk5_next-internal_server_app_api_hub_server_[hostname]_health_route_actions_0vr-bv5.js +3 -0
- package/.next/server/chunks/0dk5_next-internal_server_app_api_hub_server_[hostname]_health_route_actions_0vr-bv5.js.map +1 -0
- package/.next/server/chunks/[root-of-the-server]__05nyivw._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__05nyivw._.js.map +1 -0
- package/.next/server/chunks/[root-of-the-server]__0floe3h._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__0floe3h._.js.map +1 -0
- package/.next/server/chunks/[root-of-the-server]__0tx8s8i._.js +1 -1
- package/.next/server/chunks/[root-of-the-server]__0tx8s8i._.js.map +1 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_09kk21a._.js +4 -2
- 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_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_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/0aauz~36q5n2a.css +2 -0
- package/.next/static/chunks/0f~0kgy2pycyc.js +1 -0
- package/.next/static/chunks/0l_~q07bhpkcx.js +7 -0
- package/.next/static/chunks/1175-dp18a1e_.js +1 -0
- package/.next/static/chunks/1552j0415oeal.js +4 -0
- package/.next/trace +2 -2
- package/.next/trace-build +1 -1
- package/.next/types/routes.d.ts +3 -1
- package/.next/types/validator.ts +18 -0
- package/app/api/hub/server/[hostname]/agents/route.ts +62 -0
- package/app/api/hub/server/[hostname]/health/route.ts +58 -0
- package/app/api/hub/servers/route.ts +88 -1
- package/app/components/CommandPalette.tsx +107 -0
- package/app/components/HelpOverlay.tsx +109 -1
- package/app/components/ServersDrawer.tsx +181 -5
- package/app/components/TopoGraph.tsx +6409 -286
- package/app/globals.css +110 -5
- package/app/lib/vendorIdentity.ts +14 -3
- package/docs/rfc/v0.10.0-hero3-dashboard-upgrade.md +230 -0
- package/package.json +2 -2
- package/public/sleep2agi-logo.svg +11 -0
- package/public/vendors/claude.svg +11 -0
- package/public/vendors/minimax.svg +11 -0
- package/public/vendors/openai.svg +12 -0
- package/screenshots/r293-p0/after-full.png +0 -0
- package/screenshots/r293-p0/after-topo.png +0 -0
- package/screenshots/r293-p0/baseline-full.png +0 -0
- package/screenshots/r293-p0/baseline-topo.png +0 -0
- package/screenshots/r293-p0/logo-integrated-full.png +0 -0
- package/screenshots/r293-p0/logo-integrated-topo.png +0 -0
- package/screenshots/r293-p0/servers-drawer-v0.10.0-full.png +0 -0
- package/screenshots/r293-p0/servers-drawer-v0.10.0.png +0 -0
- package/screenshots/r293-p0/wave1-after-full.png +0 -0
- package/screenshots/r293-p0/wave1-after-topo.png +0 -0
- package/scripts/p0-servers-drawer-screenshot.mjs +99 -0
- package/scripts/p0-topo-screenshot.mjs +82 -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-self-hover-test.mjs +171 -0
- package/scripts/topo-active-links-empty-recede-test.mjs +125 -0
- package/scripts/topo-active-links-freshness-test.mjs +113 -0
- package/scripts/topo-active-links-tooltip-test.mjs +79 -0
- package/scripts/topo-active-pulse-ease-test.mjs +120 -0
- package/scripts/topo-brand-logo-transition-test.mjs +94 -0
- package/scripts/topo-brand-watermark-test.mjs +97 -0
- package/scripts/topo-canvas-aria-test.mjs +108 -0
- package/scripts/topo-canvas-brand-fade-test.mjs +87 -0
- package/scripts/topo-chat-target-breath-test.mjs +84 -0
- package/scripts/topo-chat-target-ring-ease-test.mjs +82 -0
- package/scripts/topo-chat-target-ring-fade-test.mjs +124 -0
- package/scripts/topo-chip-empty-recede-test.mjs +116 -0
- package/scripts/topo-chip-focus-test.mjs +95 -0
- package/scripts/topo-chip-pin-mirror-test.mjs +113 -0
- package/scripts/topo-chip-row-gap-test.mjs +90 -0
- package/scripts/topo-chip-row-semantic-gap-test.mjs +97 -0
- package/scripts/topo-chip-row-tabular-test.mjs +111 -0
- package/scripts/topo-chip-unit-demotion-test.mjs +93 -0
- package/scripts/topo-chiprow-data-weight-test.mjs +94 -0
- package/scripts/topo-chrome-a11y-test.mjs +107 -0
- package/scripts/topo-chrome-active-weight-test.mjs +104 -0
- package/scripts/topo-chrome-focus-ring-unify-test.mjs +100 -0
- package/scripts/topo-chrome-gap-test.mjs +73 -0
- package/scripts/topo-chrome-icon-stroke-test.mjs +95 -0
- package/scripts/topo-chrome-inactive-color-test.mjs +90 -0
- package/scripts/topo-chrome-pop-extension-test.mjs +98 -0
- package/scripts/topo-chrome-pop-nodesize-test.mjs +88 -0
- package/scripts/topo-chrome-press-state-test.mjs +135 -0
- package/scripts/topo-chrome-strip-semantic-gap-test.mjs +99 -0
- package/scripts/topo-chrome-strip-theme-ease-test.mjs +99 -0
- package/scripts/topo-chrome-zoom-level-pop-test.mjs +122 -0
- package/scripts/topo-chrome-zoom-pop-test.mjs +130 -0
- package/scripts/topo-chrome-zoom-readout-weight-test.mjs +81 -0
- package/scripts/topo-click-ripple-ease-test.mjs +94 -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-corner-radius-unify-test.mjs +103 -0
- package/scripts/topo-dense-alias-fill-transition-test.mjs +133 -0
- package/scripts/topo-discrete-zoom-smooth-test.mjs +125 -0
- package/scripts/topo-edge-badge-click-pin-test.mjs +94 -0
- package/scripts/topo-edge-badge-crossfade-test.mjs +138 -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-badge-lift-test.mjs +150 -0
- package/scripts/topo-edge-badge-ripple-test.mjs +111 -0
- package/scripts/topo-edge-badge-stroke-transition-test.mjs +118 -0
- package/scripts/topo-edge-badge-text-pin-test.mjs +121 -0
- package/scripts/topo-edge-badge-theme-ease-test.mjs +89 -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-fadein-test.mjs +106 -0
- package/scripts/topo-edge-focus-test.mjs +113 -0
- package/scripts/topo-edge-hover-test.mjs +13 -5
- package/scripts/topo-edge-pill-hot-test.mjs +129 -0
- package/scripts/topo-edge-pill-test.mjs +105 -0
- package/scripts/topo-edge-ping-pulse-retired-test.mjs +119 -0
- package/scripts/topo-edge-stroke-ease-test.mjs +100 -0
- package/scripts/topo-edge-stroke-transition-test.mjs +132 -0
- package/scripts/topo-empty-hint-tracking-test.mjs +84 -0
- package/scripts/topo-empty-state-breath-test.mjs +150 -0
- package/scripts/topo-empty-state-crossfade-test.mjs +130 -0
- package/scripts/topo-empty-state-recenter-test.mjs +107 -0
- package/scripts/topo-empty-subhint-tracking-test.mjs +87 -0
- package/scripts/topo-endpoint-ring-fade-test.mjs +132 -0
- package/scripts/topo-endpoint-ring-test.mjs +93 -0
- package/scripts/topo-endpoint-ring-thicken-test.mjs +112 -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-tabular-test.mjs +135 -0
- package/scripts/topo-filter-pill-count-test.mjs +110 -0
- package/scripts/topo-filter-pill-mobile-test.mjs +90 -0
- package/scripts/topo-freshness-chip-transition-test.mjs +80 -0
- package/scripts/topo-freshness-chip-weight-test.mjs +90 -0
- package/scripts/topo-freshness-conditional-render-test.mjs +92 -0
- package/scripts/topo-fullscreen-active-test.mjs +115 -0
- package/scripts/topo-group-box-pinned-state-test.mjs +95 -0
- package/scripts/topo-group-count-test.mjs +6 -1
- package/scripts/topo-group-label-a11y-test.mjs +113 -0
- package/scripts/topo-group-label-count-inherit-test.mjs +99 -0
- package/scripts/topo-group-label-hover-test.mjs +119 -0
- package/scripts/topo-group-label-pin-spacing-test.mjs +136 -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-pip-fadein-test.mjs +104 -0
- package/scripts/topo-group-pip-singletier-drop-test.mjs +131 -0
- package/scripts/topo-group-pip-tabular-test.mjs +95 -0
- package/scripts/topo-group-status-pips-test.mjs +103 -0
- package/scripts/topo-groupbox-fadein-test.mjs +95 -0
- package/scripts/topo-groupbox-hover-lift-test.mjs +127 -0
- package/scripts/topo-groupbox-hubcore-ease-test.mjs +106 -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-header-gap-test.mjs +94 -0
- 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-hot-tail-crossfade-test.mjs +117 -0
- package/scripts/topo-html-overlay-padding-unify-test.mjs +120 -0
- package/scripts/topo-hub-a11y-test.mjs +112 -0
- package/scripts/topo-hub-busyness-test.mjs +100 -0
- package/scripts/topo-hub-center-crossfade-test.mjs +124 -0
- package/scripts/topo-hub-click-fit-test.mjs +137 -0
- package/scripts/topo-hub-digit-scale-test.mjs +129 -0
- package/scripts/topo-hub-fadein-test.mjs +88 -0
- package/scripts/topo-hub-hover-lift-test.mjs +101 -0
- package/scripts/topo-hub-hover-ring-test.mjs +82 -0
- package/scripts/topo-hub-pip-theme-ease-test.mjs +116 -0
- package/scripts/topo-hub-spoke-ease-test.mjs +120 -0
- package/scripts/topo-hub-title-test.mjs +7 -2
- package/scripts/topo-hub-working-count-test.mjs +99 -0
- package/scripts/topo-ingroup-edge-test.mjs +103 -0
- package/scripts/topo-inner-radar-ring-retired-test.mjs +89 -0
- package/scripts/topo-kicker-color-test.mjs +93 -0
- package/scripts/topo-kicker-tracking-test.mjs +101 -0
- package/scripts/topo-kicker-weight-test.mjs +98 -0
- package/scripts/topo-label-card-theme-ease-test.mjs +85 -0
- package/scripts/topo-label-lift-test.mjs +5 -1
- package/scripts/topo-layout-hover-text-preview-test.mjs +101 -0
- package/scripts/topo-layout-switch-crossfade-test.mjs +126 -0
- package/scripts/topo-layout-toggle-border-unify-test.mjs +104 -0
- package/scripts/topo-layout-toggle-test.mjs +131 -0
- package/scripts/topo-layout-trailer-mr-test.mjs +82 -0
- package/scripts/topo-legend-compress-test.mjs +107 -0
- package/scripts/topo-legend-count-empty-test.mjs +126 -0
- package/scripts/topo-legend-count-tabular-parity-test.mjs +90 -0
- package/scripts/topo-legend-count-tabular-test.mjs +87 -0
- package/scripts/topo-legend-count-test.mjs +88 -0
- package/scripts/topo-legend-count-tier-fill-test.mjs +121 -0
- package/scripts/topo-legend-count-weight-test.mjs +86 -0
- package/scripts/topo-legend-header-symmetric-inset-test.mjs +112 -0
- package/scripts/topo-legend-hitbox-swatch-center-test.mjs +93 -0
- package/scripts/topo-legend-hover-test.mjs +113 -0
- package/scripts/topo-legend-offline-delimiter-test.mjs +84 -0
- package/scripts/topo-legend-offline-label-simplify-test.mjs +86 -0
- package/scripts/topo-legend-panel-count-weight-test.mjs +89 -0
- package/scripts/topo-legend-panel-header-test.mjs +83 -0
- package/scripts/topo-legend-pin-ring-fade-test.mjs +112 -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-labels-simplify-test.mjs +80 -0
- package/scripts/topo-legend-row-pin-spacing-test.mjs +124 -0
- package/scripts/topo-legend-row-tint-test.mjs +95 -0
- package/scripts/topo-legend-row-title-test.mjs +102 -0
- package/scripts/topo-legend-swatch-grow-test.mjs +116 -0
- package/scripts/topo-legend-swatch-radius-test.mjs +78 -0
- package/scripts/topo-minimap-a11y-test.mjs +101 -0
- package/scripts/topo-minimap-dot-transition-test.mjs +113 -0
- package/scripts/topo-minimap-radius-test.mjs +88 -0
- package/scripts/topo-minimap-rect-stroke-test.mjs +94 -0
- package/scripts/topo-minimap-viewport-smooth-test.mjs +124 -0
- package/scripts/topo-monogram-font-test.mjs +112 -0
- package/scripts/topo-monogram-stroke-test.mjs +101 -0
- package/scripts/topo-more-flows-letterspacing-test.mjs +111 -0
- package/scripts/topo-node-a11y-test.mjs +107 -0
- package/scripts/topo-node-alias-chat-pin-test.mjs +95 -0
- package/scripts/topo-node-hover-lift-test.mjs +85 -0
- package/scripts/topo-node-label-card-elevation-test.mjs +157 -0
- package/scripts/topo-node-label-card-stroke-test.mjs +135 -0
- package/scripts/topo-node-stroke-transition-test.mjs +103 -0
- package/scripts/topo-node-text-fill-transition-test.mjs +119 -0
- package/scripts/topo-node-title-peers-test.mjs +107 -0
- package/scripts/topo-node-title-test.mjs +101 -0
- package/scripts/topo-nodesize-active-hover-test.mjs +109 -0
- package/scripts/topo-nodesize-crossfade-test.mjs +141 -0
- package/scripts/topo-online-chip-nav-test.mjs +143 -0
- package/scripts/topo-orbit-particles-retired-test.mjs +91 -0
- package/scripts/topo-panel-count-unit-test.mjs +112 -0
- package/scripts/topo-panel-elevation-test.mjs +76 -0
- package/scripts/topo-panel-fadein-test.mjs +102 -0
- package/scripts/topo-panel-hot-tail-fade-test.mjs +132 -0
- package/scripts/topo-panel-hover-elevation-test.mjs +118 -0
- package/scripts/topo-panel-rx-test.mjs +90 -0
- package/scripts/topo-panel-theme-ease-test.mjs +85 -0
- package/scripts/topo-panel-title-fill-ease-test.mjs +91 -0
- package/scripts/topo-panel-title-tracking-test.mjs +78 -0
- package/scripts/topo-particle-stagger-test.mjs +82 -0
- package/scripts/topo-pin-intersection-color-ease-test.mjs +111 -0
- package/scripts/topo-pin-intersection-empty-test.mjs +129 -0
- package/scripts/topo-pin-intersection-tabular-test.mjs +96 -0
- package/scripts/topo-pin-intersection-test.mjs +121 -0
- package/scripts/topo-pin-intersection-warning-crossfade-test.mjs +107 -0
- package/scripts/topo-pin-mirror-transition-test.mjs +101 -0
- package/scripts/topo-pin-persistence-test.mjs +105 -0
- package/scripts/topo-prefix-opacity-test.mjs +107 -0
- package/scripts/topo-prepublish-guard-test.mjs +95 -0
- package/scripts/topo-pressure-hover-test.mjs +123 -0
- package/scripts/topo-pressure-pin-test.mjs +119 -0
- package/scripts/topo-pressure-seg-self-hover-test.mjs +126 -0
- package/scripts/topo-pressure-seg-tooltip-test.mjs +98 -0
- package/scripts/topo-pressure-seg-transition-test.mjs +107 -0
- package/scripts/topo-pulse-dot-crossfade-test.mjs +122 -0
- package/scripts/topo-pulse-dot-retired-test.mjs +86 -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-count-weight-test.mjs +91 -0
- package/scripts/topo-recent-panel-footer-breath-test.mjs +142 -0
- package/scripts/topo-recent-panel-hot-header-test.mjs +132 -0
- package/scripts/topo-recent-panel-hot-tabular-test.mjs +113 -0
- package/scripts/topo-recent-panel-more-crossfade-test.mjs +124 -0
- package/scripts/topo-recent-panel-more-cyan-hover-test.mjs +151 -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-panel-readability-bump-test.mjs +151 -0
- package/scripts/topo-recent-row-count-fill-test.mjs +129 -0
- package/scripts/topo-recent-row-count-weight-test.mjs +112 -0
- package/scripts/topo-recent-row-fadein-test.mjs +107 -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-spacing-test.mjs +137 -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-alpha-test.mjs +100 -0
- package/scripts/topo-recent-row-ts-tabular-test.mjs +108 -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-reset-spin-test.mjs +120 -0
- package/scripts/topo-runtime-badge-grow-test.mjs +114 -0
- package/scripts/topo-spokes-retired-test.mjs +93 -0
- package/scripts/topo-starfield-density-test.mjs +89 -0
- package/scripts/topo-status-chip-hover-test.mjs +101 -0
- package/scripts/topo-status-chip-tooltip-test.mjs +95 -0
- package/scripts/topo-statusbar-chips-self-hover-test.mjs +177 -0
- package/scripts/topo-svg-focus-test.mjs +112 -0
- package/scripts/topo-sweep-busyness-test.mjs +94 -0
- package/scripts/topo-tabular-nums-sweep-test.mjs +93 -0
- package/scripts/topo-tier-guide-dashes-test.mjs +86 -0
- package/scripts/topo-tier-ring-fadein-test.mjs +107 -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-title-block-tight-leading-test.mjs +95 -0
- package/scripts/topo-title-tracking-test.mjs +98 -0
- package/scripts/topo-titleblock-gap-test.mjs +86 -0
- package/scripts/topo-titleblock-margin-test.mjs +83 -0
- package/scripts/topo-toggle-inactive-cyan-hover-test.mjs +110 -0
- package/scripts/topo-top-rail-theme-ease-test.mjs +89 -0
- package/scripts/topo-vendor-chip-hover-test.mjs +111 -0
- package/scripts/topo-vendor-chip-self-hover-test.mjs +131 -0
- package/scripts/topo-vendor-chip-tabular-test.mjs +92 -0
- package/scripts/topo-vendor-chip-threshold-test.mjs +78 -0
- package/scripts/topo-vendor-chip-weight-test.mjs +87 -0
- package/scripts/topo-vendor-count-suffix-test.mjs +95 -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-view-smooth-test.mjs +131 -0
- package/scripts/topo-watermark-tracking-test.mjs +99 -0
- package/scripts/topo-working-chip-pin-test.mjs +154 -0
- package/scripts/topo-working-halo-breath-retired-test.mjs +99 -0
- package/scripts/topo-wrapper-flow-arrow-theme-test.mjs +97 -0
- package/scripts/topo-wrapper-radius-test.mjs +73 -0
- package/scripts/topo-wrapper-shadow-theme-ease-test.mjs +89 -0
- package/.next/static/chunks/088ouqy7tekty.js +0 -2
- package/.next/static/chunks/0hyl7mdapsz38.js +0 -1
- package/.next/static/chunks/0mqwn-l7wtcdo.js +0 -7
- package/.next/static/chunks/127kw7~wsnyu7.css +0 -2
- package/.next/static/chunks/16yfxp9ak2gdm.js +0 -1
- /package/.next/static/{23MxP0RBVA4BaOJ_HMYmM → 424zX3i80AJ_wHF_otKuP}/_buildManifest.js +0 -0
- /package/.next/static/{23MxP0RBVA4BaOJ_HMYmM → 424zX3i80AJ_wHF_otKuP}/_clientMiddlewareManifest.js +0 -0
- /package/.next/static/{23MxP0RBVA4BaOJ_HMYmM → 424zX3i80AJ_wHF_otKuP}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
/* Round 190 verification: R129 hot-tail tspan in recent-signal
|
|
2
|
+
* panel header gets anet-fade-in for smooth entrance.
|
|
3
|
+
*
|
|
4
|
+
* Pre-R190 the tspan mounted/unmounted on hotFlowCount > 0 —
|
|
5
|
+
* snap. R190 keeps the conditional render (so the tspan
|
|
6
|
+
* doesn't consume layout when no hot flows) but adds the R3
|
|
7
|
+
* .anet-fade-in CSS animation that plays once on mount.
|
|
8
|
+
*
|
|
9
|
+
* Test scenarios:
|
|
10
|
+
* A. 0 hot flows (just a few cold ones):
|
|
11
|
+
* [data-recent-panel-hot-count] NOT present
|
|
12
|
+
* B. 1 hot flow (count=12):
|
|
13
|
+
* tspan present with text '· 1 hot', className contains
|
|
14
|
+
* 'anet-fade-in', data-recent-panel-hot-count='1'
|
|
15
|
+
* C. 2 hot flows (count=15 + count=20):
|
|
16
|
+
* data-recent-panel-hot-count='2', text '· 2 hot'
|
|
17
|
+
*/
|
|
18
|
+
import { chromium } from 'playwright';
|
|
19
|
+
import { readFileSync } from 'node:fs';
|
|
20
|
+
|
|
21
|
+
const TOKEN = JSON.parse(readFileSync('/home/vansin/.anet/config.json', 'utf8')).token;
|
|
22
|
+
const browser = await chromium.launch({ headless: true });
|
|
23
|
+
|
|
24
|
+
const ctx = await browser.newContext({ viewport: { width: 1500, height: 1500 } });
|
|
25
|
+
await ctx.addCookies([{ name: 'anet_dashboard_session', value: `v3:${TOKEN}`, domain: '127.0.0.1', path: '/' }]);
|
|
26
|
+
await ctx.addInitScript(() => {
|
|
27
|
+
try { localStorage.setItem('anet-theme', 'cyber'); sessionStorage.setItem('anet_v3_auth', '1'); } catch {}
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
async function run(scenario) {
|
|
31
|
+
const fresh = new Date(Date.now() - 60 * 1000).toISOString();
|
|
32
|
+
await ctx.unroute('**/api/hub/status*').catch(() => {});
|
|
33
|
+
await ctx.unroute('**/api/hub/messages*').catch(() => {});
|
|
34
|
+
await ctx.unroute('**/api/hub/tasks*').catch(() => {});
|
|
35
|
+
await ctx.route('**/api/hub/status*', async (route) => {
|
|
36
|
+
const r = await route.fetch();
|
|
37
|
+
const b = await r.json();
|
|
38
|
+
const nid = (b.sessions || [])[0]?.network_id || 'default';
|
|
39
|
+
const mk = (alias) => ({
|
|
40
|
+
alias, status: 'working', model: 'claude-opus-4', runtime: 'cli-claude-code',
|
|
41
|
+
network_id: nid, project_dir: null,
|
|
42
|
+
created_at: fresh, updated_at: fresh, last_seen_at: fresh,
|
|
43
|
+
});
|
|
44
|
+
await route.fulfill({ response: r, json: { ...b, sessions: [
|
|
45
|
+
mk('alpha'), mk('beta'), mk('gamma'), mk('delta'),
|
|
46
|
+
] } });
|
|
47
|
+
});
|
|
48
|
+
const now = Date.now();
|
|
49
|
+
const msgs = scenario(now);
|
|
50
|
+
await ctx.route('**/api/hub/messages*', (route) => route.fulfill({ json: { messages: msgs } }));
|
|
51
|
+
await ctx.route('**/api/hub/tasks*', (route) => route.fulfill({ json: { tasks: [] } }));
|
|
52
|
+
|
|
53
|
+
const page = await ctx.newPage();
|
|
54
|
+
await page.goto('http://127.0.0.1:3000/', { waitUntil: 'domcontentloaded' });
|
|
55
|
+
await page.waitForFunction(() => document.querySelectorAll('g[data-node]').length === 4, { timeout: 30000 });
|
|
56
|
+
await page.waitForSelector('[data-recent-panel-count]', { timeout: 10000 });
|
|
57
|
+
await page.waitForTimeout(400);
|
|
58
|
+
|
|
59
|
+
const out = await page.evaluate(() => {
|
|
60
|
+
const tail = document.querySelector('[data-recent-panel-hot-count]');
|
|
61
|
+
return {
|
|
62
|
+
tailPresent: !!tail,
|
|
63
|
+
tailText: tail?.textContent || null,
|
|
64
|
+
tailCount: tail?.getAttribute('data-recent-panel-hot-count'),
|
|
65
|
+
tailClassName: tail?.getAttribute('class') || '',
|
|
66
|
+
// R223 added: visibility attribute for always-mount-with-opacity-
|
|
67
|
+
// gate. "no tail" is either tailPresent=false (legacy conditional
|
|
68
|
+
// mount, no longer current) OR tailVisible='false' (R223 always-
|
|
69
|
+
// mount with opacity 0).
|
|
70
|
+
tailVisible: tail?.getAttribute('data-recent-panel-hot-visible'),
|
|
71
|
+
};
|
|
72
|
+
});
|
|
73
|
+
await page.close();
|
|
74
|
+
return out;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Scenario A: 0 hot — 1 cold flow
|
|
78
|
+
const a = await run((now) => {
|
|
79
|
+
const m = [];
|
|
80
|
+
for (let i = 0; i < 4; i++) {
|
|
81
|
+
m.push({ id: `cold${i}`, from_alias: 'alpha', to_alias: 'beta', content: 'hi',
|
|
82
|
+
network_id: 'default', created_at: new Date(now - (1000 + i * 50)).toISOString() });
|
|
83
|
+
}
|
|
84
|
+
return m;
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
// Scenario B: 1 hot flow alpha→beta count=12
|
|
88
|
+
const b = await run((now) => {
|
|
89
|
+
const m = [];
|
|
90
|
+
for (let i = 0; i < 12; i++) {
|
|
91
|
+
m.push({ id: `hot${i}`, from_alias: 'alpha', to_alias: 'beta', content: 'hi',
|
|
92
|
+
network_id: 'default', created_at: new Date(now - (1000 + i * 50)).toISOString() });
|
|
93
|
+
}
|
|
94
|
+
return m;
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
// Scenario C: 2 hot flows
|
|
98
|
+
const c = await run((now) => {
|
|
99
|
+
const m = [];
|
|
100
|
+
for (let i = 0; i < 15; i++) {
|
|
101
|
+
m.push({ id: `h1-${i}`, from_alias: 'alpha', to_alias: 'beta', content: 'hi',
|
|
102
|
+
network_id: 'default', created_at: new Date(now - (5000 + i * 50)).toISOString() });
|
|
103
|
+
}
|
|
104
|
+
for (let i = 0; i < 20; i++) {
|
|
105
|
+
m.push({ id: `h2-${i}`, from_alias: 'gamma', to_alias: 'delta', content: 'hi',
|
|
106
|
+
network_id: 'default', created_at: new Date(now - (15000 + i * 50)).toISOString() });
|
|
107
|
+
}
|
|
108
|
+
return m;
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
await browser.close();
|
|
112
|
+
|
|
113
|
+
const results = {
|
|
114
|
+
// R223 update: hot-tail is always-mounted now with opacity-gate;
|
|
115
|
+
// "no tail" means either not in DOM (legacy) OR present-but-hidden
|
|
116
|
+
// (always-mount visible='false'). Accept both forms.
|
|
117
|
+
a_no_tail: a.tailPresent === false || a.tailVisible === 'false',
|
|
118
|
+
b_tail_present: b.tailPresent === true,
|
|
119
|
+
b_tail_text: /·\s*1\s*hot/.test(b.tailText || ''),
|
|
120
|
+
b_tail_count_1: b.tailCount === '1',
|
|
121
|
+
b_has_fade_class: b.tailClassName.includes('anet-fade-in'),
|
|
122
|
+
c_tail_present: c.tailPresent === true,
|
|
123
|
+
c_tail_text: /·\s*2\s*hot/.test(c.tailText || ''),
|
|
124
|
+
c_tail_count_2: c.tailCount === '2',
|
|
125
|
+
c_has_fade_class: c.tailClassName.includes('anet-fade-in'),
|
|
126
|
+
};
|
|
127
|
+
const ok = Object.values(results).every(Boolean);
|
|
128
|
+
console.log(`${ok ? '✅' : '❌'} panel hot-tail fade:`, JSON.stringify(results),
|
|
129
|
+
`\n A (0 hot):`, a,
|
|
130
|
+
`\n B (1 hot):`, b,
|
|
131
|
+
`\n C (2 hot):`, c);
|
|
132
|
+
process.exit(ok ? 0 : 1);
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/* Round 135 verification: both overlay panels (recent-signal +
|
|
2
|
+
* legend) drop-shadow boosts on mouseenter, restores on leave.
|
|
3
|
+
* Mirrors R18's KPI-card hover-elevation from the Overview page.
|
|
4
|
+
*
|
|
5
|
+
* Why both panels: each panel chrome already hosts interactive
|
|
6
|
+
* rows (R56/R116 recent rows, R55/R61 legend rows) and footer
|
|
7
|
+
* nav (R133). Hover-lift signals "this whole panel is alive"
|
|
8
|
+
* without misleading users that the panel itself is clickable —
|
|
9
|
+
* the underlying click affordances are still the rows + footer.
|
|
10
|
+
*
|
|
11
|
+
* State transitions tested:
|
|
12
|
+
* 1. Neither panel hovered → both data-topo-panel-hovered="false",
|
|
13
|
+
* both rect filters = baseline (2px/6px blur)
|
|
14
|
+
* 2. Hover recent → that panel hovered=true, filter boosted
|
|
15
|
+
* (4px/12px blur); legend still baseline
|
|
16
|
+
* 3. Leave recent (move far away) → recent restored
|
|
17
|
+
* 4. Hover legend → legend hovered=true, filter boosted
|
|
18
|
+
* 5. Leave legend → legend restored
|
|
19
|
+
*
|
|
20
|
+
* Filter inline-string detection: the boosted variant carries the
|
|
21
|
+
* `4px 12px` magic numbers in its drop-shadow argument.
|
|
22
|
+
*/
|
|
23
|
+
import { chromium } from 'playwright';
|
|
24
|
+
import { readFileSync } from 'node:fs';
|
|
25
|
+
|
|
26
|
+
const TOKEN = JSON.parse(readFileSync('/home/vansin/.anet/config.json', 'utf8')).token;
|
|
27
|
+
const browser = await chromium.launch({ headless: true });
|
|
28
|
+
|
|
29
|
+
const ctx = await browser.newContext({ viewport: { width: 1400, height: 1500 } });
|
|
30
|
+
await ctx.addCookies([{ name: 'anet_dashboard_session', value: `v3:${TOKEN}`, domain: '127.0.0.1', path: '/' }]);
|
|
31
|
+
await ctx.addInitScript(() => {
|
|
32
|
+
try { localStorage.setItem('anet-theme', 'cyber'); sessionStorage.setItem('anet_v3_auth', '1'); } catch {}
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
const fresh = new Date(Date.now() - 60 * 1000).toISOString();
|
|
36
|
+
await ctx.route('**/api/hub/status*', async (route) => {
|
|
37
|
+
const r = await route.fetch();
|
|
38
|
+
const b = await r.json();
|
|
39
|
+
const nid = (b.sessions || [])[0]?.network_id || 'default';
|
|
40
|
+
const mk = (alias, status) => ({
|
|
41
|
+
alias, status, model: 'claude-opus-4', runtime: 'cli-claude-code',
|
|
42
|
+
network_id: nid, project_dir: null,
|
|
43
|
+
created_at: fresh, updated_at: fresh, last_seen_at: fresh,
|
|
44
|
+
});
|
|
45
|
+
await route.fulfill({ response: r, json: { ...b, sessions: [
|
|
46
|
+
mk('alpha', 'working'), mk('beta', 'idle'), mk('gamma', 'working'),
|
|
47
|
+
] } });
|
|
48
|
+
});
|
|
49
|
+
await ctx.route('**/api/hub/messages*', (route) => route.fulfill({ json: { messages: [] } }));
|
|
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 === 3, { timeout: 30000 });
|
|
54
|
+
await page.waitForSelector('[data-topo-panel="recent"]', { timeout: 10000 });
|
|
55
|
+
await page.waitForTimeout(400);
|
|
56
|
+
|
|
57
|
+
const inspect = () => page.evaluate(() => {
|
|
58
|
+
const get = (key) => {
|
|
59
|
+
const g = document.querySelector(`[data-topo-panel="${key}"]`);
|
|
60
|
+
const rect = g?.querySelector('rect[data-topo-panel-elevation]');
|
|
61
|
+
return {
|
|
62
|
+
hovered: g?.getAttribute('data-topo-panel-hovered'),
|
|
63
|
+
filter: (rect?.getAttribute('style') || ''),
|
|
64
|
+
};
|
|
65
|
+
};
|
|
66
|
+
return { recent: get('recent'), legend: get('legend') };
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
// State 1 — neither hovered
|
|
70
|
+
const s1 = await inspect();
|
|
71
|
+
|
|
72
|
+
// State 2 — hover recent
|
|
73
|
+
await page.locator('[data-topo-panel="recent"]').hover();
|
|
74
|
+
await page.waitForTimeout(300);
|
|
75
|
+
const s2 = await inspect();
|
|
76
|
+
|
|
77
|
+
// State 3 — leave recent (move far away from both panels)
|
|
78
|
+
await page.mouse.move(700, 350);
|
|
79
|
+
await page.waitForTimeout(300);
|
|
80
|
+
const s3 = await inspect();
|
|
81
|
+
|
|
82
|
+
// State 4 — hover legend
|
|
83
|
+
await page.locator('[data-topo-panel="legend"]').hover();
|
|
84
|
+
await page.waitForTimeout(300);
|
|
85
|
+
const s4 = await inspect();
|
|
86
|
+
|
|
87
|
+
// State 5 — leave legend
|
|
88
|
+
await page.mouse.move(500, 350);
|
|
89
|
+
await page.waitForTimeout(300);
|
|
90
|
+
const s5 = await inspect();
|
|
91
|
+
|
|
92
|
+
await browser.close();
|
|
93
|
+
|
|
94
|
+
const isBoosted = (style) => /4px\s+12px/.test(style);
|
|
95
|
+
const isBase = (style) => /2px\s+6px/.test(style) && !/4px\s+12px/.test(style);
|
|
96
|
+
|
|
97
|
+
const results = {
|
|
98
|
+
s1_recent_notHovered: s1.recent.hovered === 'false',
|
|
99
|
+
s1_legend_notHovered: s1.legend.hovered === 'false',
|
|
100
|
+
s1_recent_baseShadow: isBase(s1.recent.filter),
|
|
101
|
+
s1_legend_baseShadow: isBase(s1.legend.filter),
|
|
102
|
+
|
|
103
|
+
s2_recent_hovered: s2.recent.hovered === 'true',
|
|
104
|
+
s2_recent_boosted: isBoosted(s2.recent.filter),
|
|
105
|
+
s2_legend_stillBase: s2.legend.hovered === 'false' && isBase(s2.legend.filter),
|
|
106
|
+
|
|
107
|
+
s3_recent_restored: s3.recent.hovered === 'false' && isBase(s3.recent.filter),
|
|
108
|
+
|
|
109
|
+
s4_legend_hovered: s4.legend.hovered === 'true',
|
|
110
|
+
s4_legend_boosted: isBoosted(s4.legend.filter),
|
|
111
|
+
s4_recent_stillBase: s4.recent.hovered === 'false' && isBase(s4.recent.filter),
|
|
112
|
+
|
|
113
|
+
s5_legend_restored: s5.legend.hovered === 'false' && isBase(s5.legend.filter),
|
|
114
|
+
};
|
|
115
|
+
const ok = Object.values(results).every(Boolean);
|
|
116
|
+
console.log(`${ok ? '✅' : '❌'} panel hover elevation:`, JSON.stringify(results),
|
|
117
|
+
`\n s1=`, s1, `\n s2=`, s2, `\n s3=`, s3, `\n s4=`, s4, `\n s5=`, s5);
|
|
118
|
+
process.exit(ok ? 0 : 1);
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/* Round 331 verification: SVG panel rects (recent-signal + legend)
|
|
2
|
+
* rx 8 → 10 for proportional corner-radius rhythm under R330's
|
|
3
|
+
* rounded-xl (12 px) canvas wrapper.
|
|
4
|
+
*
|
|
5
|
+
* Size-hierarchy gradient now:
|
|
6
|
+
* outer wrapper rounded-xl 12 px (R330)
|
|
7
|
+
* inner SVG panels rx=10 10 px (R331, this round)
|
|
8
|
+
* inner detail card rx=8 8 px (codex 8f981a9)
|
|
9
|
+
* node label card rx=6 6 px (legacy R63)
|
|
10
|
+
*
|
|
11
|
+
* Contract:
|
|
12
|
+
* - Both [data-topo-panel="recent"] and [data-topo-panel="legend"]
|
|
13
|
+
* have a child <rect> with rx="10".
|
|
14
|
+
* - R330 wrapper still rounded-xl (12px).
|
|
15
|
+
* - R317 / R318 / R294 chrome + pulse regressions intact.
|
|
16
|
+
* - topo-overlap-test ZERO OVERLAP separately verified (rx changes
|
|
17
|
+
* paint only, not bbox).
|
|
18
|
+
*/
|
|
19
|
+
import { chromium } from 'playwright';
|
|
20
|
+
import { readFileSync } from 'node:fs';
|
|
21
|
+
|
|
22
|
+
const TOKEN = JSON.parse(readFileSync('/home/vansin/.anet/config.json', 'utf8')).token;
|
|
23
|
+
const browser = await chromium.launch({ headless: true });
|
|
24
|
+
const ctx = await browser.newContext({ viewport: { width: 1500, height: 1500 } });
|
|
25
|
+
await ctx.addCookies([{ name: 'anet_dashboard_session', value: `v3:${TOKEN}`, domain: '127.0.0.1', path: '/' }]);
|
|
26
|
+
await ctx.addInitScript(() => {
|
|
27
|
+
try { localStorage.setItem('anet-theme', 'cyber'); sessionStorage.setItem('anet_v3_auth', '1'); } catch {}
|
|
28
|
+
});
|
|
29
|
+
const fresh = new Date(Date.now() - 60 * 1000).toISOString();
|
|
30
|
+
await ctx.route('**/api/hub/status*', async (route) => {
|
|
31
|
+
const r = await route.fetch();
|
|
32
|
+
const b = await r.json();
|
|
33
|
+
const nid = (b.sessions || [])[0]?.network_id || 'default';
|
|
34
|
+
const mk = (alias) => ({
|
|
35
|
+
alias, status: 'working', model: 'claude-opus-4', runtime: 'claude-code-cli',
|
|
36
|
+
network_id: nid, project_dir: null,
|
|
37
|
+
created_at: fresh, updated_at: fresh, last_seen_at: fresh,
|
|
38
|
+
});
|
|
39
|
+
await route.fulfill({ response: r, json: { ...b, sessions: [ mk('alpha'), mk('beta') ] } });
|
|
40
|
+
});
|
|
41
|
+
// Recent panel renders only when flowLinks > 0 (codex R310/§3.C
|
|
42
|
+
// hide-when-empty). Provide a single flow so it mounts.
|
|
43
|
+
const now = Date.now();
|
|
44
|
+
await ctx.route('**/api/hub/messages*', (r) => r.fulfill({ json: { messages: [
|
|
45
|
+
{ id: 'm1', from_alias: 'alpha', to_alias: 'beta', content: 'ping',
|
|
46
|
+
network_id: 'default', created_at: new Date(now - 5000).toISOString() },
|
|
47
|
+
] } }));
|
|
48
|
+
await ctx.route('**/api/hub/tasks*', (r) => r.fulfill({ json: { tasks: [] } }));
|
|
49
|
+
|
|
50
|
+
const page = await ctx.newPage();
|
|
51
|
+
await page.goto('http://127.0.0.1:3000/', { waitUntil: 'domcontentloaded' });
|
|
52
|
+
await page.waitForSelector('[data-topo-panel="recent"]', { timeout: 15000 });
|
|
53
|
+
await page.waitForSelector('[data-topo-panel="legend"]', { timeout: 15000 });
|
|
54
|
+
await page.waitForTimeout(300);
|
|
55
|
+
|
|
56
|
+
const probe = await page.evaluate(() => {
|
|
57
|
+
const recent = document.querySelector('[data-topo-panel="recent"]');
|
|
58
|
+
const legend = document.querySelector('[data-topo-panel="legend"]');
|
|
59
|
+
const recentRect = recent?.querySelector('rect');
|
|
60
|
+
const legendRect = legend?.querySelector('rect');
|
|
61
|
+
const wrapper = document.querySelector('[data-topo-wrapper]');
|
|
62
|
+
return {
|
|
63
|
+
recentRx: recentRect?.getAttribute('rx') ?? null,
|
|
64
|
+
legendRx: legendRect?.getAttribute('rx') ?? null,
|
|
65
|
+
wrapperClass: wrapper?.className ?? '',
|
|
66
|
+
wrapperRadius: wrapper ? getComputedStyle(wrapper).borderTopLeftRadius : null,
|
|
67
|
+
layoutInactiveCls: document.querySelector('[data-topo-chrome-layout="grid"]')?.className ?? '',
|
|
68
|
+
layoutActiveCls: document.querySelector('[data-topo-chrome-layout="ring"]')?.className ?? '',
|
|
69
|
+
pulseCount: document.querySelectorAll('[data-pulse-wrapper]').length,
|
|
70
|
+
};
|
|
71
|
+
});
|
|
72
|
+
await browser.close();
|
|
73
|
+
|
|
74
|
+
const results = {
|
|
75
|
+
recent_panel_rx_10: probe.recentRx === '10',
|
|
76
|
+
legend_panel_rx_10: probe.legendRx === '10',
|
|
77
|
+
// R330 regression — wrapper still rounded-xl.
|
|
78
|
+
r330_wrapper_rounded_xl: probe.wrapperClass.includes('rounded-xl'),
|
|
79
|
+
r330_wrapper_radius_12px: probe.wrapperRadius === '12px',
|
|
80
|
+
// R317 / R318 chrome regression.
|
|
81
|
+
r317_inactive_gray_400: probe.layoutInactiveCls.includes('text-gray-400'),
|
|
82
|
+
r318_active_font_medium: probe.layoutActiveCls.includes('font-medium'),
|
|
83
|
+
r294_pulse_absent: probe.pulseCount === 0,
|
|
84
|
+
};
|
|
85
|
+
const ok = Object.values(results).every(Boolean);
|
|
86
|
+
console.log(`${ok ? '✅' : '❌'} panel rx 10:`, JSON.stringify(results),
|
|
87
|
+
'\n recent rx:', probe.recentRx,
|
|
88
|
+
'\n legend rx:', probe.legendRx,
|
|
89
|
+
'\n wrapper radius:', probe.wrapperRadius);
|
|
90
|
+
process.exit(ok ? 0 : 1);
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/* Round 247 verification: recent-signal + legend panel chrome
|
|
2
|
+
* <rect>s pick up fill + stroke + opacity in their transition
|
|
3
|
+
* lists, completing the per-panel theme-toggle smoothing.
|
|
4
|
+
*
|
|
5
|
+
* Pre-R247 each panel rect transition was 'filter 200ms ease-out'
|
|
6
|
+
* (R135 hover-elevation drop-shadow). Three theme-driven properties
|
|
7
|
+
* snapped on theme toggle:
|
|
8
|
+
* - fill: pal.legendBox.fill (cyber #020617 ↔ light #ffffff)
|
|
9
|
+
* - stroke: pal.legendBox.stroke (cyber #1f2937 ↔ light #e2e8f0)
|
|
10
|
+
* - opacity: 0.92 cyber ↔ 0.97 light
|
|
11
|
+
*
|
|
12
|
+
* R247 adds all three to the transition list at 200ms ease-out.
|
|
13
|
+
* Mirrors R246's per-node label-card treatment at the panel scope.
|
|
14
|
+
*
|
|
15
|
+
* Test scope per panel:
|
|
16
|
+
* - element present at [data-topo-panel-elevation]
|
|
17
|
+
* - style.transition contains filter, fill, stroke, AND opacity
|
|
18
|
+
* each at 200ms (or 0.2s browser-normalised)
|
|
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
|
+
const ctx = await browser.newContext({ viewport: { width: 1500, height: 1500 } });
|
|
26
|
+
await ctx.addCookies([{ name: 'anet_dashboard_session', value: `v3:${TOKEN}`, domain: '127.0.0.1', path: '/' }]);
|
|
27
|
+
await ctx.addInitScript(() => {
|
|
28
|
+
try { localStorage.setItem('anet-theme', 'cyber'); sessionStorage.setItem('anet_v3_auth', '1'); } catch {}
|
|
29
|
+
});
|
|
30
|
+
const fresh = new Date(Date.now() - 60 * 1000).toISOString();
|
|
31
|
+
await ctx.route('**/api/hub/status*', async (route) => {
|
|
32
|
+
const r = await route.fetch();
|
|
33
|
+
const b = await r.json();
|
|
34
|
+
const nid = (b.sessions || [])[0]?.network_id || 'default';
|
|
35
|
+
const mk = (alias) => ({
|
|
36
|
+
alias, status: 'working', model: 'claude-opus-4', runtime: 'claude-code-cli',
|
|
37
|
+
network_id: nid, project_dir: null,
|
|
38
|
+
created_at: fresh, updated_at: fresh, last_seen_at: fresh,
|
|
39
|
+
});
|
|
40
|
+
await route.fulfill({ response: r, json: { ...b, sessions: [
|
|
41
|
+
mk('alpha'), mk('beta'), mk('gamma'), mk('delta'),
|
|
42
|
+
] } });
|
|
43
|
+
});
|
|
44
|
+
await ctx.route('**/api/hub/messages*', (r2) => r2.fulfill({ json: { messages: [] } }));
|
|
45
|
+
await ctx.route('**/api/hub/tasks*', (r2) => r2.fulfill({ json: { tasks: [] } }));
|
|
46
|
+
|
|
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-topo-panel-elevation="recent"]', { timeout: 10000, state: 'attached' });
|
|
51
|
+
await page.waitForSelector('[data-topo-panel-elevation="legend"]', { timeout: 10000, state: 'attached' });
|
|
52
|
+
await page.waitForTimeout(300);
|
|
53
|
+
|
|
54
|
+
const probe = await page.evaluate(() => {
|
|
55
|
+
const grab = (panel) => {
|
|
56
|
+
const r = document.querySelector(`[data-topo-panel-elevation="${panel}"]`);
|
|
57
|
+
if (!r) return null;
|
|
58
|
+
return { transition: r.style.transition };
|
|
59
|
+
};
|
|
60
|
+
return {
|
|
61
|
+
recent: grab('recent'),
|
|
62
|
+
legend: grab('legend'),
|
|
63
|
+
};
|
|
64
|
+
});
|
|
65
|
+
await browser.close();
|
|
66
|
+
|
|
67
|
+
const hasProp = (s, prop) => new RegExp(`${prop}\\s+(?:200ms|0\\.2s)`).test(s || '');
|
|
68
|
+
|
|
69
|
+
const results = {
|
|
70
|
+
recent_present: probe.recent !== null,
|
|
71
|
+
recent_has_filter_200: hasProp(probe.recent?.transition, 'filter'),
|
|
72
|
+
recent_has_fill_200: hasProp(probe.recent?.transition, 'fill'),
|
|
73
|
+
recent_has_stroke_200: hasProp(probe.recent?.transition, 'stroke'),
|
|
74
|
+
recent_has_opacity_200: hasProp(probe.recent?.transition, 'opacity'),
|
|
75
|
+
legend_present: probe.legend !== null,
|
|
76
|
+
legend_has_filter_200: hasProp(probe.legend?.transition, 'filter'),
|
|
77
|
+
legend_has_fill_200: hasProp(probe.legend?.transition, 'fill'),
|
|
78
|
+
legend_has_stroke_200: hasProp(probe.legend?.transition, 'stroke'),
|
|
79
|
+
legend_has_opacity_200: hasProp(probe.legend?.transition, 'opacity'),
|
|
80
|
+
};
|
|
81
|
+
const ok = Object.values(results).every(Boolean);
|
|
82
|
+
console.log(`${ok ? '✅' : '❌'} panel theme ease:`, JSON.stringify(results),
|
|
83
|
+
'\n recent:', probe.recent,
|
|
84
|
+
'\n legend:', probe.legend);
|
|
85
|
+
process.exit(ok ? 0 : 1);
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/* Round 266 verification: corner panel titles + legend count text
|
|
2
|
+
* pick up theme-toggle fill transitions.
|
|
3
|
+
*
|
|
4
|
+
* Pre-R266 three texts in the corner panel headers snapped fill on
|
|
5
|
+
* theme toggle:
|
|
6
|
+
* "recent signal" fill=pal.legendHeadline (cyber #e5e7eb ↔ light #0f172a)
|
|
7
|
+
* "legend" fill=pal.legendHeadline (same)
|
|
8
|
+
* "{N} nodes" fill=pal.legendAccent (cyber #67e8f9 ↔ light #10b981)
|
|
9
|
+
*
|
|
10
|
+
* The panel rect chrome eased (R247), the rows eased (various), but
|
|
11
|
+
* the BIGGEST text in each panel header hard-flipped color on theme
|
|
12
|
+
* toggle. R266 adds `transition: fill 200ms ease-out` to all three.
|
|
13
|
+
*
|
|
14
|
+
* Test scope:
|
|
15
|
+
* 1. Recent-signal title element present at [data-recent-panel-title].
|
|
16
|
+
* 2. Legend title element present at [data-legend-panel-title].
|
|
17
|
+
* 3. Legend count element present at [data-legend-panel-count].
|
|
18
|
+
* 4. Each inline transition contains `fill 200ms` (or 0.2s).
|
|
19
|
+
* 5. R265 top-rail still has its background-image transition (regression).
|
|
20
|
+
*/
|
|
21
|
+
import { chromium } from 'playwright';
|
|
22
|
+
import { readFileSync } from 'node:fs';
|
|
23
|
+
|
|
24
|
+
const TOKEN = JSON.parse(readFileSync('/home/vansin/.anet/config.json', 'utf8')).token;
|
|
25
|
+
const browser = await chromium.launch({ headless: true });
|
|
26
|
+
const ctx = await browser.newContext({ viewport: { width: 1500, 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
|
+
const fresh = new Date(Date.now() - 60 * 1000).toISOString();
|
|
32
|
+
await ctx.route('**/api/hub/status*', async (route) => {
|
|
33
|
+
const r = await route.fetch();
|
|
34
|
+
const b = await r.json();
|
|
35
|
+
const nid = (b.sessions || [])[0]?.network_id || 'default';
|
|
36
|
+
const mk = (alias) => ({
|
|
37
|
+
alias, status: 'working', model: 'claude-opus-4', runtime: 'claude-code-cli',
|
|
38
|
+
network_id: nid, project_dir: null,
|
|
39
|
+
created_at: fresh, updated_at: fresh, last_seen_at: fresh,
|
|
40
|
+
});
|
|
41
|
+
await route.fulfill({ response: r, json: { ...b, sessions: [
|
|
42
|
+
mk('alpha'), mk('beta'), mk('gamma'), mk('delta'),
|
|
43
|
+
] } });
|
|
44
|
+
});
|
|
45
|
+
await ctx.route('**/api/hub/messages*', (r) => r.fulfill({ json: { messages: [] } }));
|
|
46
|
+
await ctx.route('**/api/hub/tasks*', (r) => r.fulfill({ json: { tasks: [] } }));
|
|
47
|
+
|
|
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-panel-title]', { timeout: 10000 });
|
|
52
|
+
await page.waitForSelector('[data-legend-panel-title]', { timeout: 10000 });
|
|
53
|
+
await page.waitForSelector('[data-legend-panel-count]', { timeout: 10000 });
|
|
54
|
+
await page.waitForSelector('[data-topo-top-rail]', { timeout: 10000 });
|
|
55
|
+
await page.waitForTimeout(300);
|
|
56
|
+
|
|
57
|
+
const probe = await page.evaluate(() => {
|
|
58
|
+
const recentTitle = document.querySelector('[data-recent-panel-title]');
|
|
59
|
+
const legendTitle = document.querySelector('[data-legend-panel-title]');
|
|
60
|
+
const legendCount = document.querySelector('[data-legend-panel-count]');
|
|
61
|
+
const topRail = document.querySelector('[data-topo-top-rail]');
|
|
62
|
+
return {
|
|
63
|
+
recentTitleTransition: recentTitle ? recentTitle.style.transition : null,
|
|
64
|
+
legendTitleTransition: legendTitle ? legendTitle.style.transition : null,
|
|
65
|
+
legendCountTransition: legendCount ? legendCount.style.transition : null,
|
|
66
|
+
topRailTransition: topRail ? topRail.style.transition : null,
|
|
67
|
+
};
|
|
68
|
+
});
|
|
69
|
+
await browser.close();
|
|
70
|
+
|
|
71
|
+
const has = (s, prop) => new RegExp(`${prop}\\s+(?:200ms|0\\.2s)`).test(s || '');
|
|
72
|
+
|
|
73
|
+
const results = {
|
|
74
|
+
recent_title_present: probe.recentTitleTransition !== null,
|
|
75
|
+
recent_title_has_fill_200: has(probe.recentTitleTransition, 'fill'),
|
|
76
|
+
|
|
77
|
+
legend_title_present: probe.legendTitleTransition !== null,
|
|
78
|
+
legend_title_has_fill_200: has(probe.legendTitleTransition, 'fill'),
|
|
79
|
+
|
|
80
|
+
legend_count_present: probe.legendCountTransition !== null,
|
|
81
|
+
legend_count_has_fill_200: has(probe.legendCountTransition, 'fill'),
|
|
82
|
+
|
|
83
|
+
r265_top_rail_bg_image_200: has(probe.topRailTransition, 'background-image'),
|
|
84
|
+
};
|
|
85
|
+
const ok = Object.values(results).every(Boolean);
|
|
86
|
+
console.log(`${ok ? '✅' : '❌'} panel title fill ease:`, JSON.stringify(results),
|
|
87
|
+
'\n recent title:', probe.recentTitleTransition,
|
|
88
|
+
'\n legend title:', probe.legendTitleTransition,
|
|
89
|
+
'\n legend count:', probe.legendCountTransition,
|
|
90
|
+
'\n top rail: ', probe.topRailTransition);
|
|
91
|
+
process.exit(ok ? 0 : 1);
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/* Round 301 verification: panel titles ('recent signal' + 'legend')
|
|
2
|
+
* gain letterSpacing="0.3" for editorial parity with R289 watermark
|
|
3
|
+
* + R285 kicker tracking-widest. At fontSize 12 monospace fontWeight
|
|
4
|
+
* 700, 0.3px adds touch of designed-header register without changing
|
|
5
|
+
* the lowercase terminal-style aesthetic.
|
|
6
|
+
*
|
|
7
|
+
* Contract:
|
|
8
|
+
* - [data-recent-panel-title] attr letter-spacing === '0.3'.
|
|
9
|
+
* - [data-legend-panel-title] attr letter-spacing === '0.3'.
|
|
10
|
+
* - Text content still 'recent signal' / 'legend'.
|
|
11
|
+
* - R300 kicker font-medium + R299 mb=16px + R297 transition + R295
|
|
12
|
+
* swatch r=6 + R294 pulse absent intact.
|
|
13
|
+
*/
|
|
14
|
+
import { chromium } from 'playwright';
|
|
15
|
+
import { readFileSync } from 'node:fs';
|
|
16
|
+
|
|
17
|
+
const TOKEN = JSON.parse(readFileSync('/home/vansin/.anet/config.json', 'utf8')).token;
|
|
18
|
+
const browser = await chromium.launch({ headless: true });
|
|
19
|
+
const ctx = await browser.newContext({ viewport: { width: 1500, 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
|
+
const fresh = new Date(Date.now() - 60 * 1000).toISOString();
|
|
25
|
+
await ctx.route('**/api/hub/status*', async (route) => {
|
|
26
|
+
const r = await route.fetch();
|
|
27
|
+
const b = await r.json();
|
|
28
|
+
const nid = (b.sessions || [])[0]?.network_id || 'default';
|
|
29
|
+
const mk = (alias, model) => ({
|
|
30
|
+
alias, status: 'working', model, runtime: 'claude-code-cli',
|
|
31
|
+
network_id: nid, project_dir: null,
|
|
32
|
+
created_at: fresh, updated_at: fresh, last_seen_at: fresh,
|
|
33
|
+
});
|
|
34
|
+
await route.fulfill({ response: r, json: { ...b, sessions: [
|
|
35
|
+
mk('alpha', 'claude-opus-4'),
|
|
36
|
+
mk('beta', 'gpt-4o'),
|
|
37
|
+
] } });
|
|
38
|
+
});
|
|
39
|
+
await ctx.route('**/api/hub/messages*', (r) => r.fulfill({ json: { messages: [] } }));
|
|
40
|
+
await ctx.route('**/api/hub/tasks*', (r) => r.fulfill({ json: { tasks: [] } }));
|
|
41
|
+
|
|
42
|
+
const page = await ctx.newPage();
|
|
43
|
+
await page.goto('http://127.0.0.1:3000/', { waitUntil: 'domcontentloaded' });
|
|
44
|
+
await page.waitForSelector('[data-recent-panel-title]', { timeout: 15000 });
|
|
45
|
+
await page.waitForTimeout(300);
|
|
46
|
+
|
|
47
|
+
const probe = await page.evaluate(() => {
|
|
48
|
+
const recent = document.querySelector('[data-recent-panel-title]');
|
|
49
|
+
const legend = document.querySelector('[data-legend-panel-title]');
|
|
50
|
+
const kicker = document.querySelector('[data-topo-section-kicker]');
|
|
51
|
+
const swatch = document.querySelector('[data-legend-swatch="working"]');
|
|
52
|
+
return {
|
|
53
|
+
recentLs: recent?.getAttribute('letter-spacing') ?? null,
|
|
54
|
+
recentText: recent?.textContent ?? null,
|
|
55
|
+
legendLs: legend?.getAttribute('letter-spacing') ?? null,
|
|
56
|
+
legendText: legend?.textContent ?? null,
|
|
57
|
+
kickerFw: kicker ? getComputedStyle(kicker).fontWeight : null,
|
|
58
|
+
swatchR: swatch?.getAttribute('r') ?? null,
|
|
59
|
+
pulseCount: document.querySelectorAll('[data-pulse-wrapper]').length,
|
|
60
|
+
};
|
|
61
|
+
});
|
|
62
|
+
await browser.close();
|
|
63
|
+
|
|
64
|
+
const results = {
|
|
65
|
+
recent_title_ls_0_3: probe.recentLs === '0.3',
|
|
66
|
+
recent_title_text: probe.recentText === 'recent signal',
|
|
67
|
+
legend_title_ls_0_3: probe.legendLs === '0.3',
|
|
68
|
+
legend_title_text: probe.legendText === 'legend',
|
|
69
|
+
r300_kicker_fw_500: String(probe.kickerFw) === '500',
|
|
70
|
+
r295_swatch_r_6: probe.swatchR === '6',
|
|
71
|
+
r294_pulse_absent: probe.pulseCount === 0,
|
|
72
|
+
};
|
|
73
|
+
const ok = Object.values(results).every(Boolean);
|
|
74
|
+
console.log(`${ok ? '✅' : '❌'} panel title tracking:`, JSON.stringify(results),
|
|
75
|
+
'\n recent-panel-title letter-spacing:', probe.recentLs,
|
|
76
|
+
'\n legend-panel-title letter-spacing:', probe.legendLs,
|
|
77
|
+
'\n R300 kicker font-weight:', probe.kickerFw);
|
|
78
|
+
process.exit(ok ? 0 : 1);
|