@sleep2agi/agent-network-dashboard 0.4.6-preview.31 → 0.4.6-preview.310
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/build-manifest.json +3 -3
- package/.next/diagnostics/route-bundle-stats.json +41 -41
- package/.next/fallback-build-manifest.json +3 -3
- package/.next/prerender-manifest.json +3 -3
- package/.next/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/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/chunks/ssr/[root-of-the-server]__03b.f76._.js +1 -1
- package/.next/server/chunks/ssr/[root-of-the-server]__03b.f76._.js.map +1 -1
- package/.next/server/chunks/ssr/[root-of-the-server]__0fhoq8i._.js +1 -1
- package/.next/server/chunks/ssr/[root-of-the-server]__0fhoq8i._.js.map +1 -1
- package/.next/server/chunks/ssr/[root-of-the-server]__0nw~zhp._.js +1 -1
- package/.next/server/chunks/ssr/[root-of-the-server]__0nw~zhp._.js.map +1 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_09kk21a._.js +4 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_09kk21a._.js.map +1 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_app_01jhlxz._.js +1 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_app_01jhlxz._.js.map +1 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_app_057q.ne._.js +1 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_app_057q.ne._.js.map +1 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_app_09d29my._.js +1 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_app_09d29my._.js.map +1 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_app_0_d45-d._.js +1 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_app_0_d45-d._.js.map +1 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_app_0i3759l._.js +1 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_app_0i3759l._.js.map +1 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_app_0xgney8._.js +1 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_app_0xgney8._.js.map +1 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_app_10hjgv4._.js +1 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_app_10hjgv4._.js.map +1 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_app_1153xeb._.js +1 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_app_1153xeb._.js.map +1 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_app_12l4oto._.js +1 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_app_12l4oto._.js.map +1 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_app_components_0mvyi-4._.js +1 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_app_components_0mvyi-4._.js.map +1 -1
- package/.next/server/middleware-build-manifest.js +3 -3
- package/.next/server/pages/404.html +2 -2
- package/.next/server/pages/500.html +1 -1
- package/.next/server/server-reference-manifest.js +1 -1
- package/.next/server/server-reference-manifest.json +1 -1
- package/.next/static/chunks/0-mpa_947ipeq.js +1 -0
- package/.next/static/chunks/01lmbsd37fybu.js +1 -0
- package/.next/static/chunks/03o.h6kvmw4l_.js +1 -0
- package/.next/static/chunks/03~~oirxz7~vc.js +1 -0
- package/.next/static/chunks/05uk96gc~9mni.js +1 -0
- package/.next/static/chunks/08kf-.bgs10ze.js +1 -0
- package/.next/static/chunks/0ggj5ummw2a84.js +7 -0
- package/.next/static/chunks/0glmrdj9112tc.js +7 -0
- package/.next/static/chunks/0o40uf-rn28q6.js +1 -0
- package/.next/static/chunks/0q3hr1~viwzkt.js +4 -0
- package/.next/static/chunks/0rxrez_cjn.eh.js +1 -0
- package/.next/static/chunks/0x8x.29hkju5a.js +1 -0
- package/.next/static/chunks/0~ks9b48lw8hx.css +2 -0
- package/.next/static/chunks/13lvf-h-j8bmc.js +1 -0
- package/.next/static/chunks/174re5ar~kxne.js +1 -0
- package/.next/trace +2 -2
- package/.next/trace-build +1 -1
- package/app/components/ChatPopover.tsx +38 -2
- package/app/components/CommandPalette.tsx +107 -0
- package/app/components/HelpOverlay.tsx +126 -0
- package/app/components/TopoGraph.tsx +5927 -258
- package/app/components/utils.ts +8 -7
- package/app/globals.css +110 -5
- package/app/lib/time.ts +36 -0
- package/app/lib/vendorIdentity.ts +14 -3
- 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/scripts/help-overlay-topo-test.mjs +44 -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-chip-test.mjs +73 -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-auto-fit-test.mjs +73 -0
- package/scripts/topo-brand-watermark-test.mjs +97 -0
- package/scripts/topo-canvas-aria-test.mjs +108 -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-semantic-gap-test.mjs +97 -0
- package/scripts/topo-chip-row-tabular-test.mjs +111 -0
- package/scripts/topo-chrome-a11y-test.mjs +107 -0
- package/scripts/topo-chrome-icon-stroke-test.mjs +95 -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-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-cwd-tooltip-test.mjs +64 -0
- package/scripts/topo-dblclick-reset-test.mjs +74 -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 +93 -0
- package/scripts/topo-edge-pill-hot-test.mjs +129 -0
- package/scripts/topo-edge-pill-test.mjs +105 -0
- package/scripts/topo-edge-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-edge-tooltip-test.mjs +70 -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-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-test.mjs +110 -0
- package/scripts/topo-filter-pill-mobile-test.mjs +90 -0
- package/scripts/topo-fit-key-test.mjs +106 -0
- package/scripts/topo-freshness-chip-test.mjs +74 -0
- package/scripts/topo-freshness-chip-transition-test.mjs +80 -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 +100 -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-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 +93 -0
- 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-label-card-theme-ease-test.mjs +85 -0
- package/scripts/topo-label-lift-test.mjs +119 -0
- package/scripts/topo-lastseen-tooltip-test.mjs +59 -0
- package/scripts/topo-layout-hover-text-preview-test.mjs +101 -0
- package/scripts/topo-layout-key-test.mjs +91 -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-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-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-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-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-rect-stroke-test.mjs +94 -0
- package/scripts/topo-minimap-test.mjs +68 -0
- package/scripts/topo-minimap-viewport-smooth-test.mjs +124 -0
- package/scripts/topo-mobile-chips-test.mjs +103 -0
- package/scripts/topo-monogram-font-test.mjs +112 -0
- package/scripts/topo-monogram-stroke-test.mjs +101 -0
- package/scripts/topo-node-a11y-test.mjs +107 -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-overlap-test.mjs +32 -5
- 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-theme-ease-test.mjs +85 -0
- package/scripts/topo-panel-title-fill-ease-test.mjs +91 -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-popover-meta-test.mjs +78 -0
- package/scripts/topo-prepublish-guard-test.mjs +95 -0
- package/scripts/topo-pressure-bar-test.mjs +69 -0
- package/scripts/topo-pressure-hover-test.mjs +123 -0
- package/scripts/topo-pressure-pin-test.mjs +119 -0
- package/scripts/topo-pressure-seg-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-pulse-rate-test.mjs +71 -0
- package/scripts/topo-recent-panel-count-freshness-test.mjs +109 -0
- package/scripts/topo-recent-panel-count-test.mjs +72 -0
- package/scripts/topo-recent-panel-footer-breath-test.mjs +142 -0
- package/scripts/topo-recent-panel-hot-header-test.mjs +132 -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-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-test.mjs +95 -0
- package/scripts/topo-recent-row-typography-test.mjs +119 -0
- package/scripts/topo-recent-signal-empty-hint-test.mjs +73 -0
- package/scripts/topo-recent-signal-empty-test.mjs +63 -0
- package/scripts/topo-reduced-motion-test.mjs +77 -0
- package/scripts/topo-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-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-toggle-inactive-cyan-hover-test.mjs +110 -0
- package/scripts/topo-top-rail-theme-ease-test.mjs +89 -0
- package/scripts/topo-tz-ghost-test.mjs +69 -0
- package/scripts/topo-vendor-chip-hover-test.mjs +111 -0
- package/scripts/topo-vendor-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-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-shadow-theme-ease-test.mjs +89 -0
- package/.next/static/chunks/0-7iowzu4.798.js +0 -1
- package/.next/static/chunks/01u5zo8b7r_r3.js +0 -1
- package/.next/static/chunks/02t5jr4shh.hy.js +0 -1
- package/.next/static/chunks/09nd.t_hd.y6t.css +0 -2
- package/.next/static/chunks/0_qfg5s5uzs7..js +0 -7
- package/.next/static/chunks/0elalb9n_.~di.js +0 -1
- package/.next/static/chunks/0fqit.b4j_6rz.js +0 -1
- package/.next/static/chunks/0j_q__o8p6g83.js +0 -1
- package/.next/static/chunks/0jl6_w50zh4l5.js +0 -1
- package/.next/static/chunks/0pl7l_.2im.j0.js +0 -7
- package/.next/static/chunks/0qcfcgdthhos6.js +0 -1
- package/.next/static/chunks/0r4q73.-1bkyl.js +0 -1
- package/.next/static/chunks/0r_c8eccg3z2o.js +0 -1
- package/.next/static/chunks/10oi7l-tycgl9.js +0 -1
- package/.next/static/chunks/11uk1izuv3~0t.js +0 -1
- /package/.next/static/{mgs4E0Fu2JlZsA5DB0XUu → Kkkh4U0z1GCAKfQMsfmjt}/_buildManifest.js +0 -0
- /package/.next/static/{mgs4E0Fu2JlZsA5DB0XUu → Kkkh4U0z1GCAKfQMsfmjt}/_clientMiddlewareManifest.js +0 -0
- /package/.next/static/{mgs4E0Fu2JlZsA5DB0XUu → Kkkh4U0z1GCAKfQMsfmjt}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/* Round 57 verification: recent-signal + legend panels carry a drop-
|
|
2
|
+
* shadow filter so they read as floating cards instead of pasted-on
|
|
3
|
+
* graphics — especially important on light theme where panel fill is
|
|
4
|
+
* near-white on a near-white canvas.
|
|
5
|
+
*
|
|
6
|
+
* - Both panels render a <rect> with `data-topo-panel-elevation`.
|
|
7
|
+
* - The rect's `style.filter` contains "drop-shadow(".
|
|
8
|
+
* - Light vs cyber themes use different shadow alpha (light tuned for
|
|
9
|
+
* contrast against white canvas; cyber for subtle depth on dark).
|
|
10
|
+
* Verify the strings differ so the theme switch isn't a no-op.
|
|
11
|
+
*/
|
|
12
|
+
import { chromium } from 'playwright';
|
|
13
|
+
import { readFileSync } from 'node:fs';
|
|
14
|
+
|
|
15
|
+
const TOKEN = JSON.parse(readFileSync('/home/vansin/.anet/config.json', 'utf8')).token;
|
|
16
|
+
const browser = await chromium.launch({ headless: true });
|
|
17
|
+
|
|
18
|
+
async function probe(theme) {
|
|
19
|
+
const ctx = await browser.newContext({ viewport: { width: 1280, height: 1500 } });
|
|
20
|
+
await ctx.addCookies([{ name: 'anet_dashboard_session', value: `v3:${TOKEN}`, domain: '127.0.0.1', path: '/' }]);
|
|
21
|
+
await ctx.addInitScript((t) => {
|
|
22
|
+
try {
|
|
23
|
+
localStorage.setItem('anet-theme', t);
|
|
24
|
+
localStorage.setItem('anet-topo-layout', 'ring');
|
|
25
|
+
sessionStorage.setItem('anet_v3_auth', '1');
|
|
26
|
+
} catch {}
|
|
27
|
+
}, theme);
|
|
28
|
+
const fresh = new Date(Date.now() - 60 * 1000).toISOString();
|
|
29
|
+
await ctx.route('**/api/hub/status*', async (route) => {
|
|
30
|
+
const r = await route.fetch();
|
|
31
|
+
const b = await r.json();
|
|
32
|
+
const nid = (b.sessions || [])[0]?.network_id || 'default';
|
|
33
|
+
const sessions = ['alpha', 'beta'].map(a => ({
|
|
34
|
+
alias: a, status: 'idle', network_id: nid, project_dir: null,
|
|
35
|
+
created_at: fresh, updated_at: fresh, last_seen_at: fresh,
|
|
36
|
+
}));
|
|
37
|
+
await route.fulfill({ response: r, json: { ...b, sessions } });
|
|
38
|
+
});
|
|
39
|
+
await ctx.route('**/api/hub/messages*', (route) => route.fulfill({ json: { messages: [] } }));
|
|
40
|
+
await ctx.route('**/api/hub/tasks*', (route) => route.fulfill({ json: { tasks: [] } }));
|
|
41
|
+
const page = await ctx.newPage();
|
|
42
|
+
await page.goto('http://127.0.0.1:3000/', { waitUntil: 'domcontentloaded' });
|
|
43
|
+
await page.waitForSelector('rect[data-topo-panel-elevation="recent"]', { timeout: 30000 });
|
|
44
|
+
await page.waitForTimeout(400);
|
|
45
|
+
const filters = await page.evaluate(() => {
|
|
46
|
+
const recent = document.querySelector('rect[data-topo-panel-elevation="recent"]');
|
|
47
|
+
const legend = document.querySelector('rect[data-topo-panel-elevation="legend"]');
|
|
48
|
+
return {
|
|
49
|
+
recent: recent?.getAttribute('style') || '',
|
|
50
|
+
legend: legend?.getAttribute('style') || '',
|
|
51
|
+
recentComputed: recent ? getComputedStyle(recent).filter : null,
|
|
52
|
+
legendComputed: legend ? getComputedStyle(legend).filter : null,
|
|
53
|
+
};
|
|
54
|
+
});
|
|
55
|
+
await ctx.close();
|
|
56
|
+
return filters;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const light = await probe('light');
|
|
60
|
+
const cyber = await probe('cyber');
|
|
61
|
+
await browser.close();
|
|
62
|
+
|
|
63
|
+
const hasShadow = (s) => /drop-shadow\(/.test(s || '');
|
|
64
|
+
const results = {
|
|
65
|
+
light_recent_hasShadow: hasShadow(light.recent),
|
|
66
|
+
light_legend_hasShadow: hasShadow(light.legend),
|
|
67
|
+
cyber_recent_hasShadow: hasShadow(cyber.recent),
|
|
68
|
+
cyber_legend_hasShadow: hasShadow(cyber.legend),
|
|
69
|
+
themes_differ: light.recent !== cyber.recent,
|
|
70
|
+
computed_resolves: hasShadow(light.recentComputed) && hasShadow(cyber.recentComputed),
|
|
71
|
+
};
|
|
72
|
+
const ok = Object.values(results).every(Boolean);
|
|
73
|
+
console.log(`${ok ? '✅' : '❌'} panel elevation:`, JSON.stringify(results),
|
|
74
|
+
`\n light.recent=${JSON.stringify(light.recent)}`,
|
|
75
|
+
`\n cyber.recent=${JSON.stringify(cyber.recent)}`);
|
|
76
|
+
process.exit(ok ? 0 : 1);
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/* Round 175 verification: corner panels fade-in after the
|
|
2
|
+
* canvas content reveal.
|
|
3
|
+
*
|
|
4
|
+
* Pre-R175 the recent-signal (top-left) + legend (top-right)
|
|
5
|
+
* panels appeared instantly while nodes/edges/group boxes/tier
|
|
6
|
+
* rings staggered in around them. The panels felt like 'already
|
|
7
|
+
* there' before the content showed up.
|
|
8
|
+
*
|
|
9
|
+
* R175 adds .anet-fade-in + 700ms / 800ms animation-delay on
|
|
10
|
+
* the two panel <g> wrappers — fifth surface in the first-paint
|
|
11
|
+
* reveal family (after R9 nodes / R172 edges / R173 group boxes
|
|
12
|
+
* / R174 tier rings).
|
|
13
|
+
*
|
|
14
|
+
* Test:
|
|
15
|
+
* 1. Mock 3 sessions in ring layout
|
|
16
|
+
* 2. Probe [data-topo-panel="recent"] and [="legend"]
|
|
17
|
+
* 3. Both have .anet-fade-in className
|
|
18
|
+
* 4. recent panel animationDelay = 700ms
|
|
19
|
+
* 5. legend panel animationDelay = 800ms
|
|
20
|
+
* 6. data-topo-panel-fade-delay attributes match
|
|
21
|
+
*/
|
|
22
|
+
import { chromium } from 'playwright';
|
|
23
|
+
import { readFileSync } from 'node:fs';
|
|
24
|
+
|
|
25
|
+
const TOKEN = JSON.parse(readFileSync('/home/vansin/.anet/config.json', 'utf8')).token;
|
|
26
|
+
const browser = await chromium.launch({ headless: true });
|
|
27
|
+
|
|
28
|
+
const ctx = await browser.newContext({ viewport: { width: 1500, height: 1500 } });
|
|
29
|
+
await ctx.addCookies([{ name: 'anet_dashboard_session', value: `v3:${TOKEN}`, domain: '127.0.0.1', path: '/' }]);
|
|
30
|
+
await ctx.addInitScript(() => {
|
|
31
|
+
try {
|
|
32
|
+
localStorage.setItem('anet-theme', 'cyber');
|
|
33
|
+
sessionStorage.setItem('anet_v3_auth', '1');
|
|
34
|
+
localStorage.setItem('anet-topo-layout', 'ring');
|
|
35
|
+
} catch {}
|
|
36
|
+
});
|
|
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: 'cli-claude-code',
|
|
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: [mk('alpha'), mk('beta'), mk('gamma')] } });
|
|
49
|
+
});
|
|
50
|
+
await ctx.route('**/api/hub/messages*', (route) => route.fulfill({ json: { messages: [] } }));
|
|
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 === 3, { timeout: 30000 });
|
|
56
|
+
await page.waitForSelector('[data-topo-panel="recent"]', { timeout: 10000 });
|
|
57
|
+
await page.waitForSelector('[data-topo-panel="legend"]', { timeout: 10000 });
|
|
58
|
+
await page.waitForTimeout(400);
|
|
59
|
+
|
|
60
|
+
const probe = await page.evaluate(() => {
|
|
61
|
+
const grab = (sel) => {
|
|
62
|
+
const el = document.querySelector(sel);
|
|
63
|
+
if (!el) return null;
|
|
64
|
+
return {
|
|
65
|
+
hasFadeClass: (el.getAttribute('class') || '').includes('anet-fade-in'),
|
|
66
|
+
fadeDelayAttr: parseFloat(el.getAttribute('data-topo-panel-fade-delay') || ''),
|
|
67
|
+
animationDelay: el.style.animationDelay || getComputedStyle(el).animationDelay,
|
|
68
|
+
};
|
|
69
|
+
};
|
|
70
|
+
return {
|
|
71
|
+
recent: grab('[data-topo-panel="recent"]'),
|
|
72
|
+
legend: grab('[data-topo-panel="legend"]'),
|
|
73
|
+
};
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
await browser.close();
|
|
77
|
+
|
|
78
|
+
const parseDelay = (s) => {
|
|
79
|
+
if (!s) return null;
|
|
80
|
+
if (s.endsWith('ms')) return parseFloat(s);
|
|
81
|
+
if (s.endsWith('s')) return parseFloat(s) * 1000;
|
|
82
|
+
return parseFloat(s);
|
|
83
|
+
};
|
|
84
|
+
const recentDelay = parseDelay(probe.recent?.animationDelay);
|
|
85
|
+
const legendDelay = parseDelay(probe.legend?.animationDelay);
|
|
86
|
+
|
|
87
|
+
const results = {
|
|
88
|
+
recent_panel_found: probe.recent !== null,
|
|
89
|
+
legend_panel_found: probe.legend !== null,
|
|
90
|
+
recent_has_fade_class: probe.recent?.hasFadeClass === true,
|
|
91
|
+
legend_has_fade_class: probe.legend?.hasFadeClass === true,
|
|
92
|
+
recent_delay_attr_700: probe.recent?.fadeDelayAttr === 700,
|
|
93
|
+
legend_delay_attr_800: probe.legend?.fadeDelayAttr === 800,
|
|
94
|
+
recent_anim_delay_700ms: recentDelay === 700,
|
|
95
|
+
legend_anim_delay_800ms: legendDelay === 800,
|
|
96
|
+
legend_lags_recent_100ms: legendDelay - recentDelay === 100,
|
|
97
|
+
};
|
|
98
|
+
const ok = Object.values(results).every(Boolean);
|
|
99
|
+
console.log(`${ok ? '✅' : '❌'} panel fade-in:`, JSON.stringify(results),
|
|
100
|
+
`\n recent =`, probe.recent, `delay=${recentDelay}`,
|
|
101
|
+
`\n legend =`, probe.legend, `delay=${legendDelay}`);
|
|
102
|
+
process.exit(ok ? 0 : 1);
|
|
@@ -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,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);
|