@sleep2agi/agent-network-dashboard 0.5.3-preview.26 → 0.5.3-preview.260
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 +7 -7
- package/.next/fallback-build-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 +2 -2
- package/.next/server/app/_not-found.segments/_full.segment.rsc +2 -2
- package/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/.next/server/app/_not-found.segments/_index.segment.rsc +2 -2
- package/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- 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 +2 -2
- package/.next/server/app/admin.segments/_full.segment.rsc +2 -2
- package/.next/server/app/admin.segments/_head.segment.rsc +1 -1
- package/.next/server/app/admin.segments/_index.segment.rsc +2 -2
- package/.next/server/app/admin.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/admin.segments/admin/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/admin.segments/admin.segment.rsc +1 -1
- package/.next/server/app/index.html +2 -2
- package/.next/server/app/index.rsc +3 -3
- package/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
- package/.next/server/app/index.segments/_full.segment.rsc +3 -3
- package/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/.next/server/app/index.segments/_index.segment.rsc +2 -2
- 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 +3 -3
- package/.next/server/app/login.segments/_full.segment.rsc +3 -3
- package/.next/server/app/login.segments/_head.segment.rsc +1 -1
- package/.next/server/app/login.segments/_index.segment.rsc +2 -2
- package/.next/server/app/login.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/login.segments/login/__PAGE__.segment.rsc +2 -2
- package/.next/server/app/login.segments/login.segment.rsc +1 -1
- 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 +2 -2
- package/.next/server/app/logs.segments/_full.segment.rsc +2 -2
- package/.next/server/app/logs.segments/_head.segment.rsc +1 -1
- package/.next/server/app/logs.segments/_index.segment.rsc +2 -2
- package/.next/server/app/logs.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/logs.segments/logs/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/logs.segments/logs.segment.rsc +1 -1
- 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 +2 -2
- package/.next/server/app/messages.segments/_full.segment.rsc +2 -2
- package/.next/server/app/messages.segments/_head.segment.rsc +1 -1
- package/.next/server/app/messages.segments/_index.segment.rsc +2 -2
- package/.next/server/app/messages.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/messages.segments/messages/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/messages.segments/messages.segment.rsc +1 -1
- 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 +2 -2
- package/.next/server/app/node.segments/_full.segment.rsc +2 -2
- package/.next/server/app/node.segments/_head.segment.rsc +1 -1
- package/.next/server/app/node.segments/_index.segment.rsc +2 -2
- package/.next/server/app/node.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/node.segments/node/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/node.segments/node.segment.rsc +1 -1
- 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 +2 -2
- package/.next/server/app/nodes.segments/_full.segment.rsc +2 -2
- package/.next/server/app/nodes.segments/_head.segment.rsc +1 -1
- package/.next/server/app/nodes.segments/_index.segment.rsc +2 -2
- package/.next/server/app/nodes.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/nodes.segments/nodes/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/nodes.segments/nodes.segment.rsc +1 -1
- 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 +2 -2
- package/.next/server/app/server-logs.segments/_full.segment.rsc +2 -2
- package/.next/server/app/server-logs.segments/_head.segment.rsc +1 -1
- package/.next/server/app/server-logs.segments/_index.segment.rsc +2 -2
- package/.next/server/app/server-logs.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/server-logs.segments/server-logs/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/server-logs.segments/server-logs.segment.rsc +1 -1
- 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 +2 -2
- package/.next/server/app/settings/networks.segments/_full.segment.rsc +2 -2
- package/.next/server/app/settings/networks.segments/_head.segment.rsc +1 -1
- package/.next/server/app/settings/networks.segments/_index.segment.rsc +2 -2
- package/.next/server/app/settings/networks.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/settings/networks.segments/settings/networks/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/settings/networks.segments/settings/networks.segment.rsc +1 -1
- package/.next/server/app/settings/networks.segments/settings.segment.rsc +1 -1
- 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 +2 -2
- package/.next/server/app/settings/tokens.segments/_full.segment.rsc +2 -2
- package/.next/server/app/settings/tokens.segments/_head.segment.rsc +1 -1
- package/.next/server/app/settings/tokens.segments/_index.segment.rsc +2 -2
- package/.next/server/app/settings/tokens.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/settings/tokens.segments/settings/tokens/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/settings/tokens.segments/settings/tokens.segment.rsc +1 -1
- package/.next/server/app/settings/tokens.segments/settings.segment.rsc +1 -1
- package/.next/server/app/settings.html +2 -2
- package/.next/server/app/settings.rsc +3 -3
- package/.next/server/app/settings.segments/_full.segment.rsc +3 -3
- package/.next/server/app/settings.segments/_head.segment.rsc +1 -1
- package/.next/server/app/settings.segments/_index.segment.rsc +2 -2
- package/.next/server/app/settings.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/settings.segments/settings/__PAGE__.segment.rsc +2 -2
- package/.next/server/app/settings.segments/settings.segment.rsc +1 -1
- 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 +2 -2
- package/.next/server/app/tasks.segments/_full.segment.rsc +2 -2
- package/.next/server/app/tasks.segments/_head.segment.rsc +1 -1
- package/.next/server/app/tasks.segments/_index.segment.rsc +2 -2
- package/.next/server/app/tasks.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/tasks.segments/tasks/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/tasks.segments/tasks.segment.rsc +1 -1
- package/.next/server/chunks/[root-of-the-server]__0tx8s8i._.js +1 -1
- package/.next/server/chunks/[root-of-the-server]__0tx8s8i._.js.map +1 -1
- package/.next/server/chunks/ssr/[root-of-the-server]__0sv~g.o._.js +1 -1
- package/.next/server/chunks/ssr/[root-of-the-server]__0sv~g.o._.js.map +1 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_09kk21a._.js +4 -4
- package/.next/server/chunks/ssr/agent-network-dashboard_09kk21a._.js.map +1 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_app_01jhlxz._.js +1 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_app_01jhlxz._.js.map +1 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_app_09d29my._.js +1 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_app_09d29my._.js.map +1 -1
- package/.next/server/middleware-build-manifest.js +3 -3
- package/.next/server/pages/404.html +2 -2
- package/.next/server/pages/500.html +1 -1
- package/.next/static/chunks/083elibefsefi.js +4 -0
- package/.next/static/chunks/{05uydm8okqgqe.js → 0p142v5va508~.js} +1 -1
- package/.next/static/chunks/0u8v68gl7g6j1.js +1 -0
- package/.next/static/chunks/11sahbo6ikg8g.js +1 -0
- package/.next/static/chunks/16-7qr7qx9zrz.css +2 -0
- package/.next/trace +2 -2
- package/.next/trace-build +1 -1
- package/app/api/hub/servers/route.ts +3 -29
- package/app/components/TopoGraph.tsx +6143 -180
- package/app/globals.css +897 -7
- package/app/lib/serverDedupe.ts +122 -0
- package/package.json +1 -1
- package/scripts/p157-rc2-dedup-test.mjs +110 -0
- package/scripts/topo-a11y-titles-catalog-test.mjs +132 -0
- package/scripts/topo-active-chrome-hover-text-test.mjs +107 -0
- package/scripts/topo-active-links-chip-halo-layers-test.mjs +81 -0
- package/scripts/topo-alias-chat-brightness-test.mjs +79 -0
- package/scripts/topo-alias-text-halo-layers-test.mjs +98 -0
- package/scripts/topo-animation-temporal-modes-catalog-test.mjs +144 -0
- package/scripts/topo-avatar-chat-gate-test.mjs +77 -0
- package/scripts/topo-avatar-drop-shadow-test.mjs +86 -0
- package/scripts/topo-avatar-fallback-hover-test.mjs +104 -0
- package/scripts/topo-avatar-fallback-rotate-test.mjs +92 -0
- package/scripts/topo-avatar-rotate-test.mjs +85 -0
- package/scripts/topo-avatar-scale-test.mjs +89 -0
- package/scripts/topo-badge-chat-gate-test.mjs +74 -0
- package/scripts/topo-brand-drop-shadow-test.mjs +71 -0
- package/scripts/topo-brand-logo-breath-test.mjs +102 -0
- package/scripts/topo-brand-logo-halo-layers-test.mjs +85 -0
- package/scripts/topo-brand-logo-hover-brightness-test.mjs +105 -0
- package/scripts/topo-brand-logo-hover-rotate-test.mjs +93 -0
- package/scripts/topo-brand-logo-hover-test.mjs +85 -0
- package/scripts/topo-canvas-desc-a11y-test.mjs +87 -0
- package/scripts/topo-canvas-entrance-animation-test.mjs +117 -0
- package/scripts/topo-canvas-scan-beam-diagonal-test.mjs +148 -0
- package/scripts/topo-canvas-scan-beam-test.mjs +109 -0
- package/scripts/topo-canvas-scan-beam-vertical-test.mjs +123 -0
- package/scripts/topo-card-chat-brightness-test.mjs +86 -0
- package/scripts/topo-chat-ring-breath-curve-test.mjs +114 -0
- package/scripts/topo-chat-ring-brightness-test.mjs +80 -0
- package/scripts/topo-chat-ring-halo-layers-test.mjs +100 -0
- package/scripts/topo-chat-ring-r-breath-test.mjs +121 -0
- package/scripts/topo-chat-ring-status-halo-test.mjs +106 -0
- package/scripts/topo-chat-ring-sw-breath-test.mjs +123 -0
- package/scripts/topo-chip-pin-halo-test.mjs +85 -0
- package/scripts/topo-chip-row-digit-ls-test.mjs +135 -0
- package/scripts/topo-chip-row-member-alias-lit-test.mjs +154 -0
- package/scripts/topo-chip-row-tier-glow-brightness-test.mjs +99 -0
- package/scripts/topo-chip-row-unit-hover-tracking-test.mjs +124 -0
- package/scripts/topo-chrome-control-halo-layers-test.mjs +22 -0
- package/scripts/topo-chrome-fullscreen-breath-test.mjs +121 -0
- package/scripts/topo-chrome-layout-trailer-breath-test.mjs +86 -0
- package/scripts/topo-chrome-nodesize-trailer-breath-test.mjs +86 -0
- package/scripts/topo-chrome-reset-breath-test.mjs +115 -0
- package/scripts/topo-chrome-strip-entrance-animation-test.mjs +115 -0
- package/scripts/topo-chrome-wrapper-halo-test.mjs +83 -0
- package/scripts/topo-chrome-zoom-wrapper-breath-test.mjs +85 -0
- package/scripts/topo-click-ripple-glow-test.mjs +86 -0
- package/scripts/topo-click-ripple-halo-layers-test.mjs +79 -0
- package/scripts/topo-click-ripple-sw-test.mjs +110 -0
- package/scripts/topo-crescent-breath-test.mjs +104 -0
- package/scripts/topo-crescent-envelope-breath-test.mjs +103 -0
- package/scripts/topo-crescent-recede-test.mjs +111 -0
- package/scripts/topo-dense-alias-chat-halo-test.mjs +73 -0
- package/scripts/topo-dense-alias-halo-layers-test.mjs +80 -0
- package/scripts/topo-dual-axis-surfaces-catalog-test.mjs +94 -0
- package/scripts/topo-edge-badge-circle-brightness-test.mjs +82 -0
- package/scripts/topo-edge-badge-circle-hot-pulse-test.mjs +100 -0
- package/scripts/topo-edge-badge-digit-halo-layers-test.mjs +107 -0
- package/scripts/topo-edge-badge-endpoint-gate-test.mjs +94 -0
- package/scripts/topo-edge-badge-halo-layers-test.mjs +85 -0
- package/scripts/topo-edge-badge-hot-pulse-test.mjs +92 -0
- package/scripts/topo-edge-badge-hover-glow-test.mjs +90 -0
- package/scripts/topo-edge-badge-text-brightness-test.mjs +83 -0
- package/scripts/topo-edge-chat-gate-test.mjs +71 -0
- package/scripts/topo-edge-flow-rail-halo-layers-test.mjs +89 -0
- package/scripts/topo-edge-particle-brightness-test.mjs +82 -0
- package/scripts/topo-edge-particle-halo-layers-test.mjs +91 -0
- package/scripts/topo-edge-pill-glow-test.mjs +67 -0
- package/scripts/topo-edge-pin-halo-test.mjs +99 -0
- package/scripts/topo-edge-visible-brightness-test.mjs +84 -0
- package/scripts/topo-edge-visible-halo-layers-test.mjs +87 -0
- package/scripts/topo-endpoint-ring-brightness-test.mjs +83 -0
- package/scripts/topo-endpoint-ring-flow-halo-test.mjs +107 -0
- package/scripts/topo-endpoint-ring-halo-layers-test.mjs +100 -0
- package/scripts/topo-filter-pill-glow-test.mjs +90 -0
- package/scripts/topo-filter-pill-halo-layers-test.mjs +27 -0
- package/scripts/topo-flow-arrow-brightness-test.mjs +82 -0
- package/scripts/topo-flow-rail-brightness-test.mjs +80 -0
- package/scripts/topo-fullscreen-attr-test.mjs +73 -0
- package/scripts/topo-fullscreen-brightness-test.mjs +84 -0
- package/scripts/topo-fullscreen-icon-rotate-test.mjs +93 -0
- package/scripts/topo-grid-content-bottom-attr-test.mjs +72 -0
- package/scripts/topo-group-box-brightness-test.mjs +84 -0
- package/scripts/topo-group-box-halo-layers-test.mjs +91 -0
- package/scripts/topo-group-chat-gate-test.mjs +77 -0
- package/scripts/topo-group-label-brightness-test.mjs +84 -0
- package/scripts/topo-group-label-halo-layers-test.mjs +78 -0
- package/scripts/topo-group-label-hover-glow-test.mjs +86 -0
- package/scripts/topo-group-label-member-alias-hover-test.mjs +125 -0
- package/scripts/topo-group-pill-glow-test.mjs +76 -0
- package/scripts/topo-group-tint-brightness-test.mjs +82 -0
- package/scripts/topo-h2-dual-axis-breath-test.mjs +92 -0
- package/scripts/topo-h2-triple-axis-breath-test.mjs +142 -0
- package/scripts/topo-halo-chat-gate-test.mjs +72 -0
- package/scripts/topo-hover-detail-halo-test.mjs +76 -0
- package/scripts/topo-hub-a11y-title-test.mjs +95 -0
- package/scripts/topo-hub-core-brightness-test.mjs +82 -0
- package/scripts/topo-hub-core-halo-layers-test.mjs +81 -0
- package/scripts/topo-hub-digit-brightness-test.mjs +79 -0
- package/scripts/topo-hub-digit-halo-layers-test.mjs +76 -0
- package/scripts/topo-hub-digit-ls-test.mjs +119 -0
- package/scripts/topo-hub-halo-brightness-test.mjs +80 -0
- package/scripts/topo-hub-halo-glow-test.mjs +96 -0
- package/scripts/topo-hub-halo-halo-layers-test.mjs +76 -0
- package/scripts/topo-hub-highlight-brightness-test.mjs +84 -0
- package/scripts/topo-hub-highlight-glow-test.mjs +99 -0
- package/scripts/topo-hub-highlight-halo-layers-test.mjs +78 -0
- package/scripts/topo-hub-highlight-r-test.mjs +112 -0
- package/scripts/topo-hub-hover-ring-brightness-test.mjs +79 -0
- package/scripts/topo-hub-hover-ring-glow-test.mjs +97 -0
- package/scripts/topo-hub-hover-ring-halo-layers-test.mjs +71 -0
- package/scripts/topo-hub-spoke-brightness-test.mjs +77 -0
- package/scripts/topo-hub-spoke-glow-test.mjs +112 -0
- package/scripts/topo-hub-spoke-halo-layers-test.mjs +97 -0
- package/scripts/topo-hub-spoke-self-filter-test.mjs +119 -0
- package/scripts/topo-kicker-breath-test.mjs +100 -0
- package/scripts/topo-kicker-dual-axis-breath-test.mjs +81 -0
- package/scripts/topo-kicker-halo-layers-test.mjs +82 -0
- package/scripts/topo-kicker-triple-axis-breath-test.mjs +124 -0
- package/scripts/topo-label-card-brightness-test.mjs +81 -0
- package/scripts/topo-layout-hover-fw-test.mjs +98 -0
- package/scripts/topo-layout-toggle-brightness-test.mjs +94 -0
- package/scripts/topo-layout-toggle-halo-layers-test.mjs +95 -0
- package/scripts/topo-legend-count-brightness-test.mjs +80 -0
- package/scripts/topo-legend-count-halo-layers-test.mjs +79 -0
- package/scripts/topo-legend-count-letter-spacing-test.mjs +108 -0
- package/scripts/topo-legend-label-fw-test.mjs +107 -0
- package/scripts/topo-legend-panel-title-breath-test.mjs +86 -0
- package/scripts/topo-legend-pin-ring-brightness-test.mjs +82 -0
- package/scripts/topo-legend-pin-ring-halo-layers-test.mjs +71 -0
- package/scripts/topo-legend-row-count-brightness-test.mjs +85 -0
- package/scripts/topo-legend-row-label-glow-test.mjs +102 -0
- package/scripts/topo-legend-swatch-glow-test.mjs +109 -0
- package/scripts/topo-legend-swatch-member-alias-match-test.mjs +139 -0
- package/scripts/topo-legend-tint-brightness-test.mjs +83 -0
- package/scripts/topo-legend-trio-halo-layers-test.mjs +22 -0
- package/scripts/topo-minimap-container-halo-test.mjs +82 -0
- package/scripts/topo-minimap-dot-chat-gate-test.mjs +81 -0
- package/scripts/topo-minimap-hover-glow-test.mjs +109 -0
- package/scripts/topo-minimap-viewport-brightness-test.mjs +84 -0
- package/scripts/topo-minimap-viewport-halo-layers-test.mjs +24 -0
- package/scripts/topo-more-footer-brightness-test.mjs +94 -0
- package/scripts/topo-node-alias-brightness-test.mjs +84 -0
- package/scripts/topo-node-avatar-halo-layers-test.mjs +25 -0
- package/scripts/topo-node-hover-ring-halo-layers-test.mjs +70 -0
- package/scripts/topo-node-label-card-halo-test.mjs +76 -0
- package/scripts/topo-node-sub-text-brightness-test.mjs +88 -0
- package/scripts/topo-nodesize-brightness-test.mjs +82 -0
- package/scripts/topo-nodesize-halo-layers-test.mjs +89 -0
- package/scripts/topo-nodesize-hover-fw-test.mjs +99 -0
- package/scripts/topo-orphan-label-opacity-test.mjs +98 -0
- package/scripts/topo-panel-count-halo-layers-test.mjs +91 -0
- package/scripts/topo-panel-count-hover-ls-test.mjs +87 -0
- package/scripts/topo-panel-rect-halo-test.mjs +90 -0
- package/scripts/topo-panel-row-brightness-test.mjs +116 -0
- package/scripts/topo-panel-title-brightness-test.mjs +98 -0
- package/scripts/topo-panel-title-glow-test.mjs +111 -0
- package/scripts/topo-panel-titles-dual-axis-breath-test.mjs +94 -0
- package/scripts/topo-panel-titles-halo-layers-test.mjs +23 -0
- package/scripts/topo-panel-titles-triple-axis-breath-test.mjs +161 -0
- package/scripts/topo-pill-x-rotate-test.mjs +96 -0
- package/scripts/topo-pip-brightness-test.mjs +85 -0
- package/scripts/topo-pressure-bar-halo-layers-test.mjs +19 -0
- package/scripts/topo-pressure-seg-glow-test.mjs +92 -0
- package/scripts/topo-pressure-seg-member-alias-match-test.mjs +133 -0
- package/scripts/topo-pressure-seg-motion-test.mjs +101 -0
- package/scripts/topo-r717-scan-beam-pair-pattern-test.mjs +100 -0
- package/scripts/topo-r717-triple-axis-pair-pattern-test.mjs +113 -0
- package/scripts/topo-r717-triple-axis-tier-pattern-test.mjs +117 -0
- package/scripts/topo-recent-count-brightness-test.mjs +84 -0
- package/scripts/topo-recent-more-fw-test.mjs +126 -0
- package/scripts/topo-recent-more-halo-layers-test.mjs +90 -0
- package/scripts/topo-recent-panel-hot-pulse-test.mjs +105 -0
- package/scripts/topo-recent-panel-title-breath-test.mjs +91 -0
- package/scripts/topo-recent-pip-halo-layers-test.mjs +82 -0
- package/scripts/topo-recent-row-chat-gate-test.mjs +75 -0
- package/scripts/topo-recent-row-content-lift-test.mjs +140 -0
- package/scripts/topo-recent-row-fw-test.mjs +115 -0
- package/scripts/topo-recent-row-text-glow-test.mjs +86 -0
- package/scripts/topo-recent-row-text-halo-layers-test.mjs +67 -0
- package/scripts/topo-recent-tint-brightness-test.mjs +80 -0
- package/scripts/topo-recent-ts-brightness-test.mjs +86 -0
- package/scripts/topo-reduced-motion-attr-test.mjs +69 -0
- package/scripts/topo-reset-brightness-test.mjs +83 -0
- package/scripts/topo-reset-icon-hover-scale-test.mjs +102 -0
- package/scripts/topo-respiratory-axis-count-stats-test.mjs +154 -0
- package/scripts/topo-respiratory-patterns-catalog-test.mjs +112 -0
- package/scripts/topo-respiratory-rolodex-test.mjs +83 -0
- package/scripts/topo-respiratory-tiers-catalog-test.mjs +119 -0
- package/scripts/topo-respiratory-triple-axis-surfaces-catalog-test.mjs +127 -0
- package/scripts/topo-runtime-badge-brightness-test.mjs +78 -0
- package/scripts/topo-runtime-badge-glow-test.mjs +108 -0
- package/scripts/topo-runtime-badge-halo-layers-test.mjs +87 -0
- package/scripts/topo-runtime-badge-rotate-test.mjs +85 -0
- package/scripts/topo-section-title-breath-test.mjs +83 -0
- package/scripts/topo-section-title-halo-layers-test.mjs +88 -0
- package/scripts/topo-spoke-chat-gate-test.mjs +72 -0
- package/scripts/topo-starfield-hue-test.mjs +109 -0
- package/scripts/topo-status-pin-pill-halo-layers-test.mjs +17 -0
- package/scripts/topo-status-ring-brightness-test.mjs +84 -0
- package/scripts/topo-status-ring-chat-gate-test.mjs +72 -0
- package/scripts/topo-status-ring-halo-layers-test.mjs +105 -0
- package/scripts/topo-status-ring-status-halo-test.mjs +110 -0
- package/scripts/topo-sub-text-chat-brightness-test.mjs +81 -0
- package/scripts/topo-svg-title-a11y-r731-test.mjs +93 -0
- package/scripts/topo-svg-title-a11y-test.mjs +88 -0
- package/scripts/topo-title-block-entrance-animation-test.mjs +127 -0
- package/scripts/topo-title-block-envelope-breath-test.mjs +87 -0
- package/scripts/topo-titleblock-h2-hover-fw-test.mjs +109 -0
- package/scripts/topo-titleblock-h2-hover-tracking-test.mjs +128 -0
- package/scripts/topo-titleblock-kicker-hover-test.mjs +134 -0
- package/scripts/topo-vendor-chip-glow-test.mjs +97 -0
- package/scripts/topo-vendor-chip-halo-layers-test.mjs +18 -0
- package/scripts/topo-vendor-chip-pin-halo-test.mjs +88 -0
- package/scripts/topo-vendor-count-suffix-halo-layers-test.mjs +79 -0
- package/scripts/topo-vendor-distribution-wrapper-halo-test.mjs +93 -0
- package/scripts/topo-vendor-letter-halo-layers-test.mjs +93 -0
- package/scripts/topo-vendor-pill-glow-test.mjs +98 -0
- package/scripts/topo-watermark-breath-test.mjs +100 -0
- package/scripts/topo-watermark-dual-axis-breath-test.mjs +88 -0
- package/scripts/topo-watermark-envelope-breath-test.mjs +88 -0
- package/scripts/topo-watermark-recede-test.mjs +114 -0
- package/scripts/topo-watermark-triple-axis-breath-test.mjs +129 -0
- package/scripts/topo-working-online-chip-halo-layers-test.mjs +94 -0
- package/scripts/topo-zoom-buttons-brightness-test.mjs +94 -0
- package/scripts/topo-zoom-in-out-halo-layers-test.mjs +97 -0
- package/scripts/topo-zoom-level-breath-test.mjs +87 -0
- package/scripts/topo-zoom-level-brightness-test.mjs +83 -0
- package/scripts/topo-zoom-level-color-test.mjs +105 -0
- package/scripts/topo-zoom-level-dual-axis-breath-test.mjs +83 -0
- package/scripts/topo-zoom-level-halo-layers-test.mjs +78 -0
- package/scripts/topo-zoom-level-triple-axis-breath-test.mjs +148 -0
- package/.next/static/chunks/0b57cx-~yee9s.js +0 -1
- package/.next/static/chunks/0c5ux9rrl-j.a.js +0 -4
- package/.next/static/chunks/0ixrbcha76lse.js +0 -1
- package/.next/static/chunks/0m.1mvl~t.avc.css +0 -2
- /package/.next/static/{fAHTff4Obp5vYwjZIWEvA → wz1T-LhLDalz691PpN3E7}/_buildManifest.js +0 -0
- /package/.next/static/{fAHTff4Obp5vYwjZIWEvA → wz1T-LhLDalz691PpN3E7}/_clientMiddlewareManifest.js +0 -0
- /package/.next/static/{fAHTff4Obp5vYwjZIWEvA → wz1T-LhLDalz691PpN3E7}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/* Round 549 verification: title-block brand logo gains hover:rotate-6
|
|
2
|
+
* paired with R548's hover:scale-105. Banked R547 Tailwind 4 pattern —
|
|
3
|
+
* probe BOTH cs.scale AND cs.rotate (individual CSS properties, not
|
|
4
|
+
* combined transform).
|
|
5
|
+
*
|
|
6
|
+
* Test phases:
|
|
7
|
+
* 1. rest: scale='none' (or '1'), rotate='none' (or '0deg')
|
|
8
|
+
* 2. hover: scale='1.05', rotate='6deg'
|
|
9
|
+
* 3. source-side regex confirms className + data-attr wired
|
|
10
|
+
*/
|
|
11
|
+
import { chromium } from 'playwright';
|
|
12
|
+
import { readFileSync } from 'node:fs';
|
|
13
|
+
|
|
14
|
+
const TOKEN = JSON.parse(readFileSync('/home/vansin/.anet/config.json', 'utf8')).token;
|
|
15
|
+
const fresh = new Date(Date.now() - 60 * 1000).toISOString();
|
|
16
|
+
|
|
17
|
+
const browser = await chromium.launch({ headless: true });
|
|
18
|
+
const ctx = await browser.newContext({ viewport: { width: 1500, height: 1200 } });
|
|
19
|
+
await ctx.addCookies([{ name: 'anet_dashboard_session', value: `v3:${TOKEN}`, domain: '127.0.0.1', path: '/' }]);
|
|
20
|
+
await ctx.addInitScript(() => {
|
|
21
|
+
try {
|
|
22
|
+
localStorage.setItem('anet-theme', 'cyber');
|
|
23
|
+
localStorage.setItem('anet-topo-layout', 'ring');
|
|
24
|
+
sessionStorage.setItem('anet_v3_auth', '1');
|
|
25
|
+
} catch {}
|
|
26
|
+
});
|
|
27
|
+
await ctx.route('**/api/hub/status*', async (route) => {
|
|
28
|
+
const r = await route.fetch();
|
|
29
|
+
const b = await r.json();
|
|
30
|
+
const nid = (b.sessions || [])[0]?.network_id || 'default';
|
|
31
|
+
const mk = (alias) => ({
|
|
32
|
+
alias, status: 'idle', model: 'claude-opus-4', runtime: 'claude-code-cli',
|
|
33
|
+
network_id: nid, project_dir: null,
|
|
34
|
+
created_at: fresh, updated_at: fresh, last_seen_at: fresh,
|
|
35
|
+
});
|
|
36
|
+
await route.fulfill({ response: r, json: { ...b, sessions: [mk('a·1')] } });
|
|
37
|
+
});
|
|
38
|
+
await ctx.route('**/api/hub/messages*', (r) => r.fulfill({ json: { messages: [] } }));
|
|
39
|
+
await ctx.route('**/api/hub/tasks*', (r) => r.fulfill({ json: { tasks: [] } }));
|
|
40
|
+
const page = await ctx.newPage();
|
|
41
|
+
await page.goto('http://127.0.0.1:3000/', { waitUntil: 'networkidle' });
|
|
42
|
+
await page.waitForSelector('[data-topo-brand-logo]', { timeout: 15000 });
|
|
43
|
+
await page.waitForTimeout(500);
|
|
44
|
+
|
|
45
|
+
const sel = '[data-topo-brand-logo]';
|
|
46
|
+
const rest = await page.evaluate((s) => {
|
|
47
|
+
const el = document.querySelector(s);
|
|
48
|
+
if (!el) return null;
|
|
49
|
+
const cs = getComputedStyle(el);
|
|
50
|
+
return {
|
|
51
|
+
attrScale: el.getAttribute('data-topo-brand-logo-hover-scale'),
|
|
52
|
+
attrRotate: el.getAttribute('data-topo-brand-logo-hover-rotate'),
|
|
53
|
+
scale: cs.scale,
|
|
54
|
+
rotate: cs.rotate,
|
|
55
|
+
};
|
|
56
|
+
}, sel);
|
|
57
|
+
|
|
58
|
+
await page.hover(sel);
|
|
59
|
+
await page.waitForTimeout(400);
|
|
60
|
+
const hover = await page.evaluate((s) => {
|
|
61
|
+
const el = document.querySelector(s);
|
|
62
|
+
if (!el) return null;
|
|
63
|
+
const cs = getComputedStyle(el);
|
|
64
|
+
return { scale: cs.scale, rotate: cs.rotate };
|
|
65
|
+
}, sel);
|
|
66
|
+
|
|
67
|
+
await browser.close();
|
|
68
|
+
|
|
69
|
+
const src = readFileSync('/home/vansin/agent-network-dashboard/app/components/TopoGraph.tsx', 'utf8');
|
|
70
|
+
const sourceClassNameWired =
|
|
71
|
+
/className="shrink-0 transition-transform duration-200 ease-out hover:scale-105 hover:rotate-6 transform-gpu"/.test(src);
|
|
72
|
+
const sourceScaleAttrWired =
|
|
73
|
+
/data-topo-brand-logo-hover-scale="1\.05"/.test(src);
|
|
74
|
+
const sourceRotateAttrWired =
|
|
75
|
+
/data-topo-brand-logo-hover-rotate="6deg"/.test(src);
|
|
76
|
+
|
|
77
|
+
const results = {
|
|
78
|
+
rest_scale_idle: rest?.scale === 'none' || rest?.scale === '1',
|
|
79
|
+
rest_rotate_idle: rest?.rotate === 'none' || rest?.rotate === '0deg',
|
|
80
|
+
rest_attr_scale_105: rest?.attrScale === '1.05',
|
|
81
|
+
rest_attr_rotate_6deg: rest?.attrRotate === '6deg',
|
|
82
|
+
hover_scale_105: hover?.scale === '1.05',
|
|
83
|
+
hover_rotate_6deg: hover?.rotate === '6deg',
|
|
84
|
+
source_classname: sourceClassNameWired,
|
|
85
|
+
source_scale_attr: sourceScaleAttrWired,
|
|
86
|
+
source_rotate_attr: sourceRotateAttrWired,
|
|
87
|
+
};
|
|
88
|
+
const ok = Object.values(results).every(Boolean);
|
|
89
|
+
console.log(`${ok ? '✅' : '❌'} R549 brand-logo hover-rotate-6 (paired with R548 scale-105):`,
|
|
90
|
+
JSON.stringify(results, null, 2),
|
|
91
|
+
'\n rest:', JSON.stringify(rest),
|
|
92
|
+
'\n hover:', JSON.stringify(hover));
|
|
93
|
+
process.exit(ok ? 0 : 1);
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/* Round 548 verification: title-block brand logo gains hover:scale-105
|
|
2
|
+
* delight gesture. Banked R547 Tailwind 4 pattern — probe cs.scale not
|
|
3
|
+
* cs.transform.
|
|
4
|
+
*
|
|
5
|
+
* Test phases:
|
|
6
|
+
* 1. rest: scale='none'
|
|
7
|
+
* 2. hover: scale='1.05'
|
|
8
|
+
* 3. source-side regex confirms className + data-attr wired
|
|
9
|
+
*/
|
|
10
|
+
import { chromium } from 'playwright';
|
|
11
|
+
import { readFileSync } from 'node:fs';
|
|
12
|
+
|
|
13
|
+
const TOKEN = JSON.parse(readFileSync('/home/vansin/.anet/config.json', 'utf8')).token;
|
|
14
|
+
const fresh = new Date(Date.now() - 60 * 1000).toISOString();
|
|
15
|
+
|
|
16
|
+
const browser = await chromium.launch({ headless: true });
|
|
17
|
+
const ctx = await browser.newContext({ viewport: { width: 1500, height: 1200 } });
|
|
18
|
+
await ctx.addCookies([{ name: 'anet_dashboard_session', value: `v3:${TOKEN}`, domain: '127.0.0.1', path: '/' }]);
|
|
19
|
+
await ctx.addInitScript(() => {
|
|
20
|
+
try {
|
|
21
|
+
localStorage.setItem('anet-theme', 'cyber');
|
|
22
|
+
localStorage.setItem('anet-topo-layout', 'ring');
|
|
23
|
+
sessionStorage.setItem('anet_v3_auth', '1');
|
|
24
|
+
} catch {}
|
|
25
|
+
});
|
|
26
|
+
await ctx.route('**/api/hub/status*', async (route) => {
|
|
27
|
+
const r = await route.fetch();
|
|
28
|
+
const b = await r.json();
|
|
29
|
+
const nid = (b.sessions || [])[0]?.network_id || 'default';
|
|
30
|
+
const mk = (alias) => ({
|
|
31
|
+
alias, status: 'idle', model: 'claude-opus-4', runtime: 'claude-code-cli',
|
|
32
|
+
network_id: nid, project_dir: null,
|
|
33
|
+
created_at: fresh, updated_at: fresh, last_seen_at: fresh,
|
|
34
|
+
});
|
|
35
|
+
await route.fulfill({ response: r, json: { ...b, sessions: [mk('a·1')] } });
|
|
36
|
+
});
|
|
37
|
+
await ctx.route('**/api/hub/messages*', (r) => r.fulfill({ json: { messages: [] } }));
|
|
38
|
+
await ctx.route('**/api/hub/tasks*', (r) => r.fulfill({ json: { tasks: [] } }));
|
|
39
|
+
const page = await ctx.newPage();
|
|
40
|
+
await page.goto('http://127.0.0.1:3000/', { waitUntil: 'networkidle' });
|
|
41
|
+
await page.waitForSelector('[data-topo-brand-logo]', { timeout: 15000 });
|
|
42
|
+
await page.waitForTimeout(500);
|
|
43
|
+
|
|
44
|
+
const sel = '[data-topo-brand-logo]';
|
|
45
|
+
const rest = await page.evaluate((s) => {
|
|
46
|
+
const el = document.querySelector(s);
|
|
47
|
+
if (!el) return null;
|
|
48
|
+
const cs = getComputedStyle(el);
|
|
49
|
+
return {
|
|
50
|
+
attrScale: el.getAttribute('data-topo-brand-logo-hover-scale'),
|
|
51
|
+
scale: cs.scale,
|
|
52
|
+
rotate: cs.rotate,
|
|
53
|
+
};
|
|
54
|
+
}, sel);
|
|
55
|
+
|
|
56
|
+
await page.hover(sel);
|
|
57
|
+
await page.waitForTimeout(400);
|
|
58
|
+
const hover = await page.evaluate((s) => {
|
|
59
|
+
const el = document.querySelector(s);
|
|
60
|
+
if (!el) return null;
|
|
61
|
+
const cs = getComputedStyle(el);
|
|
62
|
+
return { scale: cs.scale };
|
|
63
|
+
}, sel);
|
|
64
|
+
|
|
65
|
+
await browser.close();
|
|
66
|
+
|
|
67
|
+
const src = readFileSync('/home/vansin/agent-network-dashboard/app/components/TopoGraph.tsx', 'utf8');
|
|
68
|
+
const sourceClassNameWired =
|
|
69
|
+
/className="shrink-0 transition-transform duration-200 ease-out hover:scale-105 transform-gpu"/.test(src);
|
|
70
|
+
const sourceAttrWired =
|
|
71
|
+
/data-topo-brand-logo-hover-scale="1\.05"/.test(src);
|
|
72
|
+
|
|
73
|
+
const results = {
|
|
74
|
+
rest_scale_none: rest?.scale === 'none' || rest?.scale === '1',
|
|
75
|
+
rest_attr_scale_105: rest?.attrScale === '1.05',
|
|
76
|
+
hover_scale_105: hover?.scale === '1.05',
|
|
77
|
+
source_classname: sourceClassNameWired,
|
|
78
|
+
source_attr: sourceAttrWired,
|
|
79
|
+
};
|
|
80
|
+
const ok = Object.values(results).every(Boolean);
|
|
81
|
+
console.log(`${ok ? '✅' : '❌'} R548 brand-logo hover-scale:`,
|
|
82
|
+
JSON.stringify(results, null, 2),
|
|
83
|
+
'\n rest:', JSON.stringify(rest),
|
|
84
|
+
'\n hover:', JSON.stringify(hover));
|
|
85
|
+
process.exit(ok ? 0 : 1);
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/* Round 734 — SVG <desc> stable structural description on root canvas
|
|
2
|
+
* + aria-describedby linkage. Different a11y mechanism from R730-R733:
|
|
3
|
+
* R730-R733 add <title> children as accessible NAMES on individual
|
|
4
|
+
* decorative elements (watermark, brand logo, hub, etc.)
|
|
5
|
+
* R734 adds <desc> as a stable DESCRIPTION on the canvas root,
|
|
6
|
+
* complementing the existing dynamic aria-label (R7/R469).
|
|
7
|
+
*
|
|
8
|
+
* WAI-ARIA name + description pair: SR announces the accessible name
|
|
9
|
+
* (label) first, then optionally reads the description on follow-up.
|
|
10
|
+
*
|
|
11
|
+
* Assertions:
|
|
12
|
+
* - Root <svg> has aria-describedby="anet-topo-canvas-desc"
|
|
13
|
+
* - <desc id="anet-topo-canvas-desc"> exists as a child of root <svg>
|
|
14
|
+
* - desc content mentions key structural surfaces: hub, ring/grid,
|
|
15
|
+
* recent-signal, legend, chrome strip
|
|
16
|
+
* - desc content mentions key interactions: Tab, double-click, l-key
|
|
17
|
+
* - aria-label (R7/R469 dynamic) still present and not replaced
|
|
18
|
+
* - aria-roledescription (R-original) still present
|
|
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 fresh = new Date(Date.now() - 60 * 1000).toISOString();
|
|
25
|
+
|
|
26
|
+
const browser = await chromium.launch({ headless: true });
|
|
27
|
+
const ctx = await browser.newContext({ viewport: { width: 1500, height: 1200 } });
|
|
28
|
+
await ctx.addCookies([{ name: 'anet_dashboard_session', value: `v3:${TOKEN}`, domain: '127.0.0.1', path: '/' }]);
|
|
29
|
+
await ctx.addInitScript(() => {
|
|
30
|
+
try {
|
|
31
|
+
localStorage.setItem('anet-theme', 'cyber');
|
|
32
|
+
localStorage.setItem('anet-topo-layout', 'ring');
|
|
33
|
+
sessionStorage.setItem('anet_v3_auth', '1');
|
|
34
|
+
} catch {}
|
|
35
|
+
});
|
|
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) => ({
|
|
41
|
+
alias, status: 'idle', model: 'claude-opus-4', runtime: 'claude-code-cli',
|
|
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: [mk('a·1'), mk('a·2')] } });
|
|
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
|
+
const page = await ctx.newPage();
|
|
50
|
+
await page.goto('http://127.0.0.1:3000/', { waitUntil: 'networkidle' });
|
|
51
|
+
await page.waitForSelector('[data-topo-canvas-aria]', { timeout: 15000, state: 'attached' });
|
|
52
|
+
await page.waitForTimeout(300);
|
|
53
|
+
|
|
54
|
+
const state = await page.evaluate(() => {
|
|
55
|
+
const svg = document.querySelector('[data-topo-canvas-aria]');
|
|
56
|
+
const desc = document.getElementById('anet-topo-canvas-desc');
|
|
57
|
+
return {
|
|
58
|
+
aria_describedby: svg?.getAttribute('aria-describedby') ?? null,
|
|
59
|
+
aria_label: svg?.getAttribute('aria-label') ?? null,
|
|
60
|
+
aria_roledescr: svg?.getAttribute('aria-roledescription') ?? null,
|
|
61
|
+
desc_present: !!desc,
|
|
62
|
+
desc_text: desc?.textContent ?? null,
|
|
63
|
+
desc_is_child_of_svg: desc?.parentElement === svg,
|
|
64
|
+
};
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
await browser.close();
|
|
68
|
+
|
|
69
|
+
const text = state.desc_text ?? '';
|
|
70
|
+
const textLower = text.toLowerCase();
|
|
71
|
+
const mentionsStructural = ['hub', 'ring', 'grid', 'recent-signal', 'legend', 'chrome strip'].every(k => textLower.includes(k));
|
|
72
|
+
const mentionsInteractions = ['Tab', 'double-click', 'l '].every(k => text.includes(k));
|
|
73
|
+
|
|
74
|
+
const results = {
|
|
75
|
+
aria_describedby_correct: state.aria_describedby === 'anet-topo-canvas-desc',
|
|
76
|
+
desc_element_present: state.desc_present === true,
|
|
77
|
+
desc_is_direct_child: state.desc_is_child_of_svg === true,
|
|
78
|
+
desc_mentions_structural: mentionsStructural,
|
|
79
|
+
desc_mentions_interactions: mentionsInteractions,
|
|
80
|
+
aria_label_preserved: typeof state.aria_label === 'string' && state.aria_label.includes('Agent network topology'),
|
|
81
|
+
aria_roledescription_kept: state.aria_roledescr === 'agent network topology',
|
|
82
|
+
};
|
|
83
|
+
const ok = Object.values(results).every(Boolean);
|
|
84
|
+
console.log(`${ok ? '✅' : '❌'} R734 SVG <desc> + aria-describedby on root canvas (WAI-ARIA name + description pair):`,
|
|
85
|
+
JSON.stringify(results, null, 2),
|
|
86
|
+
`\n state: ${JSON.stringify(state)}`);
|
|
87
|
+
process.exit(ok ? 0 : 1);
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/* Round 740 — one-time canvas entrance animation. Plays on first
|
|
2
|
+
* paint, then the canvas sits at scale(1) opacity(1) for the rest of
|
|
3
|
+
* the session. Distinct from breath (infinite rest-axis) and ambient
|
|
4
|
+
* (infinite sweep-axis) — R740 is ONE-SHOT.
|
|
5
|
+
*
|
|
6
|
+
* Assertions:
|
|
7
|
+
* - .anet-topo-canvas-entrance class on root <svg> (reducedMotion off)
|
|
8
|
+
* - data-topo-canvas-entrance="true" attribute
|
|
9
|
+
* - CSS @keyframes 0% scale(0.99) opacity 0.8 → 100% scale(1) opacity 1
|
|
10
|
+
* - .anet-topo-canvas-entrance binds 600ms ease-out animation
|
|
11
|
+
* - CSS animation NOT infinite (no `infinite` keyword) — one-shot
|
|
12
|
+
* - transform-origin: 50% 50%
|
|
13
|
+
* - prefers-reduced-motion guard present
|
|
14
|
+
* - Animation completes within ~1s (test waits 1.2s after mount,
|
|
15
|
+
* then verifies computed transform is identity matrix)
|
|
16
|
+
* - Existing canvas className tokens (w-full h-auto block) preserved
|
|
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 fresh = new Date(Date.now() - 60 * 1000).toISOString();
|
|
23
|
+
|
|
24
|
+
const browser = await chromium.launch({ headless: true });
|
|
25
|
+
const ctx = await browser.newContext({ viewport: { width: 1500, height: 1200 } });
|
|
26
|
+
await ctx.addCookies([{ name: 'anet_dashboard_session', value: `v3:${TOKEN}`, domain: '127.0.0.1', path: '/' }]);
|
|
27
|
+
await ctx.addInitScript(() => {
|
|
28
|
+
try {
|
|
29
|
+
localStorage.setItem('anet-theme', 'cyber');
|
|
30
|
+
localStorage.setItem('anet-topo-layout', 'ring');
|
|
31
|
+
sessionStorage.setItem('anet_v3_auth', '1');
|
|
32
|
+
} catch {}
|
|
33
|
+
});
|
|
34
|
+
await ctx.route('**/api/hub/status*', async (route) => {
|
|
35
|
+
const r = await route.fetch();
|
|
36
|
+
const b = await r.json();
|
|
37
|
+
const nid = (b.sessions || [])[0]?.network_id || 'default';
|
|
38
|
+
const mk = (alias) => ({
|
|
39
|
+
alias, status: 'idle', model: 'claude-opus-4', runtime: 'claude-code-cli',
|
|
40
|
+
network_id: nid, project_dir: null,
|
|
41
|
+
created_at: fresh, updated_at: fresh, last_seen_at: fresh,
|
|
42
|
+
});
|
|
43
|
+
await route.fulfill({ response: r, json: { ...b, sessions: [mk('a·1'), mk('a·2')] } });
|
|
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
|
+
const page = await ctx.newPage();
|
|
48
|
+
await page.goto('http://127.0.0.1:3000/', { waitUntil: 'networkidle' });
|
|
49
|
+
await page.waitForSelector('[data-topo-canvas-aria]', { timeout: 15000, state: 'attached' });
|
|
50
|
+
|
|
51
|
+
/* Wait past the 600ms animation duration so computed transform settles
|
|
52
|
+
* to the final state (scale(1)). */
|
|
53
|
+
await page.waitForTimeout(1200);
|
|
54
|
+
|
|
55
|
+
const state = await page.evaluate(() => {
|
|
56
|
+
const svg = document.querySelector('[data-topo-canvas-aria]');
|
|
57
|
+
if (!svg) return null;
|
|
58
|
+
const cs = getComputedStyle(svg);
|
|
59
|
+
return {
|
|
60
|
+
has_entrance_class: svg.classList.contains('anet-topo-canvas-entrance'),
|
|
61
|
+
entrance_attr: svg.getAttribute('data-topo-canvas-entrance'),
|
|
62
|
+
class_attr: svg.getAttribute('class'),
|
|
63
|
+
anim_name: cs.animationName,
|
|
64
|
+
anim_duration: cs.animationDuration,
|
|
65
|
+
anim_iteration: cs.animationIterationCount,
|
|
66
|
+
transform_origin: cs.transformOrigin,
|
|
67
|
+
computed_transform: cs.transform,
|
|
68
|
+
computed_opacity: cs.opacity,
|
|
69
|
+
};
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
await browser.close();
|
|
73
|
+
|
|
74
|
+
const cssSrc = readFileSync('/home/vansin/agent-network-dashboard/app/globals.css', 'utf8');
|
|
75
|
+
const cssKfStart = /@keyframes anet-topo-canvas-entrance-kf\s*\{[\s\S]*?0%\s*\{[\s\S]*?transform:\s*scale\(0\.99\)[\s\S]*?opacity:\s*0\.8/.test(cssSrc);
|
|
76
|
+
const cssKfEnd = /@keyframes anet-topo-canvas-entrance-kf\s*\{[\s\S]*?100%\s*\{[\s\S]*?transform:\s*scale\(1\)[\s\S]*?opacity:\s*1/.test(cssSrc);
|
|
77
|
+
const cssClassBound = /\.anet-topo-canvas-entrance\s*\{[\s\S]*?animation:\s*anet-topo-canvas-entrance-kf\s+600ms\s+ease-out/.test(cssSrc);
|
|
78
|
+
/* The CSS source regex was too broad (matched `infinite` in OTHER
|
|
79
|
+
* class blocks past this one). Verify one-shot directly via the
|
|
80
|
+
* runtime computed animation-iteration-count — this is the property
|
|
81
|
+
* that actually determines whether the animation replays. */
|
|
82
|
+
const runtimeOneShot = state?.anim_iteration === '1';
|
|
83
|
+
const cssTransformOrigin = /\.anet-topo-canvas-entrance\s*\{[\s\S]*?transform-origin:\s*50%\s+50%/.test(cssSrc);
|
|
84
|
+
const cssReducedMotion = /@media\s*\(prefers-reduced-motion:\s*reduce\)\s*\{[\s\S]*?\.anet-topo-canvas-entrance\s*\{\s*animation:\s*none/.test(cssSrc);
|
|
85
|
+
|
|
86
|
+
/* After 1.2s the animation should have completed; computed transform
|
|
87
|
+
* should be identity-matrix (scale 1). matrix(1, 0, 0, 1, 0, 0) === 'none'
|
|
88
|
+
* in some browsers; accept either. */
|
|
89
|
+
const transformSettled = state?.computed_transform === 'none'
|
|
90
|
+
|| state?.computed_transform === 'matrix(1, 0, 0, 1, 0, 0)';
|
|
91
|
+
|
|
92
|
+
const opacitySettled = parseFloat(state?.computed_opacity ?? '0') > 0.99;
|
|
93
|
+
|
|
94
|
+
const classKept = typeof state?.class_attr === 'string'
|
|
95
|
+
&& state.class_attr.includes('w-full')
|
|
96
|
+
&& state.class_attr.includes('h-auto')
|
|
97
|
+
&& state.class_attr.includes('block')
|
|
98
|
+
&& state.class_attr.includes('anet-topo-canvas-entrance');
|
|
99
|
+
|
|
100
|
+
const results = {
|
|
101
|
+
has_entrance_class: state?.has_entrance_class === true,
|
|
102
|
+
entrance_attr_true: state?.entrance_attr === 'true',
|
|
103
|
+
original_classes_preserved: classKept,
|
|
104
|
+
css_keyframe_start: cssKfStart,
|
|
105
|
+
css_keyframe_end: cssKfEnd,
|
|
106
|
+
css_class_binds_600ms_ease_out: cssClassBound,
|
|
107
|
+
runtime_animation_one_shot: runtimeOneShot,
|
|
108
|
+
css_transform_origin_center: cssTransformOrigin,
|
|
109
|
+
css_reduced_motion_guard: cssReducedMotion,
|
|
110
|
+
transform_settled_to_identity: transformSettled,
|
|
111
|
+
opacity_settled_to_1: opacitySettled,
|
|
112
|
+
};
|
|
113
|
+
const ok = Object.values(results).every(Boolean);
|
|
114
|
+
console.log(`${ok ? '✅' : '❌'} R740 one-time canvas entrance animation (scale 0.99→1 + opacity 0.8→1 @ 600ms ease-out, one-shot):`,
|
|
115
|
+
JSON.stringify(results, null, 2),
|
|
116
|
+
`\n state: ${JSON.stringify(state)}`);
|
|
117
|
+
process.exit(ok ? 0 : 1);
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
/* Round 739 — diagonal scan beam (3rd member of ambient scan beam
|
|
2
|
+
* family). Completes the trio from pair:
|
|
3
|
+
* R735 horizontal beam 30 s (top → bottom)
|
|
4
|
+
* R736 vertical beam 23 s (left → right)
|
|
5
|
+
* R739 diagonal beam 19 s (NW → SE) ← this round
|
|
6
|
+
*
|
|
7
|
+
* Coprime invariants:
|
|
8
|
+
* gcd(19, 23) = 1
|
|
9
|
+
* gcd(19, 30) = 1
|
|
10
|
+
* gcd(23, 30) = 1
|
|
11
|
+
* → 3 cadences pairwise coprime → never phase-lock as a trio.
|
|
12
|
+
*
|
|
13
|
+
* Assertions:
|
|
14
|
+
* - <line data-topo-canvas-scan-beam-diagonal> exists with 4 SMIL
|
|
15
|
+
* <animate> children on x1/y1/x2/y2 (all 19s, all repeatCount=indefinite)
|
|
16
|
+
* - opacity animate 0 → 0.06 → 0 at keyTimes 0/0.05/0.95/1, dur 19s
|
|
17
|
+
* - SVG <title>: "canvas scan beam diagonal · ambient sweep · 19s cycle"
|
|
18
|
+
* - data-topo-canvas-scan-beam-diagonal-active="true"
|
|
19
|
+
* - diagonal beam in background layer (rendered before nodes)
|
|
20
|
+
* - diagonal beam rendered AFTER vertical beam (trio document order)
|
|
21
|
+
* - all 3 beams alive (R735 + R736 regressions)
|
|
22
|
+
* - all 3 cadences pairwise coprime (Euclid check)
|
|
23
|
+
* - R717 patterns has 10 entries (was 9)
|
|
24
|
+
* - R717 includes new `scan-beam-trio` with shape "coprime-trio"
|
|
25
|
+
* and cadences [19, 23, 30]
|
|
26
|
+
* - R729 stats: patterns_count 10, ambient_patterns 2, ambient_cadences 3
|
|
27
|
+
* - R732 a11y catalog: 9 entries incl. diagonal beam
|
|
28
|
+
*/
|
|
29
|
+
import { chromium } from 'playwright';
|
|
30
|
+
import { readFileSync } from 'node:fs';
|
|
31
|
+
|
|
32
|
+
const TOKEN = JSON.parse(readFileSync('/home/vansin/.anet/config.json', 'utf8')).token;
|
|
33
|
+
const fresh = new Date(Date.now() - 60 * 1000).toISOString();
|
|
34
|
+
|
|
35
|
+
const browser = await chromium.launch({ headless: true });
|
|
36
|
+
const ctx = await browser.newContext({ viewport: { width: 1500, height: 1200 } });
|
|
37
|
+
await ctx.addCookies([{ name: 'anet_dashboard_session', value: `v3:${TOKEN}`, domain: '127.0.0.1', path: '/' }]);
|
|
38
|
+
await ctx.addInitScript(() => {
|
|
39
|
+
try {
|
|
40
|
+
localStorage.setItem('anet-theme', 'cyber');
|
|
41
|
+
localStorage.setItem('anet-topo-layout', 'ring');
|
|
42
|
+
sessionStorage.setItem('anet_v3_auth', '1');
|
|
43
|
+
} catch {}
|
|
44
|
+
});
|
|
45
|
+
await ctx.route('**/api/hub/status*', async (route) => {
|
|
46
|
+
const r = await route.fetch();
|
|
47
|
+
const b = await r.json();
|
|
48
|
+
const nid = (b.sessions || [])[0]?.network_id || 'default';
|
|
49
|
+
const mk = (alias) => ({
|
|
50
|
+
alias, status: 'idle', model: 'claude-opus-4', runtime: 'claude-code-cli',
|
|
51
|
+
network_id: nid, project_dir: null,
|
|
52
|
+
created_at: fresh, updated_at: fresh, last_seen_at: fresh,
|
|
53
|
+
});
|
|
54
|
+
await route.fulfill({ response: r, json: { ...b, sessions: [mk('a·1'), mk('a·2')] } });
|
|
55
|
+
});
|
|
56
|
+
await ctx.route('**/api/hub/messages*', (r) => r.fulfill({ json: { messages: [] } }));
|
|
57
|
+
await ctx.route('**/api/hub/tasks*', (r) => r.fulfill({ json: { tasks: [] } }));
|
|
58
|
+
const page = await ctx.newPage();
|
|
59
|
+
await page.goto('http://127.0.0.1:3000/', { waitUntil: 'networkidle' });
|
|
60
|
+
await page.waitForSelector('[data-topo-canvas-scan-beam-diagonal]', { timeout: 15000, state: 'attached' });
|
|
61
|
+
await page.waitForTimeout(300);
|
|
62
|
+
|
|
63
|
+
const state = await page.evaluate(() => {
|
|
64
|
+
const dbeam = document.querySelector('[data-topo-canvas-scan-beam-diagonal]');
|
|
65
|
+
const vbeam = document.querySelector('[data-topo-canvas-scan-beam-vertical]');
|
|
66
|
+
const hbeam = document.querySelector('[data-topo-canvas-scan-beam]');
|
|
67
|
+
if (!dbeam) return null;
|
|
68
|
+
const getAnim = (el, attr) => el?.querySelector(`animate[attributeName="${attr}"]`);
|
|
69
|
+
const x1A = getAnim(dbeam, 'x1');
|
|
70
|
+
const y1A = getAnim(dbeam, 'y1');
|
|
71
|
+
const x2A = getAnim(dbeam, 'x2');
|
|
72
|
+
const y2A = getAnim(dbeam, 'y2');
|
|
73
|
+
const opA = getAnim(dbeam, 'opacity');
|
|
74
|
+
const dtitle = dbeam.querySelector(':scope > title');
|
|
75
|
+
const svg = document.querySelector('[data-topo-canvas-aria]');
|
|
76
|
+
const firstNode = svg?.querySelector('g[data-node]');
|
|
77
|
+
const dbeamBeforeNodes = dbeam && firstNode
|
|
78
|
+
? (dbeam.compareDocumentPosition(firstNode) & Node.DOCUMENT_POSITION_FOLLOWING) !== 0
|
|
79
|
+
: null;
|
|
80
|
+
const dbeamAfterVbeam = vbeam && dbeam
|
|
81
|
+
? (vbeam.compareDocumentPosition(dbeam) & Node.DOCUMENT_POSITION_FOLLOWING) !== 0
|
|
82
|
+
: null;
|
|
83
|
+
return {
|
|
84
|
+
dbeam_present: !!dbeam,
|
|
85
|
+
dbeam_active_attr: dbeam?.getAttribute('data-topo-canvas-scan-beam-diagonal-active') ?? null,
|
|
86
|
+
x1_dur: x1A?.getAttribute('dur'), x1_vals: x1A?.getAttribute('values'),
|
|
87
|
+
y1_dur: y1A?.getAttribute('dur'), y1_vals: y1A?.getAttribute('values'),
|
|
88
|
+
x2_dur: x2A?.getAttribute('dur'), x2_vals: x2A?.getAttribute('values'),
|
|
89
|
+
y2_dur: y2A?.getAttribute('dur'), y2_vals: y2A?.getAttribute('values'),
|
|
90
|
+
op_dur: opA?.getAttribute('dur'), op_vals: opA?.getAttribute('values'), op_kt: opA?.getAttribute('keyTimes'),
|
|
91
|
+
dtitle_text: dtitle?.textContent ?? null,
|
|
92
|
+
dbeam_before_nodes: dbeamBeforeNodes,
|
|
93
|
+
dbeam_after_vbeam: dbeamAfterVbeam,
|
|
94
|
+
hbeam_present: !!hbeam,
|
|
95
|
+
vbeam_present: !!vbeam,
|
|
96
|
+
patterns: svg?.getAttribute('data-topo-respiratory-patterns') ?? null,
|
|
97
|
+
stats: svg?.getAttribute('data-topo-respiratory-axis-count-stats') ?? null,
|
|
98
|
+
a11y: svg?.getAttribute('data-topo-a11y-titles') ?? null,
|
|
99
|
+
};
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
await browser.close();
|
|
103
|
+
|
|
104
|
+
const gcd = (a, b) => (b === 0 ? a : gcd(b, a % b));
|
|
105
|
+
const coprime_trio = gcd(19, 23) === 1 && gcd(19, 30) === 1 && gcd(23, 30) === 1;
|
|
106
|
+
|
|
107
|
+
let patterns = null;
|
|
108
|
+
let stats = null;
|
|
109
|
+
let a11y = null;
|
|
110
|
+
try {
|
|
111
|
+
patterns = JSON.parse(state?.patterns ?? '');
|
|
112
|
+
stats = JSON.parse(state?.stats ?? '');
|
|
113
|
+
a11y = JSON.parse(state?.a11y ?? '');
|
|
114
|
+
} catch {}
|
|
115
|
+
|
|
116
|
+
const trioEntry = Array.isArray(patterns) ? patterns.find(p => p.name === 'scan-beam-trio') : null;
|
|
117
|
+
const trioCorrect = !!trioEntry
|
|
118
|
+
&& JSON.stringify(trioEntry.cadences) === JSON.stringify([19, 23, 30])
|
|
119
|
+
&& trioEntry.shape === 'coprime-trio'
|
|
120
|
+
&& Array.isArray(trioEntry.anchors) && trioEntry.anchors.length === 3
|
|
121
|
+
&& trioEntry.anchors.includes('scan beam diagonal');
|
|
122
|
+
|
|
123
|
+
const results = {
|
|
124
|
+
dbeam_line_present: state?.dbeam_present === true,
|
|
125
|
+
dbeam_active_true: state?.dbeam_active_attr === 'true',
|
|
126
|
+
x1_anim_full: state?.x1_dur === '19s' && state?.x1_vals === '-100;1100;-100',
|
|
127
|
+
y1_anim_full: state?.y1_dur === '19s' && state?.y1_vals === '-100;780;-100',
|
|
128
|
+
x2_anim_full: state?.x2_dur === '19s' && state?.x2_vals === '-30;1170;-30',
|
|
129
|
+
y2_anim_full: state?.y2_dur === '19s' && state?.y2_vals === '-30;850;-30',
|
|
130
|
+
op_anim_ramped: state?.op_dur === '19s' && state?.op_vals === '0;0.06;0.06;0' && state?.op_kt === '0;0.05;0.95;1',
|
|
131
|
+
dbeam_a11y_title: state?.dtitle_text === 'canvas scan beam diagonal · ambient sweep · 19s cycle',
|
|
132
|
+
dbeam_background_layer: state?.dbeam_before_nodes === true,
|
|
133
|
+
dbeam_after_vertical: state?.dbeam_after_vbeam === true,
|
|
134
|
+
all_three_beams_present: state?.dbeam_present && state?.vbeam_present && state?.hbeam_present,
|
|
135
|
+
coprime_trio_pairwise: coprime_trio,
|
|
136
|
+
r717_has_10_entries: Array.isArray(patterns) && patterns.length === 10,
|
|
137
|
+
r717_trio_entry_correct: trioCorrect,
|
|
138
|
+
r729_patterns_count_10: stats?.patterns_count === 10,
|
|
139
|
+
r729_ambient_patterns_2: stats?.ambient_patterns === 2,
|
|
140
|
+
r729_ambient_cadences_3: stats?.ambient_cadences === 3,
|
|
141
|
+
r732_a11y_has_9_entries: Array.isArray(a11y) && a11y.length === 9,
|
|
142
|
+
};
|
|
143
|
+
const ok = Object.values(results).every(Boolean);
|
|
144
|
+
console.log(`${ok ? '✅' : '❌'} R739 diagonal scan beam (3rd ambient member, completes scan-beam-trio with pairwise-coprime cadences):`,
|
|
145
|
+
JSON.stringify(results, null, 2),
|
|
146
|
+
`\n trio entry: ${JSON.stringify(trioEntry)}`,
|
|
147
|
+
`\n gcd: 19-23=${gcd(19,23)} 19-30=${gcd(19,30)} 23-30=${gcd(23,30)}`);
|
|
148
|
+
process.exit(ok ? 0 : 1);
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/* Round 735 — SVG scan beam: ambient living-system sweep across the
|
|
2
|
+
* canvas every 30 s. Pivot round: first genuinely new VISIBLE
|
|
3
|
+
* animation outside the breath / a11y / meta-doc threads since R720.
|
|
4
|
+
*
|
|
5
|
+
* Spec:
|
|
6
|
+
* - 1 px tall horizontal cyan stripe (pal.legendAccent)
|
|
7
|
+
* - y animates -2 → 680 → -2 over 30 s repeatCount=indefinite
|
|
8
|
+
* - opacity animates 0 → 0.08 → 0.08 → 0 at keyTimes 0/0.05/0.95/1
|
|
9
|
+
* - pointer-events: none, no business logic
|
|
10
|
+
* - rendered AFTER panel backdrop, BEFORE all other canvas content
|
|
11
|
+
* (background layer; nodes paint over it)
|
|
12
|
+
* - gated by !reducedMotion at JSX level
|
|
13
|
+
* - SVG <title> child for a11y ("canvas scan beam · ambient sweep · 30s cycle")
|
|
14
|
+
*
|
|
15
|
+
* Assertions:
|
|
16
|
+
* - <rect data-topo-canvas-scan-beam> exists
|
|
17
|
+
* - Two <animate> children: attributeName="y" and attributeName="opacity"
|
|
18
|
+
* - y animate has values "-2;680;-2" and dur "30s"
|
|
19
|
+
* - opacity animate has values "0;0.08;0.08;0" and dur "30s"
|
|
20
|
+
* - <title> child has the expected accessible name
|
|
21
|
+
* - data-topo-canvas-scan-beam-active="true" (reducedMotion off in test)
|
|
22
|
+
* - Beam is rendered BEFORE nodes (background-layer z-order)
|
|
23
|
+
* - R732 a11y-titles catalog has the scan-beam entry (7 total)
|
|
24
|
+
* - Overlap-test selectors don't match the rect (no data-node /
|
|
25
|
+
* data-group, no matching translate prefix) — verified indirectly
|
|
26
|
+
* by overlap test still passing
|
|
27
|
+
*/
|
|
28
|
+
import { chromium } from 'playwright';
|
|
29
|
+
import { readFileSync } from 'node:fs';
|
|
30
|
+
|
|
31
|
+
const TOKEN = JSON.parse(readFileSync('/home/vansin/.anet/config.json', 'utf8')).token;
|
|
32
|
+
const fresh = new Date(Date.now() - 60 * 1000).toISOString();
|
|
33
|
+
|
|
34
|
+
const browser = await chromium.launch({ headless: true });
|
|
35
|
+
const ctx = await browser.newContext({ viewport: { width: 1500, height: 1200 } });
|
|
36
|
+
await ctx.addCookies([{ name: 'anet_dashboard_session', value: `v3:${TOKEN}`, domain: '127.0.0.1', path: '/' }]);
|
|
37
|
+
await ctx.addInitScript(() => {
|
|
38
|
+
try {
|
|
39
|
+
localStorage.setItem('anet-theme', 'cyber');
|
|
40
|
+
localStorage.setItem('anet-topo-layout', 'ring');
|
|
41
|
+
sessionStorage.setItem('anet_v3_auth', '1');
|
|
42
|
+
} catch {}
|
|
43
|
+
});
|
|
44
|
+
await ctx.route('**/api/hub/status*', async (route) => {
|
|
45
|
+
const r = await route.fetch();
|
|
46
|
+
const b = await r.json();
|
|
47
|
+
const nid = (b.sessions || [])[0]?.network_id || 'default';
|
|
48
|
+
const mk = (alias) => ({
|
|
49
|
+
alias, status: 'idle', model: 'claude-opus-4', runtime: 'claude-code-cli',
|
|
50
|
+
network_id: nid, project_dir: null,
|
|
51
|
+
created_at: fresh, updated_at: fresh, last_seen_at: fresh,
|
|
52
|
+
});
|
|
53
|
+
await route.fulfill({ response: r, json: { ...b, sessions: [mk('a·1'), mk('a·2')] } });
|
|
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
|
+
const page = await ctx.newPage();
|
|
58
|
+
await page.goto('http://127.0.0.1:3000/', { waitUntil: 'networkidle' });
|
|
59
|
+
await page.waitForSelector('[data-topo-canvas-scan-beam]', { timeout: 15000, state: 'attached' });
|
|
60
|
+
await page.waitForTimeout(300);
|
|
61
|
+
|
|
62
|
+
const state = await page.evaluate(() => {
|
|
63
|
+
const beam = document.querySelector('[data-topo-canvas-scan-beam]');
|
|
64
|
+
if (!beam) return null;
|
|
65
|
+
const yAnim = beam.querySelector('animate[attributeName="y"]');
|
|
66
|
+
const opAnim = beam.querySelector('animate[attributeName="opacity"]');
|
|
67
|
+
const titleEl = beam.querySelector(':scope > title');
|
|
68
|
+
const svg = document.querySelector('[data-topo-canvas-aria]');
|
|
69
|
+
const firstNode = svg?.querySelector('g[data-node]');
|
|
70
|
+
const beamBeforeNodes = beam && firstNode
|
|
71
|
+
? (beam.compareDocumentPosition(firstNode) & Node.DOCUMENT_POSITION_FOLLOWING) !== 0
|
|
72
|
+
: null;
|
|
73
|
+
const catalogAttr = svg?.getAttribute('data-topo-a11y-titles') ?? null;
|
|
74
|
+
return {
|
|
75
|
+
beam_present: !!beam,
|
|
76
|
+
beam_active_attr: beam?.getAttribute('data-topo-canvas-scan-beam-active') ?? null,
|
|
77
|
+
beam_width: beam?.getAttribute('width') ?? null,
|
|
78
|
+
beam_height: beam?.getAttribute('height') ?? null,
|
|
79
|
+
y_anim_present: !!yAnim,
|
|
80
|
+
y_anim_values: yAnim?.getAttribute('values') ?? null,
|
|
81
|
+
y_anim_dur: yAnim?.getAttribute('dur') ?? null,
|
|
82
|
+
y_anim_repeat: yAnim?.getAttribute('repeatCount') ?? null,
|
|
83
|
+
op_anim_present: !!opAnim,
|
|
84
|
+
op_anim_values: opAnim?.getAttribute('values') ?? null,
|
|
85
|
+
op_anim_dur: opAnim?.getAttribute('dur') ?? null,
|
|
86
|
+
op_anim_keytimes: opAnim?.getAttribute('keyTimes') ?? null,
|
|
87
|
+
title_text: titleEl?.textContent ?? null,
|
|
88
|
+
beam_before_nodes: beamBeforeNodes,
|
|
89
|
+
catalog_has_entry: typeof catalogAttr === 'string' && catalogAttr.includes('canvas scan beam'),
|
|
90
|
+
};
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
await browser.close();
|
|
94
|
+
|
|
95
|
+
const results = {
|
|
96
|
+
beam_rect_present: state?.beam_present === true,
|
|
97
|
+
beam_active_true: state?.beam_active_attr === 'true',
|
|
98
|
+
beam_full_width_1px: state?.beam_width === '1000' && state?.beam_height === '1',
|
|
99
|
+
y_anim_full_sweep: state?.y_anim_present === true && state?.y_anim_values === '-2;680;-2' && state?.y_anim_dur === '30s' && state?.y_anim_repeat === 'indefinite',
|
|
100
|
+
opacity_anim_ramped: state?.op_anim_present === true && state?.op_anim_values === '0;0.08;0.08;0' && state?.op_anim_dur === '30s' && state?.op_anim_keytimes === '0;0.05;0.95;1',
|
|
101
|
+
a11y_title_present: state?.title_text === 'canvas scan beam · ambient sweep · 30s cycle',
|
|
102
|
+
beam_in_background_layer: state?.beam_before_nodes === true,
|
|
103
|
+
r732_catalog_includes_beam: state?.catalog_has_entry === true,
|
|
104
|
+
};
|
|
105
|
+
const ok = Object.values(results).every(Boolean);
|
|
106
|
+
console.log(`${ok ? '✅' : '❌'} R735 SVG canvas scan beam (ambient 30s sweep, first non-introspection visible animation since R720):`,
|
|
107
|
+
JSON.stringify(results, null, 2),
|
|
108
|
+
`\n state: ${JSON.stringify(state)}`);
|
|
109
|
+
process.exit(ok ? 0 : 1);
|