@sleep2agi/agent-network-dashboard 0.5.3 → 0.5.4
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 +35 -35
- package/.next/fallback-build-manifest.json +3 -3
- package/.next/prerender-manifest.json +29 -0
- package/.next/routes-manifest.json +12 -0
- package/.next/server/app/_global-error.html +1 -1
- package/.next/server/app/_global-error.rsc +2 -2
- package/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_full.segment.rsc +2 -2
- 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 +13 -13
- package/.next/server/app/_not-found.segments/_full.segment.rsc +13 -13
- 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 +15 -15
- package/.next/server/app/admin.segments/_full.segment.rsc +15 -15
- 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/upload/route/app-paths-manifest.json +3 -0
- package/.next/server/app/api/hub/upload/route/build-manifest.json +9 -0
- package/.next/server/app/api/hub/upload/route/server-reference-manifest.json +4 -0
- package/.next/server/app/api/hub/upload/route.js +7 -0
- package/.next/server/app/api/hub/upload/route.js.map +5 -0
- package/.next/server/app/api/hub/upload/route.js.nft.json +1 -0
- package/.next/server/app/api/hub/upload/route_client-reference-manifest.js +3 -0
- package/.next/server/app/index.html +2 -2
- package/.next/server/app/index.rsc +15 -15
- package/.next/server/app/index.segments/__PAGE__.segment.rsc +4 -4
- package/.next/server/app/index.segments/_full.segment.rsc +15 -15
- 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 +15 -15
- package/.next/server/app/login.segments/_full.segment.rsc +15 -15
- 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 +15 -15
- package/.next/server/app/logs.segments/_full.segment.rsc +15 -15
- 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/manifest.webmanifest/route/app-paths-manifest.json +3 -0
- package/.next/server/app/manifest.webmanifest/route/build-manifest.json +9 -0
- package/.next/server/app/manifest.webmanifest/route/server-reference-manifest.json +4 -0
- package/.next/server/app/manifest.webmanifest/route.js +8 -0
- package/.next/server/app/manifest.webmanifest/route.js.map +5 -0
- package/.next/server/app/manifest.webmanifest/route.js.nft.json +1 -0
- package/.next/server/app/manifest.webmanifest/route_client-reference-manifest.js +3 -0
- package/.next/server/app/manifest.webmanifest.body +1 -0
- package/.next/server/app/manifest.webmanifest.meta +1 -0
- 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 +15 -15
- package/.next/server/app/messages.segments/_full.segment.rsc +15 -15
- 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 +15 -15
- package/.next/server/app/node.segments/_full.segment.rsc +15 -15
- 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 +15 -15
- package/.next/server/app/nodes.segments/_full.segment.rsc +15 -15
- 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 +15 -15
- package/.next/server/app/server-logs.segments/_full.segment.rsc +15 -15
- 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 +15 -15
- package/.next/server/app/settings/networks.segments/_full.segment.rsc +15 -15
- 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 +15 -15
- package/.next/server/app/settings/tokens.segments/_full.segment.rsc +15 -15
- 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 +15 -15
- package/.next/server/app/settings.segments/_full.segment.rsc +15 -15
- 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 +15 -15
- package/.next/server/app/tasks.segments/_full.segment.rsc +15 -15
- 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/00jm_next_dist_0ju_ux9._.js +18 -0
- package/.next/server/chunks/00jm_next_dist_0ju_ux9._.js.map +1 -0
- package/.next/server/chunks/0ykm__next-internal_server_app_api_hub_upload_route_actions_03_eqnf.js +3 -0
- package/.next/server/chunks/0ykm__next-internal_server_app_manifest_webmanifest_route_actions_0m16rb8.js +3 -0
- package/.next/server/chunks/0ykm__next-internal_server_app_manifest_webmanifest_route_actions_0m16rb8.js.map +1 -0
- package/.next/server/chunks/{[externals]__11vad82._.js → [externals]__036g1.i._.js} +2 -2
- package/.next/server/chunks/[externals]__036g1.i._.js.map +1 -0
- package/.next/server/chunks/[root-of-the-server]__0-8_f0o._.js +3 -0
- package/.next/server/chunks/[root-of-the-server]__0-8_f0o._.js.map +1 -0
- package/.next/server/chunks/{[root-of-the-server]__08uyvdq._.js → [root-of-the-server]__0jndzts._.js} +2 -2
- package/.next/server/chunks/{[root-of-the-server]__08uyvdq._.js.map → [root-of-the-server]__0jndzts._.js.map} +1 -1
- package/.next/server/chunks/[root-of-the-server]__0mxw4vb._.js +1 -1
- package/.next/server/chunks/[root-of-the-server]__0mxw4vb._.js.map +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/00jm_next_dist_esm_build_templates_app-page_0..ddwm.js +1 -1
- package/.next/server/chunks/ssr/00jm_next_dist_esm_build_templates_app-page_0..ddwm.js.map +1 -1
- package/.next/server/chunks/ssr/00jm_next_dist_esm_build_templates_app-page_02bxi6j.js +1 -1
- package/.next/server/chunks/ssr/00jm_next_dist_esm_build_templates_app-page_02bxi6j.js.map +1 -1
- package/.next/server/chunks/ssr/00jm_next_dist_esm_build_templates_app-page_05oassd.js +1 -1
- package/.next/server/chunks/ssr/00jm_next_dist_esm_build_templates_app-page_05oassd.js.map +1 -1
- package/.next/server/chunks/ssr/00jm_next_dist_esm_build_templates_app-page_05vxtby.js +1 -1
- package/.next/server/chunks/ssr/00jm_next_dist_esm_build_templates_app-page_05vxtby.js.map +1 -1
- package/.next/server/chunks/ssr/00jm_next_dist_esm_build_templates_app-page_05~eml4.js +1 -1
- package/.next/server/chunks/ssr/00jm_next_dist_esm_build_templates_app-page_05~eml4.js.map +1 -1
- package/.next/server/chunks/ssr/00jm_next_dist_esm_build_templates_app-page_0_-g_q2.js +1 -1
- package/.next/server/chunks/ssr/00jm_next_dist_esm_build_templates_app-page_0_-g_q2.js.map +1 -1
- package/.next/server/chunks/ssr/00jm_next_dist_esm_build_templates_app-page_0_ec0xu.js +1 -1
- package/.next/server/chunks/ssr/00jm_next_dist_esm_build_templates_app-page_0_ec0xu.js.map +1 -1
- package/.next/server/chunks/ssr/00jm_next_dist_esm_build_templates_app-page_0czb6wz.js +1 -1
- package/.next/server/chunks/ssr/00jm_next_dist_esm_build_templates_app-page_0czb6wz.js.map +1 -1
- package/.next/server/chunks/ssr/00jm_next_dist_esm_build_templates_app-page_0e-cn.p.js +1 -1
- package/.next/server/chunks/ssr/00jm_next_dist_esm_build_templates_app-page_0e-cn.p.js.map +1 -1
- package/.next/server/chunks/ssr/00jm_next_dist_esm_build_templates_app-page_0k8_sr8.js +1 -1
- package/.next/server/chunks/ssr/00jm_next_dist_esm_build_templates_app-page_0k8_sr8.js.map +1 -1
- package/.next/server/chunks/ssr/00jm_next_dist_esm_build_templates_app-page_0lt_3bw.js +1 -1
- package/.next/server/chunks/ssr/00jm_next_dist_esm_build_templates_app-page_0lt_3bw.js.map +1 -1
- package/.next/server/chunks/ssr/00jm_next_dist_esm_build_templates_app-page_0uyh3yt.js +1 -1
- package/.next/server/chunks/ssr/00jm_next_dist_esm_build_templates_app-page_0uyh3yt.js.map +1 -1
- package/.next/server/chunks/ssr/00jm_next_dist_esm_build_templates_app-page_0v-a2ps.js +1 -1
- package/.next/server/chunks/ssr/00jm_next_dist_esm_build_templates_app-page_0v-a2ps.js.map +1 -1
- package/.next/server/chunks/ssr/00jm_next_dist_esm_build_templates_app-page_12.4r9~.js +1 -1
- package/.next/server/chunks/ssr/00jm_next_dist_esm_build_templates_app-page_12.4r9~.js.map +1 -1
- package/.next/server/chunks/ssr/00jm_next_dist_esm_build_templates_app-page_13mqkay.js +1 -1
- package/.next/server/chunks/ssr/00jm_next_dist_esm_build_templates_app-page_13mqkay.js.map +1 -1
- package/.next/server/chunks/ssr/[root-of-the-server]__030vg4n._.js +4 -1
- package/.next/server/chunks/ssr/[root-of-the-server]__030vg4n._.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/[root-of-the-server]__0u5aqkk._.js +1 -1
- package/.next/server/chunks/ssr/[root-of-the-server]__0u5aqkk._.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/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/middleware.js +2 -2
- package/.next/server/middleware.js.nft.json +1 -1
- package/.next/server/pages/404.html +2 -2
- package/.next/server/pages/500.html +1 -1
- package/.next/static/chunks/{07~8sx3_5uiox.js → 04wjx7vbxusw5.js} +4 -1
- package/.next/static/chunks/089t1exs6apb8.js +4 -0
- package/.next/static/chunks/{0ph1in3421~o-.js → 09e8kxo30n5cf.js} +1 -1
- package/.next/static/chunks/{0v4-5tng.uh.7.js → 0k-c1chkvf78s.js} +2 -2
- package/.next/static/chunks/0v2~nlpk-cx6v.css +2 -0
- package/.next/static/chunks/0xsye-9kffdi0.js +1 -0
- package/.next/static/chunks/0~rx_~akeylmq.js +1 -0
- package/.next/trace +2 -2
- package/.next/trace-build +1 -1
- package/.next/types/routes.d.ts +2 -1
- package/.next/types/validator.ts +9 -0
- package/app/api/hub/send/route.ts +11 -2
- package/app/api/hub/servers/route.ts +3 -29
- package/app/api/hub/upload/route.ts +83 -0
- package/app/components/AppShell.tsx +3 -1
- package/app/components/MobileNav.tsx +45 -0
- package/app/components/TaskChatPanel.tsx +130 -6
- package/app/components/TopoGraph.tsx +6686 -248
- package/app/globals.css +897 -7
- package/app/layout.tsx +6 -0
- package/app/lib/serverDedupe.ts +122 -0
- package/app/lib/vendorIdentity.ts +74 -56
- package/app/manifest.ts +23 -0
- package/package.json +4 -4
- package/public/vendors/claude.svg +7 -8
- package/public/vendors/minimax.svg +8 -9
- package/public/vendors/openai.svg +8 -10
- 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-cluster-count-attr-test.mjs +80 -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-live-lanes.mjs +48 -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-overlap-test.mjs +22 -8
- 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-tree-diag.mjs +95 -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/0fuba20p57-zo.js +0 -1
- package/.next/static/chunks/0m.1mvl~t.avc.css +0 -2
- package/.next/static/chunks/10cj-86disers.js +0 -1
- package/.next/static/chunks/158h2g7f-nxbt.js +0 -4
- /package/.next/server/chunks/{[externals]__11vad82._.js.map → 0ykm__next-internal_server_app_api_hub_upload_route_actions_03_eqnf.js.map} +0 -0
- /package/.next/static/{tQ1EtcEiS7ikgAoAyZWm7 → xq88BMF7fMUHWh10yaKTn}/_buildManifest.js +0 -0
- /package/.next/static/{tQ1EtcEiS7ikgAoAyZWm7 → xq88BMF7fMUHWh10yaKTn}/_clientMiddlewareManifest.js +0 -0
- /package/.next/static/{tQ1EtcEiS7ikgAoAyZWm7 → xq88BMF7fMUHWh10yaKTn}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/* Round 731 — extend SVG <title> a11y children to 2 more decorative
|
|
2
|
+
* SVG elements: title-block brand logo + canvas-corner crescent mark.
|
|
3
|
+
* Continues R730's a11y sub-family thread.
|
|
4
|
+
*
|
|
5
|
+
* R730 + R731 a11y title coverage so far (5 elements):
|
|
6
|
+
* R730 watermark <text> "sleep2agi · brand watermark"
|
|
7
|
+
* R730 recent panel title "recent signal · activity panel title"
|
|
8
|
+
* R730 legend panel title "legend · status / vendor / runtime swatch panel"
|
|
9
|
+
* R731 title-block brand logo "sleep2agi · brand logo"
|
|
10
|
+
* R731 canvas-corner crescent "sleep2agi · canvas-corner brand mark"
|
|
11
|
+
*
|
|
12
|
+
* Canonical title format: "<surface-name> · <structural-role>".
|
|
13
|
+
*
|
|
14
|
+
* Assertions:
|
|
15
|
+
* - Brand logo <svg> has a <title> child with expected text
|
|
16
|
+
* - Canvas-corner crescent <g> has a <title> child with expected text
|
|
17
|
+
* - Both follow the canonical "<name> · <role>" format
|
|
18
|
+
* - R730 watermark title still present (regression)
|
|
19
|
+
* - R730 legend title still present (regression)
|
|
20
|
+
*/
|
|
21
|
+
import { chromium } from 'playwright';
|
|
22
|
+
import { readFileSync } from 'node:fs';
|
|
23
|
+
|
|
24
|
+
const TOKEN = JSON.parse(readFileSync('/home/vansin/.anet/config.json', 'utf8')).token;
|
|
25
|
+
const fresh = new Date(Date.now() - 60 * 1000).toISOString();
|
|
26
|
+
|
|
27
|
+
const browser = await chromium.launch({ headless: true });
|
|
28
|
+
const ctx = await browser.newContext({ viewport: { width: 1500, height: 1200 } });
|
|
29
|
+
await ctx.addCookies([{ name: 'anet_dashboard_session', value: `v3:${TOKEN}`, domain: '127.0.0.1', path: '/' }]);
|
|
30
|
+
await ctx.addInitScript(() => {
|
|
31
|
+
try {
|
|
32
|
+
localStorage.setItem('anet-theme', 'cyber');
|
|
33
|
+
localStorage.setItem('anet-topo-layout', 'ring');
|
|
34
|
+
sessionStorage.setItem('anet_v3_auth', '1');
|
|
35
|
+
} catch {}
|
|
36
|
+
});
|
|
37
|
+
await ctx.route('**/api/hub/status*', async (route) => {
|
|
38
|
+
const r = await route.fetch();
|
|
39
|
+
const b = await r.json();
|
|
40
|
+
const nid = (b.sessions || [])[0]?.network_id || 'default';
|
|
41
|
+
const mk = (alias) => ({
|
|
42
|
+
alias, status: 'idle', model: 'claude-opus-4', runtime: 'claude-code-cli',
|
|
43
|
+
network_id: nid, project_dir: null,
|
|
44
|
+
created_at: fresh, updated_at: fresh, last_seen_at: fresh,
|
|
45
|
+
});
|
|
46
|
+
await route.fulfill({ response: r, json: { ...b, sessions: [mk('a·1'), mk('a·2')] } });
|
|
47
|
+
});
|
|
48
|
+
await ctx.route('**/api/hub/messages*', (r) => r.fulfill({ json: { messages: [] } }));
|
|
49
|
+
await ctx.route('**/api/hub/tasks*', (r) => r.fulfill({ json: { tasks: [] } }));
|
|
50
|
+
const page = await ctx.newPage();
|
|
51
|
+
await page.goto('http://127.0.0.1:3000/', { waitUntil: 'networkidle' });
|
|
52
|
+
await page.waitForSelector('[data-topo-brand-logo]', { timeout: 15000, state: 'attached' });
|
|
53
|
+
await page.waitForTimeout(300);
|
|
54
|
+
|
|
55
|
+
const state = await page.evaluate(() => {
|
|
56
|
+
const brandLogo = document.querySelector('[data-topo-brand-logo]');
|
|
57
|
+
const canvasMark = document.querySelector('[data-topo-brand-canvas-mark]');
|
|
58
|
+
const watermark = document.querySelector('[data-topo-brand-watermark]');
|
|
59
|
+
const legend = document.querySelector('[data-legend-panel-title]');
|
|
60
|
+
/* Get DIRECT child <title> (not descendant) so we don't pick up
|
|
61
|
+
* titles from nested SVG elements inside the brand logo's mask defs. */
|
|
62
|
+
const directTitleText = (el) => {
|
|
63
|
+
if (!el) return null;
|
|
64
|
+
for (const child of el.children) {
|
|
65
|
+
if (child.tagName.toLowerCase() === 'title') return child.textContent;
|
|
66
|
+
}
|
|
67
|
+
return null;
|
|
68
|
+
};
|
|
69
|
+
return {
|
|
70
|
+
brand_logo_title: directTitleText(brandLogo),
|
|
71
|
+
canvas_mark_title: directTitleText(canvasMark),
|
|
72
|
+
watermark_title: directTitleText(watermark),
|
|
73
|
+
legend_title: directTitleText(legend),
|
|
74
|
+
};
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
await browser.close();
|
|
78
|
+
|
|
79
|
+
const canonicalFormat = (s) => typeof s === 'string' && /^[^·]+ · [^·]+$/.test(s);
|
|
80
|
+
|
|
81
|
+
const results = {
|
|
82
|
+
brand_logo_title_present: state.brand_logo_title === 'sleep2agi · brand logo',
|
|
83
|
+
canvas_mark_title_present: state.canvas_mark_title === 'sleep2agi · canvas-corner brand mark',
|
|
84
|
+
brand_logo_canonical_format: canonicalFormat(state.brand_logo_title),
|
|
85
|
+
canvas_mark_canonical_format: canonicalFormat(state.canvas_mark_title),
|
|
86
|
+
r730_watermark_title_kept: state.watermark_title === 'sleep2agi · brand watermark',
|
|
87
|
+
r730_legend_title_kept: state.legend_title === 'legend · status / vendor / runtime swatch panel',
|
|
88
|
+
};
|
|
89
|
+
const ok = Object.values(results).every(Boolean);
|
|
90
|
+
console.log(`${ok ? '✅' : '❌'} R731 SVG <title> a11y extension to brand logo + canvas-corner crescent:`,
|
|
91
|
+
JSON.stringify(results, null, 2),
|
|
92
|
+
`\n state: ${JSON.stringify(state)}`);
|
|
93
|
+
process.exit(ok ? 0 : 1);
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/* Round 730 — SVG <title> a11y children on the 3 primary SVG text
|
|
2
|
+
* anchors (watermark, recent panel title, legend panel title). Pure
|
|
3
|
+
* additive a11y improvement: screen readers can now identify these
|
|
4
|
+
* decorative SVG elements via their accessible name. No visible chrome
|
|
5
|
+
* change (mouse tooltips don't fire because the elements have
|
|
6
|
+
* pointer-events: none), no overlap risk.
|
|
7
|
+
*
|
|
8
|
+
* Pivot round: first non-breath-family addition after the R721–R729
|
|
9
|
+
* triple-axis + meta-doc hexagon thread.
|
|
10
|
+
*
|
|
11
|
+
* Assertions:
|
|
12
|
+
* - Watermark <text> has a <title> child with expected text
|
|
13
|
+
* - Recent panel title (when rendered) has a <title> child
|
|
14
|
+
* - Legend panel title has a <title> child
|
|
15
|
+
* - Each title text matches the canonical format "<name> · <role>"
|
|
16
|
+
* - Existing breath animations on all 3 are preserved (regression)
|
|
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-brand-watermark]', { timeout: 15000, state: 'attached' });
|
|
50
|
+
await page.waitForTimeout(300);
|
|
51
|
+
|
|
52
|
+
const state = await page.evaluate(() => {
|
|
53
|
+
const watermark = document.querySelector('[data-topo-brand-watermark]');
|
|
54
|
+
const recent = document.querySelector('[data-recent-panel-title]');
|
|
55
|
+
const legend = document.querySelector('[data-legend-panel-title]');
|
|
56
|
+
const titleOf = (el) => el?.querySelector('title')?.textContent ?? null;
|
|
57
|
+
const smilCount = (el) => el?.querySelectorAll('animate').length ?? 0;
|
|
58
|
+
return {
|
|
59
|
+
watermark_present: !!watermark,
|
|
60
|
+
watermark_title_text: titleOf(watermark),
|
|
61
|
+
watermark_smil_count: smilCount(watermark), // expect 2 (R519 opacity + R712 letter-spacing)
|
|
62
|
+
recent_present: !!recent,
|
|
63
|
+
recent_title_text: titleOf(recent),
|
|
64
|
+
recent_smil_count: smilCount(recent), // expect 2 (R700 opacity + R713 font-size)
|
|
65
|
+
legend_present: !!legend,
|
|
66
|
+
legend_title_text: titleOf(legend),
|
|
67
|
+
legend_smil_count: smilCount(legend), // expect 2 (R701 opacity + R713 font-size)
|
|
68
|
+
};
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
await browser.close();
|
|
72
|
+
|
|
73
|
+
const results = {
|
|
74
|
+
watermark_title_present: state.watermark_present && state.watermark_title_text === 'sleep2agi · brand watermark',
|
|
75
|
+
watermark_smil_preserved: state.watermark_smil_count === 2,
|
|
76
|
+
/* Recent panel renders conditionally on flowLinks; same conditional-
|
|
77
|
+
* presence pattern as R728. Treat as pass if not rendered, strict
|
|
78
|
+
* check otherwise. */
|
|
79
|
+
recent_title_present: !state.recent_present || state.recent_title_text === 'recent signal · activity panel title',
|
|
80
|
+
recent_smil_preserved: !state.recent_present || state.recent_smil_count === 2,
|
|
81
|
+
legend_title_present: state.legend_present && state.legend_title_text === 'legend · status / vendor / runtime swatch panel',
|
|
82
|
+
legend_smil_preserved: state.legend_present && state.legend_smil_count === 2,
|
|
83
|
+
};
|
|
84
|
+
const ok = Object.values(results).every(Boolean);
|
|
85
|
+
console.log(`${ok ? '✅' : '❌'} R730 SVG <title> a11y children on 3 SVG text anchors (watermark + recent + legend titles):`,
|
|
86
|
+
JSON.stringify(results, null, 2),
|
|
87
|
+
`\n state: ${JSON.stringify(state)}`);
|
|
88
|
+
process.exit(ok ? 0 : 1);
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/* Round 742 — title-block entrance animation. 2nd member of the
|
|
2
|
+
* entrance family (after R740 canvas root). Staggered choreography:
|
|
3
|
+
* R740 canvas 0 → 600 ms scale 0.99 → 1, opacity 0.8 → 1
|
|
4
|
+
* R742 title-block 200 → 700 ms translateY -4 → 0, opacity 0.7 → 1
|
|
5
|
+
*
|
|
6
|
+
* Assertions:
|
|
7
|
+
* - .anet-topo-title-block-entrance class on title-block wrapper
|
|
8
|
+
* - data-topo-section-titleblock-entrance="true"
|
|
9
|
+
* - CSS @keyframes 0% translateY(-4px) opacity 0.7 → 100% translateY(0) opacity 1
|
|
10
|
+
* - .anet-topo-title-block-entrance binds 500ms ease-out 200ms delay
|
|
11
|
+
* - animation NOT infinite (runtime iteration count === '1')
|
|
12
|
+
* - prefers-reduced-motion guard present
|
|
13
|
+
* - Animation completes within ~900ms (200ms delay + 500ms + 200ms buffer)
|
|
14
|
+
* → after 900ms wait, computed transform is identity & opacity = 1
|
|
15
|
+
* - Existing R706 envelope-breath class still composed (regression)
|
|
16
|
+
* - R741 catalog one-shot-mount.members === 2, includes title-block in examples
|
|
17
|
+
* - R740 canvas entrance still present (regression)
|
|
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 fresh = new Date(Date.now() - 60 * 1000).toISOString();
|
|
24
|
+
|
|
25
|
+
const browser = await chromium.launch({ headless: true });
|
|
26
|
+
const ctx = await browser.newContext({ viewport: { width: 1500, height: 1200 } });
|
|
27
|
+
await ctx.addCookies([{ name: 'anet_dashboard_session', value: `v3:${TOKEN}`, domain: '127.0.0.1', path: '/' }]);
|
|
28
|
+
await ctx.addInitScript(() => {
|
|
29
|
+
try {
|
|
30
|
+
localStorage.setItem('anet-theme', 'cyber');
|
|
31
|
+
localStorage.setItem('anet-topo-layout', 'ring');
|
|
32
|
+
sessionStorage.setItem('anet_v3_auth', '1');
|
|
33
|
+
} catch {}
|
|
34
|
+
});
|
|
35
|
+
await ctx.route('**/api/hub/status*', async (route) => {
|
|
36
|
+
const r = await route.fetch();
|
|
37
|
+
const b = await r.json();
|
|
38
|
+
const nid = (b.sessions || [])[0]?.network_id || 'default';
|
|
39
|
+
const mk = (alias) => ({
|
|
40
|
+
alias, status: 'idle', model: 'claude-opus-4', runtime: 'claude-code-cli',
|
|
41
|
+
network_id: nid, project_dir: null,
|
|
42
|
+
created_at: fresh, updated_at: fresh, last_seen_at: fresh,
|
|
43
|
+
});
|
|
44
|
+
await route.fulfill({ response: r, json: { ...b, sessions: [mk('a·1'), mk('a·2')] } });
|
|
45
|
+
});
|
|
46
|
+
await ctx.route('**/api/hub/messages*', (r) => r.fulfill({ json: { messages: [] } }));
|
|
47
|
+
await ctx.route('**/api/hub/tasks*', (r) => r.fulfill({ json: { tasks: [] } }));
|
|
48
|
+
const page = await ctx.newPage();
|
|
49
|
+
await page.goto('http://127.0.0.1:3000/', { waitUntil: 'networkidle' });
|
|
50
|
+
await page.waitForSelector('[data-topo-section-titleblock-group]', { timeout: 15000, state: 'attached' });
|
|
51
|
+
/* Wait for both R740 (0-600ms) and R742 (200-700ms) animations to
|
|
52
|
+
* complete plus a safety buffer. */
|
|
53
|
+
await page.waitForTimeout(900);
|
|
54
|
+
|
|
55
|
+
const state = await page.evaluate(() => {
|
|
56
|
+
const tb = document.querySelector('[data-topo-section-titleblock-group]');
|
|
57
|
+
const svg = document.querySelector('[data-topo-canvas-aria]');
|
|
58
|
+
if (!tb) return null;
|
|
59
|
+
const cs = getComputedStyle(tb);
|
|
60
|
+
return {
|
|
61
|
+
has_entrance_class: tb.classList.contains('anet-topo-title-block-entrance'),
|
|
62
|
+
entrance_attr: tb.getAttribute('data-topo-section-titleblock-entrance'),
|
|
63
|
+
envelope_breath_kept: tb.classList.contains('anet-topo-title-block-envelope-breath'),
|
|
64
|
+
anim_name: cs.animationName,
|
|
65
|
+
anim_duration: cs.animationDuration,
|
|
66
|
+
anim_delay: cs.animationDelay,
|
|
67
|
+
anim_iteration: cs.animationIterationCount,
|
|
68
|
+
computed_transform: cs.transform,
|
|
69
|
+
computed_opacity: cs.opacity,
|
|
70
|
+
canvas_entrance_class: svg?.classList.contains('anet-topo-canvas-entrance') ?? null,
|
|
71
|
+
temporal_modes: svg?.getAttribute('data-topo-animation-temporal-modes') ?? null,
|
|
72
|
+
};
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
await browser.close();
|
|
76
|
+
|
|
77
|
+
const cssSrc = readFileSync('/home/vansin/agent-network-dashboard/app/globals.css', 'utf8');
|
|
78
|
+
const cssKfStart = /@keyframes anet-topo-title-block-entrance-kf\s*\{[\s\S]*?0%\s*\{[\s\S]*?transform:\s*translateY\(-4px\)[\s\S]*?opacity:\s*0\.7/.test(cssSrc);
|
|
79
|
+
const cssKfEnd = /@keyframes anet-topo-title-block-entrance-kf\s*\{[\s\S]*?100%\s*\{[\s\S]*?transform:\s*translateY\(0\)[\s\S]*?opacity:\s*1/.test(cssSrc);
|
|
80
|
+
const cssClassBound = /\.anet-topo-title-block-entrance\s*\{[\s\S]*?animation:\s*anet-topo-title-block-entrance-kf\s+500ms\s+ease-out\s+200ms\s+backwards/.test(cssSrc);
|
|
81
|
+
const cssReducedMotion = /@media\s*\(prefers-reduced-motion:\s*reduce\)\s*\{[\s\S]*?\.anet-topo-title-block-entrance\s*\{\s*animation:\s*none/.test(cssSrc);
|
|
82
|
+
|
|
83
|
+
const transformSettled = state?.computed_transform === 'none'
|
|
84
|
+
|| state?.computed_transform === 'matrix(1, 0, 0, 1, 0, 0)';
|
|
85
|
+
/* The title-block carries TWO animations via the R742 compound:
|
|
86
|
+
* 1. entrance one-shot, 500ms — settles after ~700ms
|
|
87
|
+
* 2. envelope-breath infinite, 11s — opacity 0.92 ↔ 1 forever (R706)
|
|
88
|
+
* After the entrance completes, opacity is governed by the ongoing
|
|
89
|
+
* envelope breath, so it sits SOMEWHERE in [0.92, 1] — never exactly
|
|
90
|
+
* 1 at a random sample. Assert opacity ∈ [0.90, 1.00] (the R706
|
|
91
|
+
* breath band with a small tolerance) rather than === 1. */
|
|
92
|
+
const opacityInBreathBand = (() => {
|
|
93
|
+
const o = parseFloat(state?.computed_opacity ?? '0');
|
|
94
|
+
return o >= 0.90 && o <= 1.0;
|
|
95
|
+
})();
|
|
96
|
+
/* The compound animation's FIRST entry is the one-shot entrance;
|
|
97
|
+
* the SECOND is the infinite breath. Verify the entrance part is
|
|
98
|
+
* one-shot by checking the first iteration-count token === '1'. */
|
|
99
|
+
const entranceIsOneShot = (state?.anim_iteration ?? '').split(',')[0].trim() === '1';
|
|
100
|
+
const entranceIsFirstInCompound = (state?.anim_name ?? '').split(',')[0].trim() === 'anet-topo-title-block-entrance-kf';
|
|
101
|
+
|
|
102
|
+
let modes = null;
|
|
103
|
+
try { modes = JSON.parse(state?.temporal_modes ?? ''); } catch {}
|
|
104
|
+
const oneShot = Array.isArray(modes) ? modes.find(m => m.mode === 'one-shot-mount') : null;
|
|
105
|
+
const oneShotHas2 = oneShot?.members === 2 && Array.isArray(oneShot?.examples) && oneShot.examples.includes('title-block');
|
|
106
|
+
|
|
107
|
+
const results = {
|
|
108
|
+
has_entrance_class: state?.has_entrance_class === true,
|
|
109
|
+
entrance_attr_true: state?.entrance_attr === 'true',
|
|
110
|
+
envelope_breath_kept: state?.envelope_breath_kept === true,
|
|
111
|
+
css_keyframe_start: cssKfStart,
|
|
112
|
+
css_keyframe_end: cssKfEnd,
|
|
113
|
+
css_class_binds_500ms_delay_200: cssClassBound,
|
|
114
|
+
css_reduced_motion_guard: cssReducedMotion,
|
|
115
|
+
entrance_part_is_one_shot: entranceIsOneShot,
|
|
116
|
+
entrance_first_in_compound: entranceIsFirstInCompound,
|
|
117
|
+
transform_settled: transformSettled,
|
|
118
|
+
opacity_in_breath_band: opacityInBreathBand,
|
|
119
|
+
r740_canvas_entrance_kept: state?.canvas_entrance_class === true,
|
|
120
|
+
r741_one_shot_members_now_2: oneShotHas2,
|
|
121
|
+
};
|
|
122
|
+
const ok = Object.values(results).every(Boolean);
|
|
123
|
+
console.log(`${ok ? '✅' : '❌'} R742 title-block entrance animation (2nd one-shot member, staggered after canvas):`,
|
|
124
|
+
JSON.stringify(results, null, 2),
|
|
125
|
+
`\n state: ${JSON.stringify(state)}`,
|
|
126
|
+
`\n one-shot entry: ${JSON.stringify(oneShot)}`);
|
|
127
|
+
process.exit(ok ? 0 : 1);
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/* Round 706 — title-block wrapper envelope breath at 11s. Mirrors the
|
|
2
|
+
* canvas-brand-pair nested-envelope pattern (R704/R705) at the title-
|
|
3
|
+
* block scope. Creates triply-nested respiration: 3 inner trio anchors
|
|
4
|
+
* (brand-logo 5s + kicker 6s + H2 10s) inside outer wrapper (11s).
|
|
5
|
+
*
|
|
6
|
+
* 11s coprime with all 3 inner cadences (5, 6, 10) — no common factor.
|
|
7
|
+
* Tighter alpha (0.92 ↔ 1, ~8%) than canvas-brand envelopes since
|
|
8
|
+
* title-block carries primary text identity.
|
|
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'), mk('a·2')] } });
|
|
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-section-titleblock-group]', { timeout: 15000, state: 'attached' });
|
|
42
|
+
await page.waitForTimeout(300);
|
|
43
|
+
|
|
44
|
+
const runtimeState = await page.evaluate(() => {
|
|
45
|
+
const wrap = document.querySelector('[data-topo-section-titleblock-group]');
|
|
46
|
+
if (!wrap) return null;
|
|
47
|
+
const cs = getComputedStyle(wrap);
|
|
48
|
+
return {
|
|
49
|
+
has_class: wrap.classList.contains('anet-topo-title-block-envelope-breath'),
|
|
50
|
+
breath_attr: wrap.getAttribute('data-topo-section-titleblock-envelope-breath'),
|
|
51
|
+
anim_name: cs.animationName,
|
|
52
|
+
anim_duration: cs.animationDuration,
|
|
53
|
+
anim_iter: cs.animationIterationCount,
|
|
54
|
+
};
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
await browser.close();
|
|
58
|
+
|
|
59
|
+
const cssSrc = readFileSync('/home/vansin/agent-network-dashboard/app/globals.css', 'utf8');
|
|
60
|
+
const tsxSrc = readFileSync('/home/vansin/agent-network-dashboard/app/components/TopoGraph.tsx', 'utf8');
|
|
61
|
+
|
|
62
|
+
const cssKeyframes = /@keyframes anet-topo-title-block-envelope-breath-kf\s*\{[\s\S]*?0%, 100%\s*\{\s*opacity:\s*1;\s*\}[\s\S]*?50%\s*\{\s*opacity:\s*0\.92;/.test(cssSrc);
|
|
63
|
+
const cssRule = /\.anet-topo-title-block-envelope-breath\s*\{[\s\S]*?animation:\s*anet-topo-title-block-envelope-breath-kf\s+11s\s+ease-in-out\s+infinite/.test(cssSrc);
|
|
64
|
+
const cssReducedMotion = /prefers-reduced-motion:\s*reduce\s*\)\s*\{\s*\.anet-topo-title-block-envelope-breath\s*\{\s*animation:\s*none/.test(cssSrc);
|
|
65
|
+
const tsxClass = /anet-topo-title-block-envelope-breath group flex items-center gap-2\.5/.test(tsxSrc);
|
|
66
|
+
const tsxAttr = /data-topo-section-titleblock-envelope-breath="11s"/.test(tsxSrc);
|
|
67
|
+
|
|
68
|
+
const runtimeAnim = runtimeState?.anim_name === 'anet-topo-title-block-envelope-breath-kf' || runtimeState?.anim_name === 'none';
|
|
69
|
+
const runtimeDuration = runtimeState?.anim_duration === '11s' || runtimeState?.anim_name === 'none';
|
|
70
|
+
|
|
71
|
+
const results = {
|
|
72
|
+
wrapper_present: !!runtimeState,
|
|
73
|
+
has_breath_class: runtimeState?.has_class === true,
|
|
74
|
+
breath_attr_11s: runtimeState?.breath_attr === '11s',
|
|
75
|
+
runtime_anim_ok: runtimeAnim,
|
|
76
|
+
runtime_duration_ok: runtimeDuration,
|
|
77
|
+
css_keyframes: cssKeyframes,
|
|
78
|
+
css_rule: cssRule,
|
|
79
|
+
css_reduced_motion: cssReducedMotion,
|
|
80
|
+
tsx_class: tsxClass,
|
|
81
|
+
tsx_breath_attr: tsxAttr,
|
|
82
|
+
};
|
|
83
|
+
const ok = Object.values(results).every(Boolean);
|
|
84
|
+
console.log(`${ok ? '✅' : '❌'} R706 title-block wrapper envelope breath (11s, triply-nested respiration):`,
|
|
85
|
+
JSON.stringify(results, null, 2),
|
|
86
|
+
`\n runtime: ${JSON.stringify(runtimeState)}`);
|
|
87
|
+
process.exit(ok ? 0 : 1);
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/* Round 556 verification: title-block H2 "Command mesh" gains
|
|
2
|
+
* a 2nd editorial-emphasis axis — group-hover:font-bold paired
|
|
3
|
+
* with R554's group-hover:tracking-tighter.
|
|
4
|
+
*
|
|
5
|
+
* Test phases:
|
|
6
|
+
* 1. rest: fontWeight = 600 (semibold), letter-spacing ≈ -0.45px
|
|
7
|
+
* 2. hover brand logo (sibling, propagates via group-hover):
|
|
8
|
+
* H2 fontWeight = 700 (bold), letter-spacing ≈ -0.9px
|
|
9
|
+
* 3. transition-property contains BOTH letter-spacing AND font-weight
|
|
10
|
+
* 4. source-side regex confirms group-hover:font-bold wired
|
|
11
|
+
*/
|
|
12
|
+
import { chromium } from 'playwright';
|
|
13
|
+
import { readFileSync } from 'node:fs';
|
|
14
|
+
|
|
15
|
+
const TOKEN = JSON.parse(readFileSync('/home/vansin/.anet/config.json', 'utf8')).token;
|
|
16
|
+
const fresh = new Date(Date.now() - 60 * 1000).toISOString();
|
|
17
|
+
|
|
18
|
+
const browser = await chromium.launch({ headless: true });
|
|
19
|
+
const ctx = await browser.newContext({ viewport: { width: 1500, height: 1200 } });
|
|
20
|
+
await ctx.addCookies([{ name: 'anet_dashboard_session', value: `v3:${TOKEN}`, domain: '127.0.0.1', path: '/' }]);
|
|
21
|
+
await ctx.addInitScript(() => {
|
|
22
|
+
try {
|
|
23
|
+
localStorage.setItem('anet-theme', 'cyber');
|
|
24
|
+
localStorage.setItem('anet-topo-layout', 'ring');
|
|
25
|
+
sessionStorage.setItem('anet_v3_auth', '1');
|
|
26
|
+
} catch {}
|
|
27
|
+
});
|
|
28
|
+
await ctx.route('**/api/hub/status*', async (route) => {
|
|
29
|
+
const r = await route.fetch();
|
|
30
|
+
const b = await r.json();
|
|
31
|
+
const nid = (b.sessions || [])[0]?.network_id || 'default';
|
|
32
|
+
const mk = (alias) => ({
|
|
33
|
+
alias, status: 'idle', model: 'claude-opus-4', runtime: 'claude-code-cli',
|
|
34
|
+
network_id: nid, project_dir: null,
|
|
35
|
+
created_at: fresh, updated_at: fresh, last_seen_at: fresh,
|
|
36
|
+
});
|
|
37
|
+
await route.fulfill({ response: r, json: { ...b, sessions: [mk('a·1')] } });
|
|
38
|
+
});
|
|
39
|
+
await ctx.route('**/api/hub/messages*', (r) => r.fulfill({ json: { messages: [] } }));
|
|
40
|
+
await ctx.route('**/api/hub/tasks*', (r) => r.fulfill({ json: { tasks: [] } }));
|
|
41
|
+
const page = await ctx.newPage();
|
|
42
|
+
await page.goto('http://127.0.0.1:3000/', { waitUntil: 'networkidle' });
|
|
43
|
+
await page.waitForSelector('[data-topo-section-title]', { timeout: 15000 });
|
|
44
|
+
await page.waitForTimeout(500);
|
|
45
|
+
|
|
46
|
+
const h2Sel = '[data-topo-section-title]';
|
|
47
|
+
const logoSel = '[data-topo-brand-logo]';
|
|
48
|
+
|
|
49
|
+
const parsePx = (s) => parseFloat((s || '').replace(/px$/, ''));
|
|
50
|
+
|
|
51
|
+
// Phase 1: rest
|
|
52
|
+
const rest = await page.evaluate((s) => {
|
|
53
|
+
const el = document.querySelector(s);
|
|
54
|
+
if (!el) return null;
|
|
55
|
+
const cs = getComputedStyle(el);
|
|
56
|
+
return {
|
|
57
|
+
fontWeight: cs.fontWeight,
|
|
58
|
+
letterSpacing: cs.letterSpacing,
|
|
59
|
+
transitionProperty: cs.transitionProperty,
|
|
60
|
+
transitionDuration: cs.transitionDuration,
|
|
61
|
+
hoverFwAttr: el.getAttribute('data-topo-section-title-hover-fw'),
|
|
62
|
+
hoverTrackingAttr: el.getAttribute('data-topo-section-title-hover-tracking'),
|
|
63
|
+
};
|
|
64
|
+
}, h2Sel);
|
|
65
|
+
|
|
66
|
+
// Phase 2: hover brand logo (sibling) → group-hover propagates
|
|
67
|
+
await page.hover(logoSel);
|
|
68
|
+
await page.waitForTimeout(400);
|
|
69
|
+
const hover = await page.evaluate((s) => {
|
|
70
|
+
const el = document.querySelector(s);
|
|
71
|
+
if (!el) return null;
|
|
72
|
+
const cs = getComputedStyle(el);
|
|
73
|
+
return { fontWeight: cs.fontWeight, letterSpacing: cs.letterSpacing };
|
|
74
|
+
}, h2Sel);
|
|
75
|
+
|
|
76
|
+
await browser.close();
|
|
77
|
+
|
|
78
|
+
const src = readFileSync('/home/vansin/agent-network-dashboard/app/components/TopoGraph.tsx', 'utf8');
|
|
79
|
+
const sourceFwWired = /group-hover:font-bold/.test(src);
|
|
80
|
+
const sourceTransition = /transition-\[letter-spacing,font-weight\] duration-200 ease-out/.test(src);
|
|
81
|
+
const sourceFwAttr = /data-topo-section-title-hover-fw="700"/.test(src);
|
|
82
|
+
|
|
83
|
+
const restPx = parsePx(rest?.letterSpacing);
|
|
84
|
+
const hoverPx = parsePx(hover?.letterSpacing);
|
|
85
|
+
|
|
86
|
+
const results = {
|
|
87
|
+
rest_fw_semibold: rest?.fontWeight === '600',
|
|
88
|
+
rest_tracking_tight: Math.abs(restPx - (-0.45)) < 0.05,
|
|
89
|
+
hover_fw_bold: hover?.fontWeight === '700',
|
|
90
|
+
hover_tracking_tighter: Math.abs(hoverPx - (-0.9)) < 0.05,
|
|
91
|
+
// Both axes intensify together — confirm by directionality
|
|
92
|
+
fw_intensifies: parseInt(hover?.fontWeight || '0') > parseInt(rest?.fontWeight || '0'),
|
|
93
|
+
tracking_intensifies: hoverPx < restPx - 0.3, // more negative = tighter
|
|
94
|
+
transition_has_ls: /letter-spacing/.test(rest?.transitionProperty || ''),
|
|
95
|
+
transition_has_fw: /font-weight/.test(rest?.transitionProperty || ''),
|
|
96
|
+
transition_duration: rest?.transitionDuration === '0.2s',
|
|
97
|
+
rest_hover_fw_attr: rest?.hoverFwAttr === '700',
|
|
98
|
+
rest_hover_tracking_attr: rest?.hoverTrackingAttr === 'tracking-tighter',
|
|
99
|
+
source_fw_wired: sourceFwWired,
|
|
100
|
+
source_transition: sourceTransition,
|
|
101
|
+
source_fw_attr: sourceFwAttr,
|
|
102
|
+
};
|
|
103
|
+
const ok = Object.values(results).every(Boolean);
|
|
104
|
+
console.log(`${ok ? '✅' : '❌'} R556 title-block H2 group-hover:font-bold (2-axis editorial emphasis):`,
|
|
105
|
+
JSON.stringify(results, null, 2),
|
|
106
|
+
`\n rest: fw=${rest?.fontWeight}, ls=${rest?.letterSpacing}`,
|
|
107
|
+
`\n hover: fw=${hover?.fontWeight}, ls=${hover?.letterSpacing}`,
|
|
108
|
+
`\n transition: ${rest?.transitionProperty}`);
|
|
109
|
+
process.exit(ok ? 0 : 1);
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/* Round 554 verification: title-block H2 "Command mesh" gains
|
|
2
|
+
* group-hover:tracking-tighter via the wrapper's `group` flag.
|
|
3
|
+
* Hovering the brand logo OR the title text should tighten the
|
|
4
|
+
* H2's kerning from -0.025em → -0.05em.
|
|
5
|
+
*
|
|
6
|
+
* Tailwind tracking utilities map to letter-spacing CSS:
|
|
7
|
+
* tracking-tight -0.025em
|
|
8
|
+
* tracking-tighter -0.05em
|
|
9
|
+
*
|
|
10
|
+
* At text-lg (18px font-size):
|
|
11
|
+
* tracking-tight = -0.45px
|
|
12
|
+
* tracking-tighter = -0.9px
|
|
13
|
+
*
|
|
14
|
+
* Test phases:
|
|
15
|
+
* 1. rest: H2 letter-spacing ≈ -0.45px (tracking-tight)
|
|
16
|
+
* 2. hover brand logo: H2 letter-spacing ≈ -0.9px (tracking-tighter)
|
|
17
|
+
* Verifies group-hover propagation from sibling element.
|
|
18
|
+
* 3. hover H2 itself: letter-spacing ≈ -0.9px (same)
|
|
19
|
+
* 4. source: wrapper has `group`, H2 has group-hover:tracking-tighter
|
|
20
|
+
*/
|
|
21
|
+
import { chromium } from 'playwright';
|
|
22
|
+
import { readFileSync } from 'node:fs';
|
|
23
|
+
|
|
24
|
+
const TOKEN = JSON.parse(readFileSync('/home/vansin/.anet/config.json', 'utf8')).token;
|
|
25
|
+
const fresh = new Date(Date.now() - 60 * 1000).toISOString();
|
|
26
|
+
|
|
27
|
+
const browser = await chromium.launch({ headless: true });
|
|
28
|
+
const ctx = await browser.newContext({ viewport: { width: 1500, height: 1200 } });
|
|
29
|
+
await ctx.addCookies([{ name: 'anet_dashboard_session', value: `v3:${TOKEN}`, domain: '127.0.0.1', path: '/' }]);
|
|
30
|
+
await ctx.addInitScript(() => {
|
|
31
|
+
try {
|
|
32
|
+
localStorage.setItem('anet-theme', 'cyber');
|
|
33
|
+
localStorage.setItem('anet-topo-layout', 'ring');
|
|
34
|
+
sessionStorage.setItem('anet_v3_auth', '1');
|
|
35
|
+
} catch {}
|
|
36
|
+
});
|
|
37
|
+
await ctx.route('**/api/hub/status*', async (route) => {
|
|
38
|
+
const r = await route.fetch();
|
|
39
|
+
const b = await r.json();
|
|
40
|
+
const nid = (b.sessions || [])[0]?.network_id || 'default';
|
|
41
|
+
const mk = (alias) => ({
|
|
42
|
+
alias, status: 'idle', model: 'claude-opus-4', runtime: 'claude-code-cli',
|
|
43
|
+
network_id: nid, project_dir: null,
|
|
44
|
+
created_at: fresh, updated_at: fresh, last_seen_at: fresh,
|
|
45
|
+
});
|
|
46
|
+
await route.fulfill({ response: r, json: { ...b, sessions: [mk('a·1')] } });
|
|
47
|
+
});
|
|
48
|
+
await ctx.route('**/api/hub/messages*', (r) => r.fulfill({ json: { messages: [] } }));
|
|
49
|
+
await ctx.route('**/api/hub/tasks*', (r) => r.fulfill({ json: { tasks: [] } }));
|
|
50
|
+
const page = await ctx.newPage();
|
|
51
|
+
await page.goto('http://127.0.0.1:3000/', { waitUntil: 'networkidle' });
|
|
52
|
+
await page.waitForSelector('[data-topo-section-title]', { timeout: 15000 });
|
|
53
|
+
await page.waitForTimeout(500);
|
|
54
|
+
|
|
55
|
+
const h2Sel = '[data-topo-section-title]';
|
|
56
|
+
const logoSel = '[data-topo-brand-logo]';
|
|
57
|
+
|
|
58
|
+
const parsePx = (s) => parseFloat((s || '').replace(/px$/, ''));
|
|
59
|
+
|
|
60
|
+
// Phase 1: rest
|
|
61
|
+
const rest = await page.evaluate((s) => {
|
|
62
|
+
const el = document.querySelector(s);
|
|
63
|
+
if (!el) return null;
|
|
64
|
+
const cs = getComputedStyle(el);
|
|
65
|
+
return {
|
|
66
|
+
letterSpacing: cs.letterSpacing,
|
|
67
|
+
transitionProperty: cs.transitionProperty,
|
|
68
|
+
transitionDuration: cs.transitionDuration,
|
|
69
|
+
fontSize: cs.fontSize,
|
|
70
|
+
hoverAttr: el.getAttribute('data-topo-section-title-hover-tracking'),
|
|
71
|
+
};
|
|
72
|
+
}, h2Sel);
|
|
73
|
+
|
|
74
|
+
// Phase 2: hover brand logo (different element, but same group → H2 should tighten)
|
|
75
|
+
await page.hover(logoSel);
|
|
76
|
+
await page.waitForTimeout(400);
|
|
77
|
+
const hoverLogo = await page.evaluate((s) => {
|
|
78
|
+
const el = document.querySelector(s);
|
|
79
|
+
if (!el) return null;
|
|
80
|
+
const cs = getComputedStyle(el);
|
|
81
|
+
return { letterSpacing: cs.letterSpacing };
|
|
82
|
+
}, h2Sel);
|
|
83
|
+
|
|
84
|
+
// Phase 3: hover H2 itself (cross-confirm)
|
|
85
|
+
await page.mouse.move(0, 0);
|
|
86
|
+
await page.waitForTimeout(300);
|
|
87
|
+
await page.hover(h2Sel);
|
|
88
|
+
await page.waitForTimeout(400);
|
|
89
|
+
const hoverH2 = await page.evaluate((s) => {
|
|
90
|
+
const el = document.querySelector(s);
|
|
91
|
+
if (!el) return null;
|
|
92
|
+
const cs = getComputedStyle(el);
|
|
93
|
+
return { letterSpacing: cs.letterSpacing };
|
|
94
|
+
}, h2Sel);
|
|
95
|
+
|
|
96
|
+
await browser.close();
|
|
97
|
+
|
|
98
|
+
const src = readFileSync('/home/vansin/agent-network-dashboard/app/components/TopoGraph.tsx', 'utf8');
|
|
99
|
+
const sourceGroupWrapper = /<div className="group flex items-center gap-2\.5" data-topo-section-titleblock-group>/.test(src);
|
|
100
|
+
const sourceH2HoverTracking = /group-hover:tracking-tighter/.test(src);
|
|
101
|
+
const sourceH2HoverAttr = /data-topo-section-title-hover-tracking="tracking-tighter"/.test(src);
|
|
102
|
+
|
|
103
|
+
// Rest ≈ -0.45px (-0.025em × 18px), hover ≈ -0.9px (-0.05em × 18px)
|
|
104
|
+
const restPx = parsePx(rest?.letterSpacing);
|
|
105
|
+
const hoverLogoPx = parsePx(hoverLogo?.letterSpacing);
|
|
106
|
+
const hoverH2Px = parsePx(hoverH2?.letterSpacing);
|
|
107
|
+
|
|
108
|
+
const results = {
|
|
109
|
+
rest_attr_present: rest?.hoverAttr === 'tracking-tighter',
|
|
110
|
+
rest_tracking_tight: Math.abs(restPx - (-0.45)) < 0.05,
|
|
111
|
+
hover_via_logo_tightens: Math.abs(hoverLogoPx - (-0.9)) < 0.05,
|
|
112
|
+
hover_via_h2_tightens: Math.abs(hoverH2Px - (-0.9)) < 0.05,
|
|
113
|
+
hover_tighter_than_rest: hoverLogoPx < restPx - 0.3,
|
|
114
|
+
transition_has_letter_spacing: /letter-spacing/.test(rest?.transitionProperty || ''),
|
|
115
|
+
transition_duration_200ms: rest?.transitionDuration === '0.2s',
|
|
116
|
+
source_group_wrapper: sourceGroupWrapper,
|
|
117
|
+
source_h2_group_hover: sourceH2HoverTracking,
|
|
118
|
+
source_h2_attr: sourceH2HoverAttr,
|
|
119
|
+
};
|
|
120
|
+
const ok = Object.values(results).every(Boolean);
|
|
121
|
+
console.log(`${ok ? '✅' : '❌'} R554 title-block H2 group-hover:tracking-tighter:`,
|
|
122
|
+
JSON.stringify(results, null, 2),
|
|
123
|
+
`\n rest letter-spacing: ${rest?.letterSpacing} (expect ≈ -0.45px)`,
|
|
124
|
+
`\n hover-via-logo: ${hoverLogo?.letterSpacing} (expect ≈ -0.9px)`,
|
|
125
|
+
`\n hover-via-h2: ${hoverH2?.letterSpacing} (expect ≈ -0.9px)`,
|
|
126
|
+
`\n font-size: ${rest?.fontSize}`,
|
|
127
|
+
`\n transition-property: ${rest?.transitionProperty}`);
|
|
128
|
+
process.exit(ok ? 0 : 1);
|