@sleep2agi/agent-network-dashboard 0.4.6-preview.35 → 0.4.6-preview.351
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 +41 -41
- 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/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/07lsi~s-c0wvh.css +2 -0
- package/.next/static/chunks/08kf-.bgs10ze.js +1 -0
- package/.next/static/chunks/0glmrdj9112tc.js +7 -0
- package/.next/static/chunks/0l_~q07bhpkcx.js +7 -0
- package/.next/static/chunks/0rxrez_cjn.eh.js +1 -0
- package/.next/static/chunks/0weo_f7lpbi4s.js +1 -0
- package/.next/static/chunks/0x6laek2zn7cp.js +4 -0
- package/.next/static/chunks/0x8x.29hkju5a.js +1 -0
- package/.next/static/chunks/0xphj8qvh3.wq.js +1 -0
- package/.next/static/chunks/174re5ar~kxne.js +1 -0
- package/.next/trace +2 -2
- package/.next/trace-build +1 -1
- package/.next/types/routes.d.ts +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/components/ChatPopover.tsx +38 -2
- package/app/components/CommandPalette.tsx +107 -0
- package/app/components/HelpOverlay.tsx +111 -1
- package/app/components/ServersDrawer.tsx +181 -5
- package/app/components/TopoGraph.tsx +6144 -254
- 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/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/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-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-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-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-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-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-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-hint-tracking-test.mjs +84 -0
- package/scripts/topo-empty-state-breath-test.mjs +150 -0
- package/scripts/topo-empty-state-crossfade-test.mjs +130 -0
- package/scripts/topo-empty-state-recenter-test.mjs +107 -0
- package/scripts/topo-empty-subhint-tracking-test.mjs +87 -0
- package/scripts/topo-endpoint-ring-fade-test.mjs +132 -0
- package/scripts/topo-endpoint-ring-test.mjs +93 -0
- package/scripts/topo-endpoint-ring-thicken-test.mjs +112 -0
- package/scripts/topo-esc-clears-pin-test.mjs +98 -0
- package/scripts/topo-filter-pill-aliases-test.mjs +121 -0
- package/scripts/topo-filter-pill-body-click-test.mjs +112 -0
- package/scripts/topo-filter-pill-count-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-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-chip-weight-test.mjs +87 -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/01nhr7-qa0bpn.js +0 -1
- package/.next/static/chunks/02t5jr4shh.hy.js +0 -1
- package/.next/static/chunks/0_qfg5s5uzs7..js +0 -7
- package/.next/static/chunks/0elalb9n_.~di.js +0 -1
- package/.next/static/chunks/0f2hte6kip4g2.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/0kwf..oq7.27x.js +0 -7
- package/.next/static/chunks/0o_7k8ylvvs__.js +0 -1
- package/.next/static/chunks/0r4q73.-1bkyl.js +0 -1
- package/.next/static/chunks/0r_c8eccg3z2o.js +0 -1
- package/.next/static/chunks/10oi7l-tycgl9.js +0 -1
- package/.next/static/chunks/11uk1izuv3~0t.js +0 -1
- package/.next/static/chunks/13.zti9ix.1eh.css +0 -2
- /package/.next/static/{2mfVL5BX6WSYKSYcpYe9i → -fpmZJB0LShWZUodmIvd5}/_buildManifest.js +0 -0
- /package/.next/static/{2mfVL5BX6WSYKSYcpYe9i → -fpmZJB0LShWZUodmIvd5}/_clientMiddlewareManifest.js +0 -0
- /package/.next/static/{2mfVL5BX6WSYKSYcpYe9i → -fpmZJB0LShWZUodmIvd5}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/* Round 318 verification: chrome segmented-control ACTIVE button
|
|
2
|
+
* gains font-medium (500) — visual weight emphasis layered on top
|
|
3
|
+
* of the existing cyan-300 color + cyan-500/15 background. The
|
|
4
|
+
* polish broadened across all four chrome control families that
|
|
5
|
+
* share the same active-state class string:
|
|
6
|
+
* - Layout toggle (Ring / Grid) — bottom-right
|
|
7
|
+
* - nodeSize segmented (S / M / L) — bottom-right
|
|
8
|
+
* - Fullscreen toggle — top-right (single button, isFullscreen
|
|
9
|
+
* branch is its "active" state)
|
|
10
|
+
*
|
|
11
|
+
* Direction: R313/R314/R315 established font-medium as the data-
|
|
12
|
+
* weight chip family. R318 extends the same weight tier to chrome
|
|
13
|
+
* control ACTIVE states so the currently-selected option carries
|
|
14
|
+
* stronger visual prominence than just color alone.
|
|
15
|
+
*
|
|
16
|
+
* Contract:
|
|
17
|
+
* - The active Layout toggle button has className containing
|
|
18
|
+
* 'font-medium'.
|
|
19
|
+
* - The inactive Layout toggle button does NOT have font-medium
|
|
20
|
+
* in its class string (still default 400).
|
|
21
|
+
* - Computed font-weight of active button === 500.
|
|
22
|
+
* - R317 inactive gray-400 + R316 brand-logo width=40 + R313
|
|
23
|
+
* chip-row weight + R294 pulse absent all preserved.
|
|
24
|
+
*/
|
|
25
|
+
import { chromium } from 'playwright';
|
|
26
|
+
import { readFileSync } from 'node:fs';
|
|
27
|
+
|
|
28
|
+
const TOKEN = JSON.parse(readFileSync('/home/vansin/.anet/config.json', 'utf8')).token;
|
|
29
|
+
const browser = await chromium.launch({ headless: true });
|
|
30
|
+
const ctx = await browser.newContext({ viewport: { width: 1500, height: 1500 } });
|
|
31
|
+
await ctx.addCookies([{ name: 'anet_dashboard_session', value: `v3:${TOKEN}`, domain: '127.0.0.1', path: '/' }]);
|
|
32
|
+
await ctx.addInitScript(() => {
|
|
33
|
+
try {
|
|
34
|
+
localStorage.setItem('anet-theme', 'cyber');
|
|
35
|
+
sessionStorage.setItem('anet_v3_auth', '1');
|
|
36
|
+
// Force ring layout so Ring is the active button.
|
|
37
|
+
localStorage.setItem('anet-topo-layout', 'ring');
|
|
38
|
+
} catch {}
|
|
39
|
+
});
|
|
40
|
+
const fresh = new Date(Date.now() - 60 * 1000).toISOString();
|
|
41
|
+
await ctx.route('**/api/hub/status*', async (route) => {
|
|
42
|
+
const r = await route.fetch();
|
|
43
|
+
const b = await r.json();
|
|
44
|
+
const nid = (b.sessions || [])[0]?.network_id || 'default';
|
|
45
|
+
const mk = (alias, model) => ({
|
|
46
|
+
alias, status: 'working', model, runtime: 'claude-code-cli',
|
|
47
|
+
network_id: nid, project_dir: null,
|
|
48
|
+
created_at: fresh, updated_at: fresh, last_seen_at: fresh,
|
|
49
|
+
});
|
|
50
|
+
await route.fulfill({ response: r, json: { ...b, sessions: [
|
|
51
|
+
mk('alpha', 'claude-opus-4'),
|
|
52
|
+
mk('beta', 'gpt-4o'),
|
|
53
|
+
] } });
|
|
54
|
+
});
|
|
55
|
+
await ctx.route('**/api/hub/messages*', (r) => r.fulfill({ json: { messages: [] } }));
|
|
56
|
+
await ctx.route('**/api/hub/tasks*', (r) => r.fulfill({ json: { tasks: [] } }));
|
|
57
|
+
|
|
58
|
+
const page = await ctx.newPage();
|
|
59
|
+
await page.goto('http://127.0.0.1:3000/', { waitUntil: 'domcontentloaded' });
|
|
60
|
+
await page.waitForSelector('[data-topo-chrome-layout="ring"]', { timeout: 15000 });
|
|
61
|
+
await page.waitForTimeout(400);
|
|
62
|
+
|
|
63
|
+
const probe = await page.evaluate(() => {
|
|
64
|
+
const sel = (s) => document.querySelector(s);
|
|
65
|
+
const ringBtn = sel('[data-topo-chrome-layout="ring"]');
|
|
66
|
+
const gridBtn = sel('[data-topo-chrome-layout="grid"]');
|
|
67
|
+
const logo = sel('[data-topo-brand-logo]');
|
|
68
|
+
return {
|
|
69
|
+
ringActive: ringBtn?.getAttribute('data-topo-chrome-layout-active') === 'true',
|
|
70
|
+
gridActive: gridBtn?.getAttribute('data-topo-chrome-layout-active') === 'true',
|
|
71
|
+
ringCls: ringBtn?.className ?? '',
|
|
72
|
+
gridCls: gridBtn?.className ?? '',
|
|
73
|
+
ringFw: ringBtn ? getComputedStyle(ringBtn).fontWeight : null,
|
|
74
|
+
gridFw: gridBtn ? getComputedStyle(gridBtn).fontWeight : null,
|
|
75
|
+
brandLogoW: logo?.getAttribute('width') ?? null,
|
|
76
|
+
workingChipCls: sel('[data-working-chip]')?.className ?? '',
|
|
77
|
+
pulseCount: document.querySelectorAll('[data-pulse-wrapper]').length,
|
|
78
|
+
};
|
|
79
|
+
});
|
|
80
|
+
await browser.close();
|
|
81
|
+
|
|
82
|
+
const activeCls = probe.ringActive ? probe.ringCls : probe.gridCls;
|
|
83
|
+
const inactiveCls = probe.ringActive ? probe.gridCls : probe.ringCls;
|
|
84
|
+
const activeFw = probe.ringActive ? probe.ringFw : probe.gridFw;
|
|
85
|
+
|
|
86
|
+
const results = {
|
|
87
|
+
exactly_one_active: probe.ringActive !== probe.gridActive,
|
|
88
|
+
active_has_font_medium: activeCls.includes('font-medium'),
|
|
89
|
+
inactive_no_font_medium: !inactiveCls.includes('font-medium'),
|
|
90
|
+
active_fw_500: String(activeFw) === '500',
|
|
91
|
+
// R317 regression: inactive still gray-400.
|
|
92
|
+
r317_inactive_gray_400: inactiveCls.includes('text-gray-400'),
|
|
93
|
+
// R316 brand-logo width=40 regression.
|
|
94
|
+
r316_brand_logo_width_40: probe.brandLogoW === '40',
|
|
95
|
+
// R313 chip-row data weight regression.
|
|
96
|
+
r313_working_chip_kept: probe.workingChipCls.includes('font-medium'),
|
|
97
|
+
// R294 pulse absent regression.
|
|
98
|
+
r294_pulse_absent: probe.pulseCount === 0,
|
|
99
|
+
};
|
|
100
|
+
const ok = Object.values(results).every(Boolean);
|
|
101
|
+
console.log(`${ok ? '✅' : '❌'} chrome active weight:`, JSON.stringify(results),
|
|
102
|
+
'\n ring active:', probe.ringActive, ' grid active:', probe.gridActive,
|
|
103
|
+
'\n active fw:', activeFw, ' inactive fw:', probe.ringActive ? probe.gridFw : probe.ringFw);
|
|
104
|
+
process.exit(ok ? 0 : 1);
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/* Round 306 verification: Layout toggle (Ring/Grid) focus-visible:
|
|
2
|
+
* ring-2 → ring-1 unifies focus-ring width across all chrome
|
|
3
|
+
* buttons. Pre-R306 Layout toggle was the only chrome button at
|
|
4
|
+
* 2px; nodeSize, zoom, reset, fullscreen all at 1px.
|
|
5
|
+
*
|
|
6
|
+
* Test approach: tab/focus each chrome button via DOM-direct
|
|
7
|
+
* focus() + check the computed outline / box-shadow width. The
|
|
8
|
+
* focus-visible CSS only matches keyboard-style focus, so we
|
|
9
|
+
* dispatch keyboard focus to trigger the focus-visible state.
|
|
10
|
+
*
|
|
11
|
+
* Contract:
|
|
12
|
+
* - All chrome buttons (Layout Ring + Grid, nodeSize S+M+L,
|
|
13
|
+
* zoom-out + zoom-in, reset, fullscreen) share the same
|
|
14
|
+
* focus-visible ring style: 1px (or equivalent).
|
|
15
|
+
* - The R305 node-alias chat-pin signature is unchanged.
|
|
16
|
+
* - R304/R302/R301/R300/R294 regressions intact.
|
|
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
|
+
const ctx = await browser.newContext({ viewport: { width: 1500, height: 1500 } });
|
|
24
|
+
await ctx.addCookies([{ name: 'anet_dashboard_session', value: `v3:${TOKEN}`, domain: '127.0.0.1', path: '/' }]);
|
|
25
|
+
await ctx.addInitScript(() => {
|
|
26
|
+
try { localStorage.setItem('anet-theme', 'cyber'); sessionStorage.setItem('anet_v3_auth', '1'); } catch {}
|
|
27
|
+
});
|
|
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 mk = (alias, model) => ({
|
|
34
|
+
alias, status: 'working', model, runtime: 'claude-code-cli',
|
|
35
|
+
network_id: nid, project_dir: null,
|
|
36
|
+
created_at: fresh, updated_at: fresh, last_seen_at: fresh,
|
|
37
|
+
});
|
|
38
|
+
await route.fulfill({ response: r, json: { ...b, sessions: [
|
|
39
|
+
mk('alpha', 'claude-opus-4'),
|
|
40
|
+
mk('beta', 'gpt-4o'),
|
|
41
|
+
] } });
|
|
42
|
+
});
|
|
43
|
+
await ctx.route('**/api/hub/messages*', (r) => r.fulfill({ json: { messages: [] } }));
|
|
44
|
+
await ctx.route('**/api/hub/tasks*', (r) => r.fulfill({ json: { tasks: [] } }));
|
|
45
|
+
|
|
46
|
+
const page = await ctx.newPage();
|
|
47
|
+
await page.goto('http://127.0.0.1:3000/', { waitUntil: 'domcontentloaded' });
|
|
48
|
+
await page.waitForSelector('[data-topo-chrome-layout="ring"]', { timeout: 15000 });
|
|
49
|
+
await page.waitForSelector('[data-topo-chrome-fullscreen]', { timeout: 5000 });
|
|
50
|
+
await page.waitForTimeout(300);
|
|
51
|
+
|
|
52
|
+
// Probe the source-of-truth: Tailwind compiles `focus-visible:ring-N`
|
|
53
|
+
// into class names; we read className strings rather than triggering
|
|
54
|
+
// focus-visible state (which requires keyboard input simulation).
|
|
55
|
+
const probe = await page.evaluate(() => {
|
|
56
|
+
const sel = (s) => document.querySelector(s);
|
|
57
|
+
const cls = (el) => el?.className ?? '';
|
|
58
|
+
// Tailwind compiles `focus-visible:ring-N` literally in the className
|
|
59
|
+
// string; checking presence of `focus-visible:ring-1` vs `ring-2`.
|
|
60
|
+
const has = (s, needle) => cls(sel(s)).includes(needle);
|
|
61
|
+
return {
|
|
62
|
+
layoutRing_ring1: has('[data-topo-chrome-layout="ring"]', 'focus-visible:ring-1'),
|
|
63
|
+
layoutRing_no_ring2: !has('[data-topo-chrome-layout="ring"]', 'focus-visible:ring-2'),
|
|
64
|
+
layoutGrid_ring1: has('[data-topo-chrome-layout="grid"]', 'focus-visible:ring-1'),
|
|
65
|
+
layoutGrid_no_ring2: !has('[data-topo-chrome-layout="grid"]', 'focus-visible:ring-2'),
|
|
66
|
+
nodesizeS_ring1: has('[data-topo-chrome-nodesize="S"]', 'focus-visible:ring-1'),
|
|
67
|
+
fullscreen_ring1: has('[data-topo-chrome-fullscreen]', 'focus-visible:ring-1'),
|
|
68
|
+
zoomIn_ring1: has('[data-topo-chrome-zoom-in]', 'focus-visible:ring-1'),
|
|
69
|
+
aliasChatTargetAttrPresent: (() => {
|
|
70
|
+
const a = sel('[data-node-alias-text]');
|
|
71
|
+
return a?.hasAttribute('data-node-alias-chat-target') ?? false;
|
|
72
|
+
})(),
|
|
73
|
+
subhintLs: sel('[data-recent-signal-empty-hint]')?.getAttribute('letter-spacing') ?? null,
|
|
74
|
+
emptyLs: sel('[data-recent-signal-empty]')?.getAttribute('letter-spacing') ?? null,
|
|
75
|
+
kickerFw: (() => {
|
|
76
|
+
const k = sel('[data-topo-section-kicker]');
|
|
77
|
+
return k ? getComputedStyle(k).fontWeight : null;
|
|
78
|
+
})(),
|
|
79
|
+
pulseCount: document.querySelectorAll('[data-pulse-wrapper]').length,
|
|
80
|
+
};
|
|
81
|
+
});
|
|
82
|
+
await browser.close();
|
|
83
|
+
|
|
84
|
+
const results = {
|
|
85
|
+
layout_ring_ring_1: probe.layoutRing_ring1,
|
|
86
|
+
layout_ring_no_ring_2: probe.layoutRing_no_ring2,
|
|
87
|
+
layout_grid_ring_1: probe.layoutGrid_ring1,
|
|
88
|
+
layout_grid_no_ring_2: probe.layoutGrid_no_ring2,
|
|
89
|
+
nodesize_S_ring_1: probe.nodesizeS_ring1,
|
|
90
|
+
fullscreen_ring_1: probe.fullscreen_ring1,
|
|
91
|
+
zoom_in_ring_1: probe.zoomIn_ring1,
|
|
92
|
+
r305_alias_chat_target_attr: probe.aliasChatTargetAttrPresent,
|
|
93
|
+
r304_subhint_ls_0_15: probe.subhintLs === '0.15',
|
|
94
|
+
r302_empty_main_ls_0_2: probe.emptyLs === '0.2',
|
|
95
|
+
r300_kicker_fw_500: String(probe.kickerFw) === '500',
|
|
96
|
+
r294_pulse_absent: probe.pulseCount === 0,
|
|
97
|
+
};
|
|
98
|
+
const ok = Object.values(results).every(Boolean);
|
|
99
|
+
console.log(`${ok ? '✅' : '❌'} chrome focus ring unify:`, JSON.stringify(results));
|
|
100
|
+
process.exit(ok ? 0 : 1);
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/* Round 288 verification: chrome strip icon strokeWidth unification.
|
|
2
|
+
*
|
|
3
|
+
* Pre-R288 the five chrome icons in the bottom-right strip carried
|
|
4
|
+
* two different stroke weights:
|
|
5
|
+
* zoom-in : strokeWidth 2.5
|
|
6
|
+
* zoom-out : strokeWidth 2.5
|
|
7
|
+
* reset : strokeWidth 2 ← outlier
|
|
8
|
+
* fullscreen : strokeWidth 2 ← outlier
|
|
9
|
+
* Operators reading the strip horizontally saw zoom icons rendering
|
|
10
|
+
* heavier than their reset/fullscreen siblings — same inconsistency
|
|
11
|
+
* R268 closed for chrome border colors.
|
|
12
|
+
*
|
|
13
|
+
* Post-R288: all five icons render at strokeWidth 2.5.
|
|
14
|
+
*
|
|
15
|
+
* Test scope:
|
|
16
|
+
* 1. zoom-in/zoom-out icons retain 2.5 (regression — no change).
|
|
17
|
+
* 2. reset icon stroke-width === '2.5'.
|
|
18
|
+
* 3. fullscreen icon (whichever variant rendered) stroke-width === '2.5'.
|
|
19
|
+
* 4. R287 minimap rect strokeWidth=1.5 still in place.
|
|
20
|
+
* 5. R283 monogram stroke + R282 watermark intact.
|
|
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
|
+
const ctx = await browser.newContext({ viewport: { width: 1500, height: 1500 } });
|
|
28
|
+
await ctx.addCookies([{ name: 'anet_dashboard_session', value: `v3:${TOKEN}`, domain: '127.0.0.1', path: '/' }]);
|
|
29
|
+
await ctx.addInitScript(() => {
|
|
30
|
+
try { localStorage.setItem('anet-theme', 'cyber'); sessionStorage.setItem('anet_v3_auth', '1'); } catch {}
|
|
31
|
+
});
|
|
32
|
+
const fresh = new Date(Date.now() - 60 * 1000).toISOString();
|
|
33
|
+
await ctx.route('**/api/hub/status*', async (route) => {
|
|
34
|
+
const r = await route.fetch();
|
|
35
|
+
const b = await r.json();
|
|
36
|
+
const nid = (b.sessions || [])[0]?.network_id || 'default';
|
|
37
|
+
const mk = (alias, model) => ({
|
|
38
|
+
alias, status: 'working', model, runtime: 'claude-code-cli',
|
|
39
|
+
network_id: nid, project_dir: null,
|
|
40
|
+
created_at: fresh, updated_at: fresh, last_seen_at: fresh,
|
|
41
|
+
});
|
|
42
|
+
await route.fulfill({ response: r, json: { ...b, sessions: [
|
|
43
|
+
mk('alpha', 'claude-opus-4'),
|
|
44
|
+
mk('beta', 'gpt-4o'),
|
|
45
|
+
] } });
|
|
46
|
+
});
|
|
47
|
+
await ctx.route('**/api/hub/messages*', (r) => r.fulfill({ json: { messages: [] } }));
|
|
48
|
+
await ctx.route('**/api/hub/tasks*', (r) => r.fulfill({ json: { tasks: [] } }));
|
|
49
|
+
|
|
50
|
+
const page = await ctx.newPage();
|
|
51
|
+
await page.goto('http://127.0.0.1:3000/', { waitUntil: 'domcontentloaded' });
|
|
52
|
+
await page.waitForSelector('[data-topo-chrome-zoom-in-icon]', { timeout: 15000 });
|
|
53
|
+
await page.waitForSelector('[data-topo-brand-watermark]', { timeout: 10000 });
|
|
54
|
+
await page.waitForTimeout(300);
|
|
55
|
+
|
|
56
|
+
const probe = await page.evaluate(() => {
|
|
57
|
+
const zin = document.querySelector('[data-topo-chrome-zoom-in-icon]');
|
|
58
|
+
const zout = document.querySelector('[data-topo-chrome-zoom-out-icon]');
|
|
59
|
+
const reset = document.querySelector('[data-topo-chrome-reset-icon]');
|
|
60
|
+
const fs = document.querySelector('[data-topo-chrome-fullscreen-icon]');
|
|
61
|
+
const alphaNode = document.querySelector('g[data-node="alpha"]');
|
|
62
|
+
const alphaCircles = alphaNode ? [...alphaNode.querySelectorAll('circle')] : [];
|
|
63
|
+
const alphaAvatarCircle = alphaCircles
|
|
64
|
+
.map(c => ({ r: +c.getAttribute('r') || 0, sw: c.getAttribute('stroke-width'), isBadge: c.hasAttribute('data-runtime-badge') }))
|
|
65
|
+
.filter(c => c.r > 0 && c.r < 18 && !c.isBadge)
|
|
66
|
+
.sort((a, b) => b.r - a.r)[0];
|
|
67
|
+
const watermark = document.querySelector('[data-topo-brand-watermark]');
|
|
68
|
+
return {
|
|
69
|
+
zinStroke: zin?.getAttribute('stroke-width') ?? null,
|
|
70
|
+
zoutStroke: zout?.getAttribute('stroke-width') ?? null,
|
|
71
|
+
resetStroke: reset?.getAttribute('stroke-width') ?? null,
|
|
72
|
+
fsStroke: fs?.getAttribute('stroke-width') ?? null,
|
|
73
|
+
fsVariant: fs?.getAttribute('data-topo-chrome-fullscreen-icon') ?? null,
|
|
74
|
+
alphaAvatarStroke: alphaAvatarCircle?.sw ?? null,
|
|
75
|
+
watermarkPresent: watermark !== null,
|
|
76
|
+
};
|
|
77
|
+
});
|
|
78
|
+
await browser.close();
|
|
79
|
+
|
|
80
|
+
const results = {
|
|
81
|
+
zoom_in_stroke_2_5: probe.zinStroke === '2.5',
|
|
82
|
+
zoom_out_stroke_2_5: probe.zoutStroke === '2.5',
|
|
83
|
+
reset_stroke_2_5: probe.resetStroke === '2.5',
|
|
84
|
+
fullscreen_stroke_2_5: probe.fsStroke === '2.5',
|
|
85
|
+
fullscreen_variant_set: probe.fsVariant === 'enter' || probe.fsVariant === 'exit',
|
|
86
|
+
r283_monogram_stroke_kept: probe.alphaAvatarStroke === '1.5',
|
|
87
|
+
r282_watermark_present: probe.watermarkPresent,
|
|
88
|
+
};
|
|
89
|
+
const ok = Object.values(results).every(Boolean);
|
|
90
|
+
console.log(`${ok ? '✅' : '❌'} chrome icon stroke unify:`, JSON.stringify(results),
|
|
91
|
+
'\n zoom-in: ', probe.zinStroke,
|
|
92
|
+
'\n zoom-out: ', probe.zoutStroke,
|
|
93
|
+
'\n reset: ', probe.resetStroke,
|
|
94
|
+
'\n fullscreen: ', probe.fsStroke, `(variant: ${probe.fsVariant})`);
|
|
95
|
+
process.exit(ok ? 0 : 1);
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/* Round 317 verification: chrome strip Layout toggle inactive text
|
|
2
|
+
* color from `text-gray-500` → `text-gray-400`. Same R296 direction
|
|
3
|
+
* (kicker 600→500) extended to chrome control inactive text — more
|
|
4
|
+
* visible but still subordinate to active cyan-300.
|
|
5
|
+
*
|
|
6
|
+
* Contract:
|
|
7
|
+
* - [data-topo-chrome-layout='ring'] when INACTIVE has className
|
|
8
|
+
* containing 'text-gray-400' (not 'text-gray-500').
|
|
9
|
+
* - [data-topo-chrome-layout='grid'] same when inactive.
|
|
10
|
+
* - At least one of Ring/Grid is inactive (only one is layout-
|
|
11
|
+
* active at a time).
|
|
12
|
+
* - R316 brand-logo width=40 + R315 freshness chip + R313/R314
|
|
13
|
+
* chip-row data weight + R294 pulse absent all preserved.
|
|
14
|
+
*/
|
|
15
|
+
import { chromium } from 'playwright';
|
|
16
|
+
import { readFileSync } from 'node:fs';
|
|
17
|
+
|
|
18
|
+
const TOKEN = JSON.parse(readFileSync('/home/vansin/.anet/config.json', 'utf8')).token;
|
|
19
|
+
const browser = await chromium.launch({ headless: true });
|
|
20
|
+
const ctx = await browser.newContext({ viewport: { width: 1500, height: 1500 } });
|
|
21
|
+
await ctx.addCookies([{ name: 'anet_dashboard_session', value: `v3:${TOKEN}`, domain: '127.0.0.1', path: '/' }]);
|
|
22
|
+
await ctx.addInitScript(() => {
|
|
23
|
+
// Force ring layout so grid will be inactive.
|
|
24
|
+
try {
|
|
25
|
+
localStorage.setItem('anet-theme', 'cyber');
|
|
26
|
+
sessionStorage.setItem('anet_v3_auth', '1');
|
|
27
|
+
localStorage.setItem('anet-topo-layout', 'ring');
|
|
28
|
+
} 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, model) => ({
|
|
36
|
+
alias, status: 'working', model, 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', 'claude-opus-4'),
|
|
42
|
+
mk('beta', 'gpt-4o'),
|
|
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.waitForSelector('[data-topo-chrome-layout="ring"]', { timeout: 15000 });
|
|
51
|
+
await page.waitForTimeout(400);
|
|
52
|
+
|
|
53
|
+
const probe = await page.evaluate(() => {
|
|
54
|
+
const sel = (s) => document.querySelector(s);
|
|
55
|
+
const ringBtn = sel('[data-topo-chrome-layout="ring"]');
|
|
56
|
+
const gridBtn = sel('[data-topo-chrome-layout="grid"]');
|
|
57
|
+
const logo = sel('[data-topo-brand-logo]');
|
|
58
|
+
return {
|
|
59
|
+
ringActive: ringBtn?.getAttribute('data-topo-chrome-layout-active') === 'true',
|
|
60
|
+
gridActive: gridBtn?.getAttribute('data-topo-chrome-layout-active') === 'true',
|
|
61
|
+
ringCls: ringBtn?.className ?? '',
|
|
62
|
+
gridCls: gridBtn?.className ?? '',
|
|
63
|
+
brandLogoW: logo?.getAttribute('width') ?? null,
|
|
64
|
+
workingChipCls: sel('[data-working-chip]')?.className ?? '',
|
|
65
|
+
pulseCount: document.querySelectorAll('[data-pulse-wrapper]').length,
|
|
66
|
+
};
|
|
67
|
+
});
|
|
68
|
+
await browser.close();
|
|
69
|
+
|
|
70
|
+
// The inactive button should have gray-400 (not gray-500). The
|
|
71
|
+
// active button uses text-cyan-300 (no gray class), so checking
|
|
72
|
+
// 'text-gray-400' is meaningful only for inactive.
|
|
73
|
+
const inactiveCls = probe.ringActive ? probe.gridCls : probe.ringCls;
|
|
74
|
+
const activeCls = probe.ringActive ? probe.ringCls : probe.gridCls;
|
|
75
|
+
|
|
76
|
+
const results = {
|
|
77
|
+
exactly_one_active: probe.ringActive !== probe.gridActive,
|
|
78
|
+
inactive_has_gray_400: inactiveCls.includes('text-gray-400'),
|
|
79
|
+
inactive_no_gray_500: !inactiveCls.includes('text-gray-500'),
|
|
80
|
+
active_has_cyan_300: activeCls.includes('text-cyan-300'),
|
|
81
|
+
r316_brand_logo_width_40: probe.brandLogoW === '40',
|
|
82
|
+
r313_working_chip_kept: probe.workingChipCls.includes('font-medium'),
|
|
83
|
+
r294_pulse_absent: probe.pulseCount === 0,
|
|
84
|
+
};
|
|
85
|
+
const ok = Object.values(results).every(Boolean);
|
|
86
|
+
console.log(`${ok ? '✅' : '❌'} chrome inactive color:`, JSON.stringify(results),
|
|
87
|
+
'\n ring active:', probe.ringActive, ' grid active:', probe.gridActive,
|
|
88
|
+
'\n inactive cls subset:', inactiveCls.match(/text-(gray|cyan)-\d+/g),
|
|
89
|
+
'\n active cls subset:', activeCls.match(/text-(gray|cyan)-\d+/g));
|
|
90
|
+
process.exit(ok ? 0 : 1);
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/* Round 249 verification: chrome-pop click animation extends from
|
|
2
|
+
* the existing zoom-in/zoom-out pair to ring/grid layout toggle +
|
|
3
|
+
* fullscreen buttons. Whole chrome strip now speaks one click
|
|
4
|
+
* vocabulary instead of zoom-only-pops + silent-everything-else.
|
|
5
|
+
*
|
|
6
|
+
* Per button, on click:
|
|
7
|
+
* data-topo-chrome-{key}-popping flips 'false' → 'true' for ~240ms
|
|
8
|
+
* className gains 'anet-chrome-pop' for the same window
|
|
9
|
+
*
|
|
10
|
+
* Test scope:
|
|
11
|
+
* - Ring layout button: click → data-topo-chrome-layout-ring-popping='true' (within 100ms)
|
|
12
|
+
* - Grid layout button: click → data-topo-chrome-layout-grid-popping='true'
|
|
13
|
+
* - Fullscreen button: click → data-topo-chrome-fullscreen-popping='true'
|
|
14
|
+
*
|
|
15
|
+
* Hard-to-test trap: chromePopping is transient (240ms TTL). Probe
|
|
16
|
+
* immediately after Playwright click resolves. Wait full 240ms after
|
|
17
|
+
* for the second probe — must be 'false' again.
|
|
18
|
+
*/
|
|
19
|
+
import { chromium } from 'playwright';
|
|
20
|
+
import { readFileSync } from 'node:fs';
|
|
21
|
+
|
|
22
|
+
const TOKEN = JSON.parse(readFileSync('/home/vansin/.anet/config.json', 'utf8')).token;
|
|
23
|
+
const browser = await chromium.launch({ headless: true });
|
|
24
|
+
const ctx = await browser.newContext({ viewport: { width: 1500, height: 1500 } });
|
|
25
|
+
await ctx.addCookies([{ name: 'anet_dashboard_session', value: `v3:${TOKEN}`, domain: '127.0.0.1', path: '/' }]);
|
|
26
|
+
await ctx.addInitScript(() => {
|
|
27
|
+
try { localStorage.setItem('anet-theme', 'cyber'); sessionStorage.setItem('anet_v3_auth', '1'); } catch {}
|
|
28
|
+
});
|
|
29
|
+
const fresh = new Date(Date.now() - 60 * 1000).toISOString();
|
|
30
|
+
await ctx.route('**/api/hub/status*', async (route) => {
|
|
31
|
+
const r = await route.fetch();
|
|
32
|
+
const b = await r.json();
|
|
33
|
+
const nid = (b.sessions || [])[0]?.network_id || 'default';
|
|
34
|
+
const mk = (alias) => ({
|
|
35
|
+
alias, status: 'working', model: 'claude-opus-4', runtime: 'claude-code-cli',
|
|
36
|
+
network_id: nid, project_dir: null,
|
|
37
|
+
created_at: fresh, updated_at: fresh, last_seen_at: fresh,
|
|
38
|
+
});
|
|
39
|
+
await route.fulfill({ response: r, json: { ...b, sessions: [
|
|
40
|
+
mk('alpha'), mk('beta'), mk('gamma'), mk('delta'),
|
|
41
|
+
] } });
|
|
42
|
+
});
|
|
43
|
+
await ctx.route('**/api/hub/messages*', (r2) => r2.fulfill({ json: { messages: [] } }));
|
|
44
|
+
await ctx.route('**/api/hub/tasks*', (r2) => r2.fulfill({ json: { tasks: [] } }));
|
|
45
|
+
|
|
46
|
+
const page = await ctx.newPage();
|
|
47
|
+
await page.goto('http://127.0.0.1:3000/', { waitUntil: 'domcontentloaded' });
|
|
48
|
+
await page.waitForFunction(() => document.querySelectorAll('g[data-node]').length === 4, { timeout: 30000 });
|
|
49
|
+
await page.waitForSelector('[data-topo-chrome-layout="ring"]', { timeout: 10000 });
|
|
50
|
+
await page.waitForSelector('[data-topo-chrome-fullscreen]', { timeout: 10000 });
|
|
51
|
+
await page.waitForTimeout(300);
|
|
52
|
+
|
|
53
|
+
const testButton = async (clickSelector, poppingAttr, label) => {
|
|
54
|
+
// Click + immediately read state. The chromePopping setState is
|
|
55
|
+
// synchronous within the click handler, so the DOM should reflect
|
|
56
|
+
// 'true' on the next React commit (very soon after click resolves).
|
|
57
|
+
await page.locator(clickSelector).click();
|
|
58
|
+
// Probe quickly — within the 240ms window
|
|
59
|
+
await page.waitForTimeout(50);
|
|
60
|
+
const duringPop = await page.locator(clickSelector).getAttribute(poppingAttr);
|
|
61
|
+
const classDuring = await page.locator(clickSelector).getAttribute('class');
|
|
62
|
+
// Wait for the pop to clear
|
|
63
|
+
await page.waitForTimeout(300);
|
|
64
|
+
const afterPop = await page.locator(clickSelector).getAttribute(poppingAttr);
|
|
65
|
+
const classAfter = await page.locator(clickSelector).getAttribute('class');
|
|
66
|
+
return {
|
|
67
|
+
label,
|
|
68
|
+
duringAttr: duringPop,
|
|
69
|
+
duringClass: /anet-chrome-pop/.test(classDuring || ''),
|
|
70
|
+
afterAttr: afterPop,
|
|
71
|
+
afterClass: /anet-chrome-pop/.test(classAfter || ''),
|
|
72
|
+
};
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
const ring = await testButton('[data-topo-chrome-layout="ring"]', 'data-topo-chrome-layout-ring-popping', 'ring');
|
|
76
|
+
const grid = await testButton('[data-topo-chrome-layout="grid"]', 'data-topo-chrome-layout-grid-popping', 'grid');
|
|
77
|
+
// For fullscreen, browser context may not honour requestFullscreen in
|
|
78
|
+
// headless mode — wrap in try/catch on the page side. Test only the
|
|
79
|
+
// data attr + className.
|
|
80
|
+
const fullscreen = await testButton('[data-topo-chrome-fullscreen]', 'data-topo-chrome-fullscreen-popping', 'fullscreen');
|
|
81
|
+
|
|
82
|
+
await browser.close();
|
|
83
|
+
|
|
84
|
+
const ok_each = (b) =>
|
|
85
|
+
b.duringAttr === 'true' && b.duringClass === true &&
|
|
86
|
+
b.afterAttr === 'false' && b.afterClass === false;
|
|
87
|
+
|
|
88
|
+
const results = {
|
|
89
|
+
ring_pops_on_click: ok_each(ring),
|
|
90
|
+
grid_pops_on_click: ok_each(grid),
|
|
91
|
+
fullscreen_pops_on_click: ok_each(fullscreen),
|
|
92
|
+
};
|
|
93
|
+
const ok = Object.values(results).every(Boolean);
|
|
94
|
+
console.log(`${ok ? '✅' : '❌'} chrome-pop extension:`, JSON.stringify(results),
|
|
95
|
+
'\n ring: ', ring,
|
|
96
|
+
'\n grid: ', grid,
|
|
97
|
+
'\n fullscreen:', fullscreen);
|
|
98
|
+
process.exit(ok ? 0 : 1);
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/* Round 250 verification: nodeSize S/M/L buttons close the chrome-
|
|
2
|
+
* pop click-feedback family. Every clickable chrome button now fires
|
|
3
|
+
* the R186 .anet-chrome-pop 220ms scale-pulse on release.
|
|
4
|
+
*
|
|
5
|
+
* R171 nodeSizeSwitching canvas crossfade still masks the radius
|
|
6
|
+
* change at the global scope; R250 chrome-pop adds the LOCAL
|
|
7
|
+
* button-level click confirmation.
|
|
8
|
+
*
|
|
9
|
+
* Test scope: click each of S/M/L → within 50ms data-topo-chrome-
|
|
10
|
+
* nodesize-popping='true' + className contains 'anet-chrome-pop'.
|
|
11
|
+
* After 300ms both clear.
|
|
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
|
+
const ctx = await browser.newContext({ viewport: { width: 1500, height: 1500 } });
|
|
19
|
+
await ctx.addCookies([{ name: 'anet_dashboard_session', value: `v3:${TOKEN}`, domain: '127.0.0.1', path: '/' }]);
|
|
20
|
+
await ctx.addInitScript(() => {
|
|
21
|
+
try { localStorage.setItem('anet-theme', 'cyber'); sessionStorage.setItem('anet_v3_auth', '1'); } catch {}
|
|
22
|
+
});
|
|
23
|
+
const fresh = new Date(Date.now() - 60 * 1000).toISOString();
|
|
24
|
+
await ctx.route('**/api/hub/status*', async (route) => {
|
|
25
|
+
const r = await route.fetch();
|
|
26
|
+
const b = await r.json();
|
|
27
|
+
const nid = (b.sessions || [])[0]?.network_id || 'default';
|
|
28
|
+
const mk = (alias) => ({
|
|
29
|
+
alias, status: 'working', model: 'claude-opus-4', runtime: 'claude-code-cli',
|
|
30
|
+
network_id: nid, project_dir: null,
|
|
31
|
+
created_at: fresh, updated_at: fresh, last_seen_at: fresh,
|
|
32
|
+
});
|
|
33
|
+
await route.fulfill({ response: r, json: { ...b, sessions: [
|
|
34
|
+
mk('alpha'), mk('beta'), mk('gamma'), mk('delta'),
|
|
35
|
+
] } });
|
|
36
|
+
});
|
|
37
|
+
await ctx.route('**/api/hub/messages*', (r2) => r2.fulfill({ json: { messages: [] } }));
|
|
38
|
+
await ctx.route('**/api/hub/tasks*', (r2) => r2.fulfill({ json: { tasks: [] } }));
|
|
39
|
+
|
|
40
|
+
const page = await ctx.newPage();
|
|
41
|
+
await page.goto('http://127.0.0.1:3000/', { waitUntil: 'domcontentloaded' });
|
|
42
|
+
await page.waitForFunction(() => document.querySelectorAll('g[data-node]').length === 4, { timeout: 30000 });
|
|
43
|
+
await page.waitForSelector('[data-topo-chrome-nodesize="S"]', { timeout: 10000 });
|
|
44
|
+
await page.waitForTimeout(300);
|
|
45
|
+
|
|
46
|
+
const testButton = async (size) => {
|
|
47
|
+
const sel = `[data-topo-chrome-nodesize="${size}"]`;
|
|
48
|
+
await page.locator(sel).click();
|
|
49
|
+
await page.waitForTimeout(50);
|
|
50
|
+
const duringAttr = await page.locator(sel).getAttribute('data-topo-chrome-nodesize-popping');
|
|
51
|
+
const duringClass = await page.locator(sel).getAttribute('class');
|
|
52
|
+
// Wait past the 240ms TTL
|
|
53
|
+
await page.waitForTimeout(300);
|
|
54
|
+
const afterAttr = await page.locator(sel).getAttribute('data-topo-chrome-nodesize-popping');
|
|
55
|
+
const afterClass = await page.locator(sel).getAttribute('class');
|
|
56
|
+
return {
|
|
57
|
+
size,
|
|
58
|
+
duringAttr,
|
|
59
|
+
duringClassHasPop: /anet-chrome-pop/.test(duringClass || ''),
|
|
60
|
+
afterAttr,
|
|
61
|
+
afterClassHasPop: /anet-chrome-pop/.test(afterClass || ''),
|
|
62
|
+
};
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
// Click each in order S → L → M to mix up state
|
|
66
|
+
const small = await testButton('S');
|
|
67
|
+
const large = await testButton('L');
|
|
68
|
+
const medium = await testButton('M');
|
|
69
|
+
|
|
70
|
+
await browser.close();
|
|
71
|
+
|
|
72
|
+
const ok_each = (b) =>
|
|
73
|
+
b.duringAttr === 'true' &&
|
|
74
|
+
b.duringClassHasPop === true &&
|
|
75
|
+
b.afterAttr === 'false' &&
|
|
76
|
+
b.afterClassHasPop === false;
|
|
77
|
+
|
|
78
|
+
const results = {
|
|
79
|
+
small_pops: ok_each(small),
|
|
80
|
+
medium_pops: ok_each(medium),
|
|
81
|
+
large_pops: ok_each(large),
|
|
82
|
+
};
|
|
83
|
+
const ok = Object.values(results).every(Boolean);
|
|
84
|
+
console.log(`${ok ? '✅' : '❌'} chrome-pop nodesize:`, JSON.stringify(results),
|
|
85
|
+
'\n small: ', small,
|
|
86
|
+
'\n medium:', medium,
|
|
87
|
+
'\n large: ', large);
|
|
88
|
+
process.exit(ok ? 0 : 1);
|