@sleep2agi/agent-network-dashboard 0.4.6 → 0.5.1-preview.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/03v-0n3d~t1sm.js +4 -0
- package/.next/static/chunks/0aauz~36q5n2a.css +2 -0
- package/.next/static/chunks/0l_~q07bhpkcx.js +7 -0
- package/.next/static/chunks/{0hyl7mdapsz38.js → 0vt5wron8jig5.js} +1 -1
- package/.next/static/chunks/{16yfxp9ak2gdm.js → 180biiw78-hb_.js} +1 -1
- 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 +6420 -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-links-unit-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-sub-hint-italic-test.mjs +83 -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/0mqwn-l7wtcdo.js +0 -7
- package/.next/static/chunks/127kw7~wsnyu7.css +0 -2
- /package/.next/static/{23MxP0RBVA4BaOJ_HMYmM → ypixDJRds4g4TLoUdmrwN}/_buildManifest.js +0 -0
- /package/.next/static/{23MxP0RBVA4BaOJ_HMYmM → ypixDJRds4g4TLoUdmrwN}/_clientMiddlewareManifest.js +0 -0
- /package/.next/static/{23MxP0RBVA4BaOJ_HMYmM → ypixDJRds4g4TLoUdmrwN}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/* Round 119 verification: when a recent-signal row is pinned (R116),
|
|
2
|
+
* the chip row renders a 4th "filter: from→to · N" pill matching
|
|
3
|
+
* the R64 / R89 pattern for status / group / vendor pins. Closes the
|
|
4
|
+
* pill-pattern gap left after R116.
|
|
5
|
+
*
|
|
6
|
+
* Verifies:
|
|
7
|
+
* - Before pin: no edge pill
|
|
8
|
+
* - Click row → pill shows correct from→to and count
|
|
9
|
+
* - Click pill body → clears
|
|
10
|
+
* - × button also clears
|
|
11
|
+
* - data-filter-match-aliases lists the two endpoints
|
|
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')] } });
|
|
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', 'alpha', 'beta', 40 * 1000),
|
|
46
|
+
mkMsg('m3', 'alpha', 'beta', 50 * 1000),
|
|
47
|
+
] } }));
|
|
48
|
+
await ctx.route('**/api/hub/tasks*', (route) => route.fulfill({ json: { tasks: [] } }));
|
|
49
|
+
const page = await ctx.newPage();
|
|
50
|
+
await page.goto('http://127.0.0.1:3000/', { waitUntil: 'domcontentloaded' });
|
|
51
|
+
await page.waitForFunction(() => document.querySelectorAll('g[data-node]').length === 3, { timeout: 30000 });
|
|
52
|
+
await page.waitForSelector('[data-recent-row]', { timeout: 10000 });
|
|
53
|
+
await page.waitForTimeout(400);
|
|
54
|
+
|
|
55
|
+
const readPill = () => page.evaluate(() => {
|
|
56
|
+
const p = document.querySelector('[data-active-filter="edge"]');
|
|
57
|
+
if (!p) return null;
|
|
58
|
+
return {
|
|
59
|
+
text: (p.textContent || '').trim(),
|
|
60
|
+
count: p.getAttribute('data-filter-match-count'),
|
|
61
|
+
aliases: p.getAttribute('data-filter-match-aliases') || '',
|
|
62
|
+
title: p.getAttribute('title') || '',
|
|
63
|
+
};
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
const before = await readPill();
|
|
67
|
+
|
|
68
|
+
// Click row to 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 readPill();
|
|
73
|
+
|
|
74
|
+
// Click pill body to clear.
|
|
75
|
+
await page.locator('[data-active-filter="edge"]').click();
|
|
76
|
+
await page.mouse.move(10, 10);
|
|
77
|
+
await page.waitForTimeout(300);
|
|
78
|
+
const afterBodyClear = await readPill();
|
|
79
|
+
|
|
80
|
+
// Pin again, then click × button.
|
|
81
|
+
await page.locator('[data-recent-row="alpha->beta"]').click();
|
|
82
|
+
await page.mouse.move(10, 10);
|
|
83
|
+
await page.waitForTimeout(300);
|
|
84
|
+
await page.locator('[data-active-filter="edge"] button').click();
|
|
85
|
+
await page.waitForTimeout(300);
|
|
86
|
+
const afterXClear = await readPill();
|
|
87
|
+
|
|
88
|
+
await browser.close();
|
|
89
|
+
|
|
90
|
+
const results = {
|
|
91
|
+
before_noPill: before === null,
|
|
92
|
+
pin_pillRendered: afterPin !== null,
|
|
93
|
+
pin_textContainsArrow: /alpha→beta/.test(afterPin?.text || ''),
|
|
94
|
+
pin_count3: afterPin?.count === '3',
|
|
95
|
+
pin_aliasesMatch: afterPin?.aliases === 'alpha,beta',
|
|
96
|
+
pin_titleHasFromTo: /alpha → beta \(3 msgs\)/.test(afterPin?.title || ''),
|
|
97
|
+
bodyClear_pillGone: afterBodyClear === null,
|
|
98
|
+
xClear_pillGone: afterXClear === null,
|
|
99
|
+
};
|
|
100
|
+
const ok = Object.values(results).every(Boolean);
|
|
101
|
+
console.log(`${ok ? '✅' : '❌'} edge pill:`, JSON.stringify(results),
|
|
102
|
+
`\n afterPin=`, afterPin,
|
|
103
|
+
`\n afterBodyClear=`, afterBodyClear,
|
|
104
|
+
`\n afterXClear=`, afterXClear);
|
|
105
|
+
process.exit(ok ? 0 : 1);
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/* Round 279 verification: arrival ping + dispatch pulse SMIL retired
|
|
2
|
+
* (R75 + R76 + R228 + R231 + R252 family) — 减法 cut #5.
|
|
3
|
+
*
|
|
4
|
+
* Per active flow edge the pre-R279 SMIL family was:
|
|
5
|
+
* particle (R50 animateMotion along curve path) ← KEPT
|
|
6
|
+
* arrival ping (R75 circle + r/opacity animate) ← RETIRED
|
|
7
|
+
* dispatch pulse (R76 circle + r/opacity animate) ← RETIRED
|
|
8
|
+
*
|
|
9
|
+
* For a 5-edge fleet that's 5×3 = 15 simultaneous SMIL on edges
|
|
10
|
+
* alone, pre-R279. The particle (a moving dot along the path) is the
|
|
11
|
+
* primary "data flowing from A → B" visual signal; the ping + pulse
|
|
12
|
+
* are secondary "arrival/dispatch confirmation" that the moving
|
|
13
|
+
* particle already conveys. R279 culls ping + pulse, keeps particle.
|
|
14
|
+
*
|
|
15
|
+
* Net: -10 SMIL animations for a 5-edge fleet. Combined with R276
|
|
16
|
+
* (-4 orbit) and R278 (-4 working halo), the canvas motion budget
|
|
17
|
+
* is now: 1 hub breath + N particles per active edge, that's it.
|
|
18
|
+
*
|
|
19
|
+
* Test scope:
|
|
20
|
+
* 1. No element matches `[data-arrival-ping]` (R75 retired).
|
|
21
|
+
* 2. No element matches `[data-dispatch-pulse]` (R76 retired).
|
|
22
|
+
* 3. Particles still present (`[data-edge-particle]` or equivalent).
|
|
23
|
+
* 4. R275 freshness chip absent (regression).
|
|
24
|
+
* 5. R276 orbit absent (regression).
|
|
25
|
+
* 6. R277 legend height 88 (regression).
|
|
26
|
+
* 7. R278 working halo <animate> count 0 (regression).
|
|
27
|
+
*/
|
|
28
|
+
import { chromium } from 'playwright';
|
|
29
|
+
import { readFileSync } from 'node:fs';
|
|
30
|
+
|
|
31
|
+
const TOKEN = JSON.parse(readFileSync('/home/vansin/.anet/config.json', 'utf8')).token;
|
|
32
|
+
const browser = await chromium.launch({ headless: true });
|
|
33
|
+
const ctx = await browser.newContext({ viewport: { width: 1500, height: 1500 } });
|
|
34
|
+
await ctx.addCookies([{ name: 'anet_dashboard_session', value: `v3:${TOKEN}`, domain: '127.0.0.1', path: '/' }]);
|
|
35
|
+
await ctx.addInitScript(() => {
|
|
36
|
+
try { localStorage.setItem('anet-theme', 'cyber'); sessionStorage.setItem('anet_v3_auth', '1'); } catch {}
|
|
37
|
+
});
|
|
38
|
+
const fresh = new Date(Date.now() - 60 * 1000).toISOString();
|
|
39
|
+
await ctx.route('**/api/hub/status*', async (route) => {
|
|
40
|
+
const r = await route.fetch();
|
|
41
|
+
const b = await r.json();
|
|
42
|
+
const nid = (b.sessions || [])[0]?.network_id || 'default';
|
|
43
|
+
const mk = (alias) => ({
|
|
44
|
+
alias, status: 'working', model: 'claude-opus-4', runtime: 'claude-code-cli',
|
|
45
|
+
network_id: nid, project_dir: null,
|
|
46
|
+
created_at: fresh, updated_at: fresh, last_seen_at: fresh,
|
|
47
|
+
});
|
|
48
|
+
await route.fulfill({ response: r, json: { ...b, sessions: [
|
|
49
|
+
mk('alpha'), mk('beta'), mk('gamma'), mk('delta'),
|
|
50
|
+
] } });
|
|
51
|
+
});
|
|
52
|
+
// 5 distinct flow pairs so particles + (formerly) ping/pulse mount
|
|
53
|
+
// on multiple edges with link.count >= 3 (the dispatch-pulse gate
|
|
54
|
+
// pre-R279).
|
|
55
|
+
const now = Date.now();
|
|
56
|
+
const msgs = [];
|
|
57
|
+
for (let pair = 0; pair < 5; pair++) {
|
|
58
|
+
for (let i = 0; i < 5; i++) {
|
|
59
|
+
const from = ['alpha','beta','gamma','delta'][pair % 4];
|
|
60
|
+
const to = ['beta','gamma','delta','alpha'][pair % 4];
|
|
61
|
+
msgs.push({
|
|
62
|
+
id: `m${pair}-${i}`, from_alias: from, to_alias: to, content: 'hi',
|
|
63
|
+
network_id: 'default',
|
|
64
|
+
created_at: new Date(now - (1000 + pair * 200 + i * 50)).toISOString(),
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
await ctx.route('**/api/hub/messages*', (r) => r.fulfill({ json: { messages: msgs } }));
|
|
69
|
+
await ctx.route('**/api/hub/tasks*', (r) => r.fulfill({ json: { tasks: [] } }));
|
|
70
|
+
|
|
71
|
+
const page = await ctx.newPage();
|
|
72
|
+
await page.goto('http://127.0.0.1:3000/', { waitUntil: 'domcontentloaded' });
|
|
73
|
+
await page.waitForFunction(() => document.querySelectorAll('g[data-node]').length === 4, { timeout: 30000 });
|
|
74
|
+
await page.waitForSelector('[data-topo-panel="legend"]', { timeout: 10000 });
|
|
75
|
+
await page.waitForSelector('[data-edge-particle]', { timeout: 10000, state: 'attached' });
|
|
76
|
+
await page.waitForTimeout(300);
|
|
77
|
+
|
|
78
|
+
const probe = await page.evaluate(() => {
|
|
79
|
+
const ping = document.querySelectorAll('[data-arrival-ping]');
|
|
80
|
+
const pulse = document.querySelectorAll('[data-dispatch-pulse]');
|
|
81
|
+
const particle = document.querySelectorAll('[data-edge-particle]');
|
|
82
|
+
const freshnessChip = document.querySelector('[data-freshness-chip]');
|
|
83
|
+
const orbits = document.querySelectorAll('[data-topo-orbit-bucket]');
|
|
84
|
+
const legendG = document.querySelector('[data-topo-panel="legend"]');
|
|
85
|
+
const legendH = legendG?.querySelector('rect')?.getAttribute('height') ?? null;
|
|
86
|
+
const halos = document.querySelectorAll('[data-node-halo-breath="on"]');
|
|
87
|
+
let haloAnimateCount = 0;
|
|
88
|
+
halos.forEach((h) => { haloAnimateCount += h.querySelectorAll('animate').length; });
|
|
89
|
+
return {
|
|
90
|
+
pingCount: ping.length,
|
|
91
|
+
pulseCount: pulse.length,
|
|
92
|
+
particleCount: particle.length,
|
|
93
|
+
freshnessPresent: freshnessChip !== null,
|
|
94
|
+
orbitCount: orbits.length,
|
|
95
|
+
legendHeight: legendH,
|
|
96
|
+
haloAnimateCount,
|
|
97
|
+
};
|
|
98
|
+
});
|
|
99
|
+
await browser.close();
|
|
100
|
+
|
|
101
|
+
const results = {
|
|
102
|
+
arrival_ping_absent: probe.pingCount === 0,
|
|
103
|
+
dispatch_pulse_absent: probe.pulseCount === 0,
|
|
104
|
+
particles_still_present: probe.particleCount > 0,
|
|
105
|
+
r275_freshness_absent: probe.freshnessPresent === false,
|
|
106
|
+
r276_orbit_absent: probe.orbitCount === 0,
|
|
107
|
+
r277_legend_height_88: probe.legendHeight === '88',
|
|
108
|
+
r278_halo_animate_count_zero: probe.haloAnimateCount === 0,
|
|
109
|
+
};
|
|
110
|
+
const ok = Object.values(results).every(Boolean);
|
|
111
|
+
console.log(`${ok ? '✅' : '❌'} edge ping/pulse retired:`, JSON.stringify(results),
|
|
112
|
+
'\n arrival ping count (expect 0):', probe.pingCount,
|
|
113
|
+
'\n dispatch pulse count (expect 0):', probe.pulseCount,
|
|
114
|
+
'\n particle count (expect > 0):', probe.particleCount,
|
|
115
|
+
'\n freshness absent:', !probe.freshnessPresent,
|
|
116
|
+
'\n orbit count (expect 0):', probe.orbitCount,
|
|
117
|
+
'\n legend height:', probe.legendHeight,
|
|
118
|
+
'\n halo animate count (expect 0):', probe.haloAnimateCount);
|
|
119
|
+
process.exit(ok ? 0 : 1);
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/* Round 245 verification: edge surface (visible flow path + flow
|
|
2
|
+
* rail dashed underline) picks up stroke-color transitions so
|
|
3
|
+
* theme toggle eases instead of snapping.
|
|
4
|
+
*
|
|
5
|
+
* Pre-R245:
|
|
6
|
+
* - [data-edge-visible]: transition = 'opacity 300ms ease-out,
|
|
7
|
+
* stroke-width 300ms ease-out' (R166)
|
|
8
|
+
* - [data-edge-flow-rail]: Tailwind className 'transition-opacity
|
|
9
|
+
* duration-300' (opacity only, no stroke)
|
|
10
|
+
*
|
|
11
|
+
* Post-R245:
|
|
12
|
+
* - [data-edge-visible]: transition list adds 'stroke 300ms ease-
|
|
13
|
+
* out' alongside the existing two
|
|
14
|
+
* - [data-edge-flow-rail]: inline style with both 'opacity' and
|
|
15
|
+
* 'stroke' at 300ms ease-out; Tailwind className dropped
|
|
16
|
+
*
|
|
17
|
+
* Scenario: 4 working agents + 5-msg alpha→beta flow → at least
|
|
18
|
+
* one visible flow + flow-rail pair.
|
|
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
|
+
const now = Date.now();
|
|
45
|
+
const msgs = [];
|
|
46
|
+
for (let i = 0; i < 5; i++) {
|
|
47
|
+
msgs.push({
|
|
48
|
+
id: `m${i}`, from_alias: 'alpha', to_alias: 'beta', content: 'hi',
|
|
49
|
+
network_id: 'default', created_at: new Date(now - (1000 + i * 50)).toISOString(),
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
await ctx.route('**/api/hub/messages*', (r2) => r2.fulfill({ json: { messages: msgs } }));
|
|
53
|
+
await ctx.route('**/api/hub/tasks*', (r2) => r2.fulfill({ json: { tasks: [] } }));
|
|
54
|
+
|
|
55
|
+
const page = await ctx.newPage();
|
|
56
|
+
await page.goto('http://127.0.0.1:3000/', { waitUntil: 'domcontentloaded' });
|
|
57
|
+
await page.waitForFunction(() => document.querySelectorAll('g[data-node]').length === 4, { timeout: 30000 });
|
|
58
|
+
await page.waitForSelector('[data-edge-visible]', { timeout: 10000, state: 'attached' });
|
|
59
|
+
await page.waitForSelector('[data-edge-flow-rail]', { timeout: 10000, state: 'attached' });
|
|
60
|
+
await page.waitForTimeout(300);
|
|
61
|
+
|
|
62
|
+
const out = await page.evaluate(() => {
|
|
63
|
+
const probe = (sel) => {
|
|
64
|
+
const el = document.querySelector(sel);
|
|
65
|
+
if (!el) return null;
|
|
66
|
+
return {
|
|
67
|
+
transition: getComputedStyle(el).transition,
|
|
68
|
+
className: el.getAttribute('class') || '',
|
|
69
|
+
stroke: el.getAttribute('stroke'),
|
|
70
|
+
};
|
|
71
|
+
};
|
|
72
|
+
return {
|
|
73
|
+
visible: probe('[data-edge-visible]'),
|
|
74
|
+
rail: probe('[data-edge-flow-rail]'),
|
|
75
|
+
};
|
|
76
|
+
});
|
|
77
|
+
await browser.close();
|
|
78
|
+
|
|
79
|
+
const hasProp = (s, prop) => new RegExp(`${prop}\\s+(?:300ms|0\\.3s)`).test(s || '');
|
|
80
|
+
|
|
81
|
+
const results = {
|
|
82
|
+
visible_present: out.visible !== null,
|
|
83
|
+
visible_has_opacity_300ms: hasProp(out.visible?.transition, 'opacity'),
|
|
84
|
+
visible_has_stroke_width_300ms: hasProp(out.visible?.transition, 'stroke-width'),
|
|
85
|
+
visible_has_stroke_300ms: hasProp(out.visible?.transition, 'stroke'),
|
|
86
|
+
|
|
87
|
+
rail_present: out.rail !== null,
|
|
88
|
+
rail_has_opacity_300ms: hasProp(out.rail?.transition, 'opacity'),
|
|
89
|
+
rail_has_stroke_300ms: hasProp(out.rail?.transition, 'stroke'),
|
|
90
|
+
// Tailwind 'transition-opacity duration-300' className dropped
|
|
91
|
+
// (the inline transition list replaces it; Tailwind would
|
|
92
|
+
// otherwise OVERRIDE the inline stroke transition with its
|
|
93
|
+
// opacity-only declaration)
|
|
94
|
+
rail_no_tailwind_class: !/transition-opacity/.test(out.rail?.className || ''),
|
|
95
|
+
};
|
|
96
|
+
const ok = Object.values(results).every(Boolean);
|
|
97
|
+
console.log(`${ok ? '✅' : '❌'} edge stroke ease:`, JSON.stringify(results),
|
|
98
|
+
'\n visible:', out.visible,
|
|
99
|
+
'\n rail: ', out.rail);
|
|
100
|
+
process.exit(ok ? 0 : 1);
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
/* Round 166 verification: visible flow edge path picks up
|
|
2
|
+
* stroke-width transition.
|
|
3
|
+
*
|
|
4
|
+
* R50 thickens hovered edges to 1.4× (renderWidth = width * 1.4)
|
|
5
|
+
* but pre-R166 only opacity transitioned — width snapped. R166
|
|
6
|
+
* adds stroke-width to the transition list so the edge thickens
|
|
7
|
+
* smoothly on hover, pairing with R164 edge-badge r-lift for
|
|
8
|
+
* coordinated 300ms ease-out across the edge surface.
|
|
9
|
+
*
|
|
10
|
+
* Test:
|
|
11
|
+
* 1. Mock 4 sessions + 1 flow alpha→beta
|
|
12
|
+
* 2. Probe visible path before hover → strokeWidth=base
|
|
13
|
+
* 3. Probe transition string includes both opacity and
|
|
14
|
+
* stroke-width
|
|
15
|
+
* 4. Hover edge hitbox → wait 350ms (past transition)
|
|
16
|
+
* 5. Probe strokeWidth → should be ≈ base * 1.4
|
|
17
|
+
* 6. mouse away → strokeWidth back to base
|
|
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
|
+
|
|
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
|
+
|
|
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: 'cli-claude-code',
|
|
38
|
+
network_id: nid, project_dir: null,
|
|
39
|
+
created_at: fresh, updated_at: fresh, last_seen_at: fresh,
|
|
40
|
+
});
|
|
41
|
+
// 4 sessions so alpha + beta are 90° apart (not 180° — that
|
|
42
|
+
// would put their edge midpoint on the hub, where the hub
|
|
43
|
+
// <g> intercepts pointer events). gamma + delta are filler.
|
|
44
|
+
await route.fulfill({ response: r, json: { ...b, sessions: [
|
|
45
|
+
mk('alpha'), mk('beta'), mk('gamma'), mk('delta'),
|
|
46
|
+
] } });
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
const now = Date.now();
|
|
50
|
+
// 4 msgs so:
|
|
51
|
+
// - width = Math.min(2+4, 7) = 6
|
|
52
|
+
// - hover renderWidth = Math.min(6*1.4, 10) = 8.4
|
|
53
|
+
// AND the edge midpoint count badge renders (R100 threshold
|
|
54
|
+
// count >= 3) so we can use it as the hover surface. The
|
|
55
|
+
// visible path has pointerEvents:none; the R48 hitbox is a
|
|
56
|
+
// thin stroke that Playwright's .hover() can't reliably land
|
|
57
|
+
// on. The badge is a r=9 circle with pointerEvents:all and
|
|
58
|
+
// propagates hover to hoveredEdgeKey (R122) — most reliable
|
|
59
|
+
// target for triggering the visible-path transition.
|
|
60
|
+
const msgs = [];
|
|
61
|
+
for (let i = 0; i < 4; i++) {
|
|
62
|
+
msgs.push({ id: `m${i}`, from_alias: 'alpha', to_alias: 'beta', content: 'hi',
|
|
63
|
+
network_id: 'default', created_at: new Date(now - (10000 + i * 500)).toISOString() });
|
|
64
|
+
}
|
|
65
|
+
await ctx.route('**/api/hub/messages*', (route) => route.fulfill({ json: { messages: msgs } }));
|
|
66
|
+
await ctx.route('**/api/hub/tasks*', (route) => route.fulfill({ json: { tasks: [] } }));
|
|
67
|
+
|
|
68
|
+
const page = await ctx.newPage();
|
|
69
|
+
await page.goto('http://127.0.0.1:3000/', { waitUntil: 'domcontentloaded' });
|
|
70
|
+
await page.waitForFunction(() => document.querySelectorAll('g[data-node]').length === 4, { timeout: 30000 });
|
|
71
|
+
await page.waitForSelector('[data-edge-visible]', { timeout: 10000 });
|
|
72
|
+
await page.waitForTimeout(400);
|
|
73
|
+
|
|
74
|
+
const idle = await page.evaluate(() => {
|
|
75
|
+
const el = document.querySelector('[data-edge-visible]');
|
|
76
|
+
if (!el) return null;
|
|
77
|
+
return {
|
|
78
|
+
strokeWidth: parseFloat(el.getAttribute('stroke-width')),
|
|
79
|
+
inlineTransition: el.style.transition || '',
|
|
80
|
+
computedTransition: getComputedStyle(el).transition || '',
|
|
81
|
+
};
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
// Hover the edge midpoint badge (R164 r=9 circle, pointerEvents:all,
|
|
85
|
+
// propagates to hoveredEdgeKey via R122). The visible path has
|
|
86
|
+
// pointerEvents:none; the R48 hitbox is a thin stroke that
|
|
87
|
+
// Playwright .hover() can't reliably land on.
|
|
88
|
+
await page.locator('[data-edge-count-badge]').hover();
|
|
89
|
+
// Wait for transition to settle.
|
|
90
|
+
await page.waitForTimeout(400);
|
|
91
|
+
const hovered = await page.evaluate(() => {
|
|
92
|
+
const el = document.querySelector('[data-edge-visible]');
|
|
93
|
+
if (!el) return null;
|
|
94
|
+
return {
|
|
95
|
+
strokeWidth: parseFloat(el.getAttribute('stroke-width')),
|
|
96
|
+
};
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
// Move cursor away
|
|
100
|
+
await page.mouse.move(10, 10);
|
|
101
|
+
await page.waitForTimeout(400);
|
|
102
|
+
const idleAgain = await page.evaluate(() => {
|
|
103
|
+
const el = document.querySelector('[data-edge-visible]');
|
|
104
|
+
if (!el) return null;
|
|
105
|
+
return {
|
|
106
|
+
strokeWidth: parseFloat(el.getAttribute('stroke-width')),
|
|
107
|
+
};
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
await browser.close();
|
|
111
|
+
|
|
112
|
+
const hasOpacity = (idle?.inlineTransition || '').includes('opacity 300ms') ||
|
|
113
|
+
/opacity\s+0\.3s|opacity\s+300ms/.test(idle?.computedTransition || '');
|
|
114
|
+
const hasStrokeWidth = (idle?.inlineTransition || '').includes('stroke-width 300ms') ||
|
|
115
|
+
/stroke-width\s+0\.3s|stroke-width\s+300ms/.test(idle?.computedTransition || '');
|
|
116
|
+
|
|
117
|
+
// Expected: width=Math.min(2+4, 7)=6. Hover renderWidth=Math.min(6*1.4, 10)=8.4.
|
|
118
|
+
const results = {
|
|
119
|
+
edge_found: idle !== null,
|
|
120
|
+
has_opacity_transition: hasOpacity,
|
|
121
|
+
has_stroke_width_transition: hasStrokeWidth,
|
|
122
|
+
idle_width_6: idle && Math.abs(idle.strokeWidth - 6) < 0.05,
|
|
123
|
+
hover_width_8p4: hovered && Math.abs(hovered.strokeWidth - 8.4) < 0.1,
|
|
124
|
+
hover_width_thicker: hovered && idle && hovered.strokeWidth > idle.strokeWidth,
|
|
125
|
+
idle_again_width_6: idleAgain && Math.abs(idleAgain.strokeWidth - 6) < 0.05,
|
|
126
|
+
};
|
|
127
|
+
const ok = Object.values(results).every(Boolean);
|
|
128
|
+
console.log(`${ok ? '✅' : '❌'} edge stroke transition:`, JSON.stringify(results),
|
|
129
|
+
`\n idle =`, idle,
|
|
130
|
+
`\n hovered =`, hovered,
|
|
131
|
+
`\n idleAgain =`, idleAgain);
|
|
132
|
+
process.exit(ok ? 0 : 1);
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/* Round 302 verification: recent-signal panel empty-state hint
|
|
2
|
+
* ('no flow yet') gains letterSpacing="0.2" for editorial parity
|
|
3
|
+
* with R301 panel titles (0.3) + R285 kicker tracking-widest +
|
|
4
|
+
* R289 watermark letterSpacing.
|
|
5
|
+
*
|
|
6
|
+
* Contract:
|
|
7
|
+
* - [data-recent-signal-empty] attr letter-spacing === '0.2'.
|
|
8
|
+
* - Text content still 'no flow yet'.
|
|
9
|
+
* - opacity 0.65 + fontStyle italic preserved.
|
|
10
|
+
* - R301 panel-title letter-spacings (0.3) still in place.
|
|
11
|
+
* - R300 kicker font-medium + R295 swatch r=6 + R294 pulse absent
|
|
12
|
+
* 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
|
+
// Empty messages → "no flow yet" hint visible.
|
|
40
|
+
await ctx.route('**/api/hub/messages*', (r) => r.fulfill({ json: { messages: [] } }));
|
|
41
|
+
await ctx.route('**/api/hub/tasks*', (r) => r.fulfill({ json: { tasks: [] } }));
|
|
42
|
+
|
|
43
|
+
const page = await ctx.newPage();
|
|
44
|
+
await page.goto('http://127.0.0.1:3000/', { waitUntil: 'domcontentloaded' });
|
|
45
|
+
await page.waitForSelector('[data-recent-signal-empty]', { timeout: 15000 });
|
|
46
|
+
await page.waitForTimeout(300);
|
|
47
|
+
|
|
48
|
+
const probe = await page.evaluate(() => {
|
|
49
|
+
const empty = document.querySelector('[data-recent-signal-empty]');
|
|
50
|
+
const recentTitle = document.querySelector('[data-recent-panel-title]');
|
|
51
|
+
const legendTitle = document.querySelector('[data-legend-panel-title]');
|
|
52
|
+
const kicker = document.querySelector('[data-topo-section-kicker]');
|
|
53
|
+
const swatch = document.querySelector('[data-legend-swatch="working"]');
|
|
54
|
+
return {
|
|
55
|
+
emptyLs: empty?.getAttribute('letter-spacing') ?? null,
|
|
56
|
+
emptyText: empty?.textContent?.trim() ?? null,
|
|
57
|
+
emptyOpacity: empty?.getAttribute('opacity') ?? null,
|
|
58
|
+
emptyStyle: empty?.getAttribute('font-style') ?? null,
|
|
59
|
+
recentTitleLs: recentTitle?.getAttribute('letter-spacing') ?? null,
|
|
60
|
+
legendTitleLs: legendTitle?.getAttribute('letter-spacing') ?? null,
|
|
61
|
+
kickerFw: kicker ? getComputedStyle(kicker).fontWeight : null,
|
|
62
|
+
swatchR: swatch?.getAttribute('r') ?? null,
|
|
63
|
+
pulseCount: document.querySelectorAll('[data-pulse-wrapper]').length,
|
|
64
|
+
};
|
|
65
|
+
});
|
|
66
|
+
await browser.close();
|
|
67
|
+
|
|
68
|
+
const results = {
|
|
69
|
+
empty_hint_ls_0_2: probe.emptyLs === '0.2',
|
|
70
|
+
empty_hint_text_kept: (probe.emptyText || '').startsWith('no flow yet'),
|
|
71
|
+
empty_opacity_0_65: String(probe.emptyOpacity) === '0.65',
|
|
72
|
+
empty_italic_kept: probe.emptyStyle === 'italic',
|
|
73
|
+
r301_recent_title_ls: probe.recentTitleLs === '0.3',
|
|
74
|
+
r301_legend_title_ls: probe.legendTitleLs === '0.3',
|
|
75
|
+
r300_kicker_fw_500: String(probe.kickerFw) === '500',
|
|
76
|
+
r295_swatch_r_6: probe.swatchR === '6',
|
|
77
|
+
r294_pulse_absent: probe.pulseCount === 0,
|
|
78
|
+
};
|
|
79
|
+
const ok = Object.values(results).every(Boolean);
|
|
80
|
+
console.log(`${ok ? '✅' : '❌'} empty-hint tracking:`, JSON.stringify(results),
|
|
81
|
+
'\n empty hint letter-spacing:', probe.emptyLs,
|
|
82
|
+
'\n empty hint text:', JSON.stringify(probe.emptyText),
|
|
83
|
+
'\n R301 panel titles ls:', probe.recentTitleLs, '/', probe.legendTitleLs);
|
|
84
|
+
process.exit(ok ? 0 : 1);
|