@sleep2agi/agent-network-dashboard 0.5.3-preview.99 → 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 +3 -3
- 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/{084e1mr6acfta.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 +4591 -216
- package/app/globals.css +839 -0
- 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-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-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-halo-layers-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-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-envelope-breath-test.mjs +103 -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-chat-gate-test.mjs +71 -0
- package/scripts/topo-edge-flow-rail-halo-layers-test.mjs +89 -0
- package/scripts/topo-edge-particle-halo-layers-test.mjs +91 -0
- package/scripts/topo-edge-pin-halo-test.mjs +99 -0
- package/scripts/topo-edge-visible-halo-layers-test.mjs +87 -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-halo-layers-test.mjs +27 -0
- package/scripts/topo-flow-arrow-brightness-test.mjs +82 -0
- package/scripts/topo-fullscreen-brightness-test.mjs +84 -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-halo-layers-test.mjs +78 -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-halo-layers-test.mjs +76 -0
- package/scripts/topo-hub-halo-halo-layers-test.mjs +76 -0
- package/scripts/topo-hub-highlight-halo-layers-test.mjs +78 -0
- package/scripts/topo-hub-hover-ring-halo-layers-test.mjs +71 -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-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-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-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-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-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-nodesize-brightness-test.mjs +82 -0
- package/scripts/topo-nodesize-halo-layers-test.mjs +89 -0
- package/scripts/topo-overlap-test.mjs +22 -8
- package/scripts/topo-panel-count-halo-layers-test.mjs +91 -0
- package/scripts/topo-panel-rect-halo-test.mjs +90 -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-pip-brightness-test.mjs +85 -0
- package/scripts/topo-pressure-bar-halo-layers-test.mjs +19 -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-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-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-reset-brightness-test.mjs +83 -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-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-status-pin-pill-halo-layers-test.mjs +17 -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-tree-diag.mjs +95 -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-watermark-dual-axis-breath-test.mjs +88 -0
- package/scripts/topo-watermark-envelope-breath-test.mjs +88 -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-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/09oxd2mm27b_n.js +0 -1
- package/.next/static/chunks/0ots8-uksxz9p.js +0 -4
- package/.next/static/chunks/0voxs92keb6tg.js +0 -1
- package/.next/static/chunks/13~aih56vx-cf.css +0 -2
- /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/{Ha31LjrNJgJIEydZivRlp → xq88BMF7fMUHWh10yaKTn}/_buildManifest.js +0 -0
- /package/.next/static/{Ha31LjrNJgJIEydZivRlp → xq88BMF7fMUHWh10yaKTn}/_clientMiddlewareManifest.js +0 -0
- /package/.next/static/{Ha31LjrNJgJIEydZivRlp → xq88BMF7fMUHWh10yaKTn}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/* Round 686 — active-links chip extends from 4+ hover axes (bg/text/
|
|
2
|
+
* border swap + translate-y) to add multi-layer halo paint axis.
|
|
3
|
+
* Inline filter conditional on hoveredActiveLinks state (existing,
|
|
4
|
+
* line 1098) gates 2-layer drop-shadow at pal.legendAccent tint with
|
|
5
|
+
* 2+4 stride, alpha 80/40. 45th anchor — first active-links anchor.
|
|
6
|
+
*
|
|
7
|
+
* Source assertions:
|
|
8
|
+
* - filter chain uses pal.legendAccent at 80/40 with 2+4 stride,
|
|
9
|
+
* gated on hoveredActiveLinks && isInteractive
|
|
10
|
+
* - data-active-links-chip-halo-layers attr toggles '2' ↔ '0'
|
|
11
|
+
*
|
|
12
|
+
* Runtime assertions:
|
|
13
|
+
* - active-links chip present (renders when sessions exist)
|
|
14
|
+
* - rest halo-layers='0'
|
|
15
|
+
* - chip is interactive when flowLinks > 0 (mock messages create flows)
|
|
16
|
+
*/
|
|
17
|
+
import { chromium } from 'playwright';
|
|
18
|
+
import { readFileSync } from 'node:fs';
|
|
19
|
+
|
|
20
|
+
const TOKEN = JSON.parse(readFileSync('/home/vansin/.anet/config.json', 'utf8')).token;
|
|
21
|
+
const fresh = new Date(Date.now() - 60 * 1000).toISOString();
|
|
22
|
+
|
|
23
|
+
const browser = await chromium.launch({ headless: true });
|
|
24
|
+
const ctx = await browser.newContext({ viewport: { width: 1500, height: 1200 } });
|
|
25
|
+
await ctx.addCookies([{ name: 'anet_dashboard_session', value: `v3:${TOKEN}`, domain: '127.0.0.1', path: '/' }]);
|
|
26
|
+
await ctx.addInitScript(() => {
|
|
27
|
+
try {
|
|
28
|
+
localStorage.setItem('anet-theme', 'cyber');
|
|
29
|
+
localStorage.setItem('anet-topo-layout', 'ring');
|
|
30
|
+
sessionStorage.setItem('anet_v3_auth', '1');
|
|
31
|
+
} catch {}
|
|
32
|
+
});
|
|
33
|
+
await ctx.route('**/api/hub/status*', async (route) => {
|
|
34
|
+
const r = await route.fetch();
|
|
35
|
+
const b = await r.json();
|
|
36
|
+
const nid = (b.sessions || [])[0]?.network_id || 'default';
|
|
37
|
+
const mk = (alias) => ({
|
|
38
|
+
alias, status: 'idle', model: 'claude-opus-4', runtime: 'claude-code-cli',
|
|
39
|
+
network_id: nid, project_dir: null,
|
|
40
|
+
created_at: fresh, updated_at: fresh, last_seen_at: fresh,
|
|
41
|
+
});
|
|
42
|
+
await route.fulfill({ response: r, json: { ...b, sessions: [mk('a·1'), mk('a·2'), mk('a·3')] } });
|
|
43
|
+
});
|
|
44
|
+
await ctx.route('**/api/hub/messages*', (r) => r.fulfill({ json: { messages: [
|
|
45
|
+
{ id: 'm1', from_alias: 'a·1', to_alias: 'a·2', kind: 'message', content: 'p', network_id: 'default', created_at: fresh },
|
|
46
|
+
{ id: 'm2', from_alias: 'a·2', to_alias: 'a·3', kind: 'task', content: 'p2', network_id: 'default', created_at: fresh },
|
|
47
|
+
] } }));
|
|
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-active-links-chip]', { timeout: 15000, state: 'attached' });
|
|
52
|
+
await page.waitForTimeout(300);
|
|
53
|
+
|
|
54
|
+
const runtimeState = await page.evaluate(() => {
|
|
55
|
+
const chip = document.querySelector('[data-active-links-chip]');
|
|
56
|
+
return chip ? {
|
|
57
|
+
halo_layers: chip.getAttribute('data-active-links-chip-halo-layers'),
|
|
58
|
+
interactive: chip.getAttribute('data-active-links-clickable'),
|
|
59
|
+
flow_count: chip.getAttribute('data-active-links-flow-count'),
|
|
60
|
+
} : null;
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
await browser.close();
|
|
64
|
+
|
|
65
|
+
const src = readFileSync('/home/vansin/agent-network-dashboard/app/components/TopoGraph.tsx', 'utf8');
|
|
66
|
+
const sourceFilter = /filter: hoveredActiveLinks && isInteractive\s*\?\s*`drop-shadow\(0 0 2px \$\{pal\.legendAccent\}80\) drop-shadow\(0 0 4px \$\{pal\.legendAccent\}40\)`\s*: undefined/.test(src);
|
|
67
|
+
const sourceAttr = /data-active-links-chip-halo-layers=\{hoveredActiveLinks && isInteractive \? '2' : '0'\}/.test(src);
|
|
68
|
+
|
|
69
|
+
const results = {
|
|
70
|
+
chip_present: !!runtimeState,
|
|
71
|
+
rest_layers_zero: runtimeState?.halo_layers === '0',
|
|
72
|
+
is_interactive: runtimeState?.interactive === 'true',
|
|
73
|
+
has_flows: runtimeState && parseInt(runtimeState.flow_count, 10) >= 1,
|
|
74
|
+
source_filter: sourceFilter,
|
|
75
|
+
source_layers_attr: sourceAttr,
|
|
76
|
+
};
|
|
77
|
+
const ok = Object.values(results).every(Boolean);
|
|
78
|
+
console.log(`${ok ? '✅' : '❌'} R686 active-links chip multi-layer halo (first active-links anchor):`,
|
|
79
|
+
JSON.stringify(results, null, 2),
|
|
80
|
+
`\n runtime: ${JSON.stringify(runtimeState)}`);
|
|
81
|
+
process.exit(ok ? 0 : 1);
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/* Round 616 — alias text brightness gate extends from hover-only
|
|
2
|
+
* to (hover || chat-target). 2nd anchor in chat-target-gated
|
|
3
|
+
* brightness family (sibling to R615 chat ring).
|
|
4
|
+
*
|
|
5
|
+
* Test phases:
|
|
6
|
+
* 1. mock 2 idle nodes → alias text renders
|
|
7
|
+
* 2. rest (no hover, no chat): filter='none', brightness-attr='1'
|
|
8
|
+
* 3. computed transition-property contains 'filter'
|
|
9
|
+
* 4. source: filter conditional includes BOTH hover AND chat
|
|
10
|
+
* gates, joined by `||`
|
|
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'), mk('a·2')] } });
|
|
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-node-alias-text]', { timeout: 15000, state: 'attached' });
|
|
44
|
+
await page.waitForTimeout(500);
|
|
45
|
+
|
|
46
|
+
const rest = await page.evaluate(() => {
|
|
47
|
+
const el = document.querySelector('[data-node-alias-text]');
|
|
48
|
+
if (!el) return null;
|
|
49
|
+
const cs = getComputedStyle(el);
|
|
50
|
+
return {
|
|
51
|
+
filter: cs.filter,
|
|
52
|
+
transitionProperty: cs.transitionProperty,
|
|
53
|
+
brightnessAttr: el.getAttribute('data-node-alias-brightness'),
|
|
54
|
+
hoveredAttr: el.getAttribute('data-node-alias-hovered'),
|
|
55
|
+
chatTargetAttr: el.getAttribute('data-node-alias-chat-target'),
|
|
56
|
+
};
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
await browser.close();
|
|
60
|
+
|
|
61
|
+
const src = readFileSync('/home/vansin/agent-network-dashboard/app/components/TopoGraph.tsx', 'utf8');
|
|
62
|
+
const sourceFilter = /filter: !reducedMotion && \(hoveredAlias === session\.alias \|\| chatAlias === session\.alias\)\s*\?\s*`drop-shadow\(0 0 2px \$\{status\.text\}80\) brightness\(1\.15\)`\s*:\s*undefined/.test(src);
|
|
63
|
+
const sourceAttr = /data-node-alias-brightness=\{!reducedMotion && \(hoveredAlias === session\.alias \|\| chatAlias === session\.alias\) \? '1\.15' : '1'\}/.test(src);
|
|
64
|
+
|
|
65
|
+
const results = {
|
|
66
|
+
alias_present: !!rest,
|
|
67
|
+
rest_filter_none: rest?.filter === 'none',
|
|
68
|
+
rest_brightness_1: rest?.brightnessAttr === '1',
|
|
69
|
+
rest_hovered_false: rest?.hoveredAttr === 'false',
|
|
70
|
+
rest_chat_target_false: rest?.chatTargetAttr === 'false',
|
|
71
|
+
transition_has_filter: /filter/.test(rest?.transitionProperty || ''),
|
|
72
|
+
source_filter_or_gate: sourceFilter,
|
|
73
|
+
source_attr_or_gate: sourceAttr,
|
|
74
|
+
};
|
|
75
|
+
const ok = Object.values(results).every(Boolean);
|
|
76
|
+
console.log(`${ok ? '✅' : '❌'} R616 alias chat-target brightness (chat-gated family 2/N):`,
|
|
77
|
+
JSON.stringify(results, null, 2),
|
|
78
|
+
`\n rest: ${JSON.stringify(rest)}`);
|
|
79
|
+
process.exit(ok ? 0 : 1);
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/* Round 645 — node alias text gains a SECOND drop-shadow layer at
|
|
2
|
+
* 4px blur + 0x40 alpha. Extends the chromatic-identity 2-layer
|
|
3
|
+
* halo family from rings (R642/R643/R644) to TEXT — first text-
|
|
4
|
+
* scope multi-layer halo anchor.
|
|
5
|
+
*
|
|
6
|
+
* Test phases:
|
|
7
|
+
* 1. rest: alias text halo-layers='0', no filter
|
|
8
|
+
* 2. click a·1 → chat-target gate fires → alias text halo-layers='2',
|
|
9
|
+
* computed filter has EXACTLY 2 drop-shadow substrings with
|
|
10
|
+
* status.text tint at different alphas
|
|
11
|
+
* 3. source: filter expression stacks 2 drop-shadows
|
|
12
|
+
*/
|
|
13
|
+
import { chromium } from 'playwright';
|
|
14
|
+
import { readFileSync } from 'node:fs';
|
|
15
|
+
|
|
16
|
+
const TOKEN = JSON.parse(readFileSync('/home/vansin/.anet/config.json', 'utf8')).token;
|
|
17
|
+
const fresh = new Date(Date.now() - 60 * 1000).toISOString();
|
|
18
|
+
|
|
19
|
+
const browser = await chromium.launch({ headless: true });
|
|
20
|
+
const ctx = await browser.newContext({ viewport: { width: 1500, height: 1200 } });
|
|
21
|
+
await ctx.addCookies([{ name: 'anet_dashboard_session', value: `v3:${TOKEN}`, domain: '127.0.0.1', path: '/' }]);
|
|
22
|
+
await ctx.addInitScript(() => {
|
|
23
|
+
try {
|
|
24
|
+
localStorage.setItem('anet-theme', 'cyber');
|
|
25
|
+
localStorage.setItem('anet-topo-layout', 'ring');
|
|
26
|
+
sessionStorage.setItem('anet_v3_auth', '1');
|
|
27
|
+
} catch {}
|
|
28
|
+
});
|
|
29
|
+
await ctx.route('**/api/hub/status*', async (route) => {
|
|
30
|
+
const r = await route.fetch();
|
|
31
|
+
const b = await r.json();
|
|
32
|
+
const nid = (b.sessions || [])[0]?.network_id || 'default';
|
|
33
|
+
const mk = (alias) => ({
|
|
34
|
+
alias, status: 'idle', model: 'claude-opus-4', runtime: 'claude-code-cli',
|
|
35
|
+
network_id: nid, project_dir: null,
|
|
36
|
+
created_at: fresh, updated_at: fresh, last_seen_at: fresh,
|
|
37
|
+
});
|
|
38
|
+
await route.fulfill({ response: r, json: { ...b, sessions: [mk('a·1'), mk('a·2')] } });
|
|
39
|
+
});
|
|
40
|
+
await ctx.route('**/api/hub/messages*', (r) => r.fulfill({ json: { messages: [] } }));
|
|
41
|
+
await ctx.route('**/api/hub/tasks*', (r) => r.fulfill({ json: { tasks: [] } }));
|
|
42
|
+
const page = await ctx.newPage();
|
|
43
|
+
await page.goto('http://127.0.0.1:3000/', { waitUntil: 'networkidle' });
|
|
44
|
+
await page.waitForSelector('[data-node-alias-text]', { timeout: 15000, state: 'attached' });
|
|
45
|
+
await page.waitForTimeout(500);
|
|
46
|
+
|
|
47
|
+
const restTexts = await page.evaluate(() => {
|
|
48
|
+
return Array.from(document.querySelectorAll('[data-node-alias-text]')).map(el => ({
|
|
49
|
+
layers: el.getAttribute('data-node-alias-halo-layers'),
|
|
50
|
+
glow: el.getAttribute('data-node-alias-glow'),
|
|
51
|
+
chatTarget: el.getAttribute('data-node-alias-chat-target'),
|
|
52
|
+
}));
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
await page.click('[data-node="a·1"]', { force: true });
|
|
56
|
+
await page.waitForTimeout(400);
|
|
57
|
+
|
|
58
|
+
const chatState = await page.evaluate(() => {
|
|
59
|
+
return Array.from(document.querySelectorAll('[data-node-alias-text]')).map(el => {
|
|
60
|
+
const cs = getComputedStyle(el);
|
|
61
|
+
return {
|
|
62
|
+
alias: el.getAttribute('data-node-alias-text'),
|
|
63
|
+
layers: el.getAttribute('data-node-alias-halo-layers'),
|
|
64
|
+
chatTarget: el.getAttribute('data-node-alias-chat-target'),
|
|
65
|
+
filter: cs.filter,
|
|
66
|
+
};
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
await browser.close();
|
|
71
|
+
|
|
72
|
+
const src = readFileSync('/home/vansin/agent-network-dashboard/app/components/TopoGraph.tsx', 'utf8');
|
|
73
|
+
const sourceFilter = /`drop-shadow\(0 0 2px \$\{status\.text\}80\) drop-shadow\(0 0 4px \$\{status\.text\}40\) brightness\(1\.15\)`/.test(src);
|
|
74
|
+
const sourceLayersAttr = /data-node-alias-halo-layers=\{!reducedMotion && \(hoveredAlias === session\.alias \|\| chatAlias === session\.alias\) \? '2' : '0'\}/.test(src);
|
|
75
|
+
|
|
76
|
+
const restAllZero = restTexts.every(t => t.layers === '0');
|
|
77
|
+
const chatActive = chatState.find(c => c.alias === 'a·1');
|
|
78
|
+
const chatActiveDropShadowCount = (chatActive?.filter?.match(/drop-shadow/g) || []).length;
|
|
79
|
+
const chatIdle = chatState.find(c => c.alias === 'a·2');
|
|
80
|
+
|
|
81
|
+
const results = {
|
|
82
|
+
texts_present: restTexts.length >= 2,
|
|
83
|
+
rest_all_zero: restAllZero,
|
|
84
|
+
chat_a1_present: !!chatActive,
|
|
85
|
+
chat_a1_layers_2: chatActive?.layers === '2',
|
|
86
|
+
chat_a1_chat_target_true:chatActive?.chatTarget === 'true',
|
|
87
|
+
chat_a1_two_dropshadows: chatActiveDropShadowCount === 2,
|
|
88
|
+
chat_a1_brightness: /brightness/.test(chatActive?.filter || ''),
|
|
89
|
+
chat_a2_layers_0: chatIdle?.layers === '0',
|
|
90
|
+
source_filter: sourceFilter,
|
|
91
|
+
source_layers_attr: sourceLayersAttr,
|
|
92
|
+
};
|
|
93
|
+
const ok = Object.values(results).every(Boolean);
|
|
94
|
+
console.log(`${ok ? '✅' : '❌'} R645 node alias text multi-layer halo (text-scope chromatic identity):`,
|
|
95
|
+
JSON.stringify(results, null, 2),
|
|
96
|
+
`\n rest: ${JSON.stringify(restTexts)}`,
|
|
97
|
+
`\n chat: ${JSON.stringify(chatState)}`);
|
|
98
|
+
process.exit(ok ? 0 : 1);
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
/* Round 741 — animation temporal modes catalog. 8TH orthogonal
|
|
2
|
+
* meta-doc axis on the topology introspection layer. Octagon:
|
|
3
|
+
*
|
|
4
|
+
* R710 rolodex (cadences) breath
|
|
5
|
+
* R716 dual-axis-surfaces (axes) breath
|
|
6
|
+
* R717 patterns (structural shapes) cross-family
|
|
7
|
+
* R720 tiers (functional roles) breath
|
|
8
|
+
* R723 triple-axis-surfaces (multi-axis) breath
|
|
9
|
+
* R729 axis-count-stats (aggregate stats) breath + cross-family
|
|
10
|
+
* R732 a11y-titles (accessible names) a11y
|
|
11
|
+
* R741 animation-temporal-modes (lifecycle) cross-family ← this round
|
|
12
|
+
*
|
|
13
|
+
* Documents WHEN animations run rather than HOW. Three temporal
|
|
14
|
+
* modes after R740:
|
|
15
|
+
* infinite-rest → breath family 18 members
|
|
16
|
+
* infinite-sweep → ambient family 3 members
|
|
17
|
+
* one-shot-mount → entrance family 1 member
|
|
18
|
+
*
|
|
19
|
+
* Cross-validation against runtime:
|
|
20
|
+
* - infinite-rest member count: rolodex (R710) flat anchor count = 18
|
|
21
|
+
* - infinite-sweep member count: scan-beam-trio (R717) anchors = 3
|
|
22
|
+
* OR distinct anchors across ambient patterns in R717
|
|
23
|
+
* - one-shot-mount member count: 1 (canvas root entrance only)
|
|
24
|
+
*
|
|
25
|
+
* Assertions:
|
|
26
|
+
* - attr present on root <svg>
|
|
27
|
+
* - JSON parses to Array of exactly 3 entries
|
|
28
|
+
* - shape: each entry has {mode, family, members, examples}
|
|
29
|
+
* - modes sorted = ['infinite-rest', 'infinite-sweep', 'one-shot-mount']
|
|
30
|
+
* - families sorted = ['ambient', 'breath', 'entrance']
|
|
31
|
+
* - members are positive integers
|
|
32
|
+
* - examples is non-empty array of strings (≤3 per mode)
|
|
33
|
+
* - Cross-check: infinite-rest.members === R710 rolodex anchor count
|
|
34
|
+
* - Cross-check: infinite-sweep.members === scan-beam-trio anchor count (3)
|
|
35
|
+
* - Cross-check: one-shot-mount.members === 1
|
|
36
|
+
*/
|
|
37
|
+
import { chromium } from 'playwright';
|
|
38
|
+
import { readFileSync } from 'node:fs';
|
|
39
|
+
|
|
40
|
+
const TOKEN = JSON.parse(readFileSync('/home/vansin/.anet/config.json', 'utf8')).token;
|
|
41
|
+
const fresh = new Date(Date.now() - 60 * 1000).toISOString();
|
|
42
|
+
|
|
43
|
+
const browser = await chromium.launch({ headless: true });
|
|
44
|
+
const ctx = await browser.newContext({ viewport: { width: 1500, height: 1200 } });
|
|
45
|
+
await ctx.addCookies([{ name: 'anet_dashboard_session', value: `v3:${TOKEN}`, domain: '127.0.0.1', path: '/' }]);
|
|
46
|
+
await ctx.addInitScript(() => {
|
|
47
|
+
try {
|
|
48
|
+
localStorage.setItem('anet-theme', 'cyber');
|
|
49
|
+
localStorage.setItem('anet-topo-layout', 'ring');
|
|
50
|
+
sessionStorage.setItem('anet_v3_auth', '1');
|
|
51
|
+
} catch {}
|
|
52
|
+
});
|
|
53
|
+
await ctx.route('**/api/hub/status*', async (route) => {
|
|
54
|
+
const r = await route.fetch();
|
|
55
|
+
const b = await r.json();
|
|
56
|
+
const nid = (b.sessions || [])[0]?.network_id || 'default';
|
|
57
|
+
const mk = (alias) => ({
|
|
58
|
+
alias, status: 'idle', model: 'claude-opus-4', runtime: 'claude-code-cli',
|
|
59
|
+
network_id: nid, project_dir: null,
|
|
60
|
+
created_at: fresh, updated_at: fresh, last_seen_at: fresh,
|
|
61
|
+
});
|
|
62
|
+
await route.fulfill({ response: r, json: { ...b, sessions: [mk('a·1'), mk('a·2')] } });
|
|
63
|
+
});
|
|
64
|
+
await ctx.route('**/api/hub/messages*', (r) => r.fulfill({ json: { messages: [] } }));
|
|
65
|
+
await ctx.route('**/api/hub/tasks*', (r) => r.fulfill({ json: { tasks: [] } }));
|
|
66
|
+
const page = await ctx.newPage();
|
|
67
|
+
await page.goto('http://127.0.0.1:3000/', { waitUntil: 'networkidle' });
|
|
68
|
+
await page.waitForSelector('[data-topo-canvas-aria]', { timeout: 15000, state: 'attached' });
|
|
69
|
+
await page.waitForTimeout(300);
|
|
70
|
+
|
|
71
|
+
const runtimeAttrs = await page.evaluate(() => {
|
|
72
|
+
const svg = document.querySelector('[data-topo-canvas-aria]');
|
|
73
|
+
return {
|
|
74
|
+
modes: svg?.getAttribute('data-topo-animation-temporal-modes') ?? null,
|
|
75
|
+
rolodex: svg?.getAttribute('data-topo-respiratory-rolodex') ?? null,
|
|
76
|
+
patterns: svg?.getAttribute('data-topo-respiratory-patterns') ?? null,
|
|
77
|
+
};
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
await browser.close();
|
|
81
|
+
|
|
82
|
+
let modes = null;
|
|
83
|
+
let rolodex = null;
|
|
84
|
+
let patterns = null;
|
|
85
|
+
let parseError = null;
|
|
86
|
+
try {
|
|
87
|
+
modes = JSON.parse(runtimeAttrs.modes ?? '');
|
|
88
|
+
rolodex = JSON.parse(runtimeAttrs.rolodex ?? '');
|
|
89
|
+
patterns = JSON.parse(runtimeAttrs.patterns ?? '');
|
|
90
|
+
} catch (e) {
|
|
91
|
+
parseError = String(e);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
const validShape = Array.isArray(modes)
|
|
95
|
+
? modes.every(m => m && typeof m === 'object'
|
|
96
|
+
&& typeof m.mode === 'string' && m.mode.length > 0
|
|
97
|
+
&& typeof m.family === 'string' && m.family.length > 0
|
|
98
|
+
&& Number.isInteger(m.members) && m.members > 0
|
|
99
|
+
&& Array.isArray(m.examples) && m.examples.length > 0 && m.examples.length <= 3
|
|
100
|
+
&& m.examples.every(e => typeof e === 'string' && e.length > 0))
|
|
101
|
+
: false;
|
|
102
|
+
|
|
103
|
+
const modeNames = Array.isArray(modes) ? modes.map(m => m.mode).sort() : [];
|
|
104
|
+
const familyNames = Array.isArray(modes) ? modes.map(m => m.family).sort() : [];
|
|
105
|
+
const expectedModes = ['infinite-rest', 'infinite-sweep', 'one-shot-mount'];
|
|
106
|
+
const expectedFamilies = ['ambient', 'breath', 'entrance'];
|
|
107
|
+
|
|
108
|
+
const infRest = Array.isArray(modes) ? modes.find(m => m.mode === 'infinite-rest') : null;
|
|
109
|
+
const infSweep = Array.isArray(modes) ? modes.find(m => m.mode === 'infinite-sweep') : null;
|
|
110
|
+
const oneShot = Array.isArray(modes) ? modes.find(m => m.mode === 'one-shot-mount') : null;
|
|
111
|
+
|
|
112
|
+
const rolodexAnchorCount = rolodex && typeof rolodex === 'object'
|
|
113
|
+
? Object.values(rolodex).reduce((acc, v) => acc + (Array.isArray(v) ? v.length : 0), 0)
|
|
114
|
+
: -1;
|
|
115
|
+
|
|
116
|
+
const scanBeamTrio = Array.isArray(patterns) ? patterns.find(p => p.name === 'scan-beam-trio') : null;
|
|
117
|
+
const scanBeamTrioAnchorCount = Array.isArray(scanBeamTrio?.anchors) ? scanBeamTrio.anchors.length : -1;
|
|
118
|
+
|
|
119
|
+
const results = {
|
|
120
|
+
attr_present: !!runtimeAttrs.modes,
|
|
121
|
+
json_parses: modes !== null && parseError === null,
|
|
122
|
+
is_array: Array.isArray(modes),
|
|
123
|
+
has_3_entries: Array.isArray(modes) && modes.length === 3,
|
|
124
|
+
shape_valid: validShape,
|
|
125
|
+
modes_match_expected: JSON.stringify(modeNames) === JSON.stringify(expectedModes),
|
|
126
|
+
families_match_expected: JSON.stringify(familyNames) === JSON.stringify(expectedFamilies),
|
|
127
|
+
inf_rest_breath_pair: infRest?.family === 'breath',
|
|
128
|
+
inf_sweep_ambient_pair: infSweep?.family === 'ambient',
|
|
129
|
+
one_shot_entrance_pair: oneShot?.family === 'entrance',
|
|
130
|
+
inf_rest_matches_rolodex_count: infRest?.members === rolodexAnchorCount,
|
|
131
|
+
inf_sweep_matches_trio_count: infSweep?.members === scanBeamTrioAnchorCount,
|
|
132
|
+
/* Entrance family has grown: R740 solo (1) → R742 pair (2) → R743
|
|
133
|
+
* trio (3). The cardinality assertion tracks the current snapshot;
|
|
134
|
+
* one_shot_count_at_least_1 is the stable invariant. */
|
|
135
|
+
one_shot_count_at_least_1: (oneShot?.members ?? 0) >= 1,
|
|
136
|
+
one_shot_count_is_3: oneShot?.members === 3,
|
|
137
|
+
};
|
|
138
|
+
const ok = Object.values(results).every(Boolean);
|
|
139
|
+
console.log(`${ok ? '✅' : '❌'} R741 animation temporal modes catalog (8th meta-doc — octagon, lifecycle dimension):`,
|
|
140
|
+
JSON.stringify(results, null, 2),
|
|
141
|
+
`\n modes: ${JSON.stringify(modes)}`,
|
|
142
|
+
`\n rolodex anchors: ${rolodexAnchorCount} · scan-beam-trio anchors: ${scanBeamTrioAnchorCount}`,
|
|
143
|
+
parseError ? `\n parseError: ${parseError}` : '');
|
|
144
|
+
process.exit(ok ? 0 : 1);
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/* Round 619 — extend isAvatarHovered + isAvatarFallbackHovered
|
|
2
|
+
* to include chatAlias === session.alias. Cascades the same 4
|
|
3
|
+
* avatar axes (brightness + rotate + scale + drop-shadow) to
|
|
4
|
+
* also fire on chat-target across all 3 branches.
|
|
5
|
+
*
|
|
6
|
+
* Test phases:
|
|
7
|
+
* 1. mock 2 idle nodes → avatar renders
|
|
8
|
+
* 2. rest (no hover, no chat): all data attrs reflect idle
|
|
9
|
+
* state — rotate '0', scale '1', drop-shadow 'none'
|
|
10
|
+
* 3. source: BOTH avatar hover state declarations use
|
|
11
|
+
* gate union (hoveredAlias || chatAlias)
|
|
12
|
+
*/
|
|
13
|
+
import { chromium } from 'playwright';
|
|
14
|
+
import { readFileSync } from 'node:fs';
|
|
15
|
+
|
|
16
|
+
const TOKEN = JSON.parse(readFileSync('/home/vansin/.anet/config.json', 'utf8')).token;
|
|
17
|
+
const fresh = new Date(Date.now() - 60 * 1000).toISOString();
|
|
18
|
+
|
|
19
|
+
const browser = await chromium.launch({ headless: true });
|
|
20
|
+
const ctx = await browser.newContext({ viewport: { width: 1500, height: 1200 } });
|
|
21
|
+
await ctx.addCookies([{ name: 'anet_dashboard_session', value: `v3:${TOKEN}`, domain: '127.0.0.1', path: '/' }]);
|
|
22
|
+
await ctx.addInitScript(() => {
|
|
23
|
+
try {
|
|
24
|
+
localStorage.setItem('anet-theme', 'cyber');
|
|
25
|
+
localStorage.setItem('anet-topo-layout', 'ring');
|
|
26
|
+
sessionStorage.setItem('anet_v3_auth', '1');
|
|
27
|
+
} catch {}
|
|
28
|
+
});
|
|
29
|
+
await ctx.route('**/api/hub/status*', async (route) => {
|
|
30
|
+
const r = await route.fetch();
|
|
31
|
+
const b = await r.json();
|
|
32
|
+
const nid = (b.sessions || [])[0]?.network_id || 'default';
|
|
33
|
+
const mk = (alias) => ({
|
|
34
|
+
alias, status: 'idle', model: 'claude-opus-4', runtime: 'claude-code-cli',
|
|
35
|
+
network_id: nid, project_dir: null,
|
|
36
|
+
created_at: fresh, updated_at: fresh, last_seen_at: fresh,
|
|
37
|
+
});
|
|
38
|
+
await route.fulfill({ response: r, json: { ...b, sessions: [mk('a·1'), mk('a·2')] } });
|
|
39
|
+
});
|
|
40
|
+
await ctx.route('**/api/hub/messages*', (r) => r.fulfill({ json: { messages: [] } }));
|
|
41
|
+
await ctx.route('**/api/hub/tasks*', (r) => r.fulfill({ json: { tasks: [] } }));
|
|
42
|
+
const page = await ctx.newPage();
|
|
43
|
+
await page.goto('http://127.0.0.1:3000/', { waitUntil: 'networkidle' });
|
|
44
|
+
await page.waitForSelector('[data-node-avatar]', { timeout: 15000, state: 'attached' });
|
|
45
|
+
await page.waitForTimeout(500);
|
|
46
|
+
|
|
47
|
+
const rest = await page.evaluate(() => {
|
|
48
|
+
const el = document.querySelector('[data-node-avatar]');
|
|
49
|
+
if (!el) return null;
|
|
50
|
+
return {
|
|
51
|
+
rotateAttr: el.getAttribute('data-node-avatar-rotate'),
|
|
52
|
+
scaleAttr: el.getAttribute('data-node-avatar-scale'),
|
|
53
|
+
hoveredAttr: el.getAttribute('data-node-avatar-hovered'),
|
|
54
|
+
dropShadowAttr: el.getAttribute('data-node-avatar-drop-shadow'),
|
|
55
|
+
};
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
await browser.close();
|
|
59
|
+
|
|
60
|
+
const src = readFileSync('/home/vansin/agent-network-dashboard/app/components/TopoGraph.tsx', 'utf8');
|
|
61
|
+
const sourceImageGate = /const isAvatarHovered = !reducedMotion && \(hoveredAlias === session\.alias \|\| chatAlias === session\.alias\)/.test(src);
|
|
62
|
+
const sourceFallbackGate = /const isAvatarFallbackHovered = !reducedMotion && \(hoveredAlias === session\.alias \|\| chatAlias === session\.alias\)/.test(src);
|
|
63
|
+
|
|
64
|
+
const results = {
|
|
65
|
+
avatar_present: !!rest,
|
|
66
|
+
rest_rotate_zero: rest?.rotateAttr === '0',
|
|
67
|
+
rest_scale_one: rest?.scaleAttr === '1',
|
|
68
|
+
rest_hovered_false: rest?.hoveredAttr === 'false',
|
|
69
|
+
rest_drop_shadow_none: rest?.dropShadowAttr === 'none',
|
|
70
|
+
source_image_gate: sourceImageGate,
|
|
71
|
+
source_fallback_gate: sourceFallbackGate,
|
|
72
|
+
};
|
|
73
|
+
const ok = Object.values(results).every(Boolean);
|
|
74
|
+
console.log(`${ok ? '✅' : '❌'} R619 avatar chat-target gate (chat-gated family 5th anchor):`,
|
|
75
|
+
JSON.stringify(results, null, 2),
|
|
76
|
+
`\n rest: ${JSON.stringify(rest)}`);
|
|
77
|
+
process.exit(ok ? 0 : 1);
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/* Round 605 — per-node avatar gains drop-shadow on hover,
|
|
2
|
+
* stacked with brightness via banked R582/R583 stacked-filter
|
|
3
|
+
* pattern. 4th hover axis on avatar (brightness + rotate +
|
|
4
|
+
* scale + drop-shadow). 3-element sibling edit (image + 2
|
|
5
|
+
* fallback branches).
|
|
6
|
+
*
|
|
7
|
+
* Test phases:
|
|
8
|
+
* 1. mock 2 idle nodes → avatar renders
|
|
9
|
+
* 2. rest: filter='none', drop-shadow attr 'none'
|
|
10
|
+
* 3. computed transition-property contains 'filter'
|
|
11
|
+
* 4. source: stacked filter conditional + data-attr on all
|
|
12
|
+
* 3 branches
|
|
13
|
+
*/
|
|
14
|
+
import { chromium } from 'playwright';
|
|
15
|
+
import { readFileSync } from 'node:fs';
|
|
16
|
+
|
|
17
|
+
const TOKEN = JSON.parse(readFileSync('/home/vansin/.anet/config.json', 'utf8')).token;
|
|
18
|
+
const fresh = new Date(Date.now() - 60 * 1000).toISOString();
|
|
19
|
+
|
|
20
|
+
const browser = await chromium.launch({ headless: true });
|
|
21
|
+
const ctx = await browser.newContext({ viewport: { width: 1500, height: 1200 } });
|
|
22
|
+
await ctx.addCookies([{ name: 'anet_dashboard_session', value: `v3:${TOKEN}`, domain: '127.0.0.1', path: '/' }]);
|
|
23
|
+
await ctx.addInitScript(() => {
|
|
24
|
+
try {
|
|
25
|
+
localStorage.setItem('anet-theme', 'cyber');
|
|
26
|
+
localStorage.setItem('anet-topo-layout', 'ring');
|
|
27
|
+
sessionStorage.setItem('anet_v3_auth', '1');
|
|
28
|
+
} catch {}
|
|
29
|
+
});
|
|
30
|
+
await ctx.route('**/api/hub/status*', async (route) => {
|
|
31
|
+
const r = await route.fetch();
|
|
32
|
+
const b = await r.json();
|
|
33
|
+
const nid = (b.sessions || [])[0]?.network_id || 'default';
|
|
34
|
+
const mk = (alias) => ({
|
|
35
|
+
alias, status: 'idle', model: 'claude-opus-4', runtime: 'claude-code-cli',
|
|
36
|
+
network_id: nid, project_dir: null,
|
|
37
|
+
created_at: fresh, updated_at: fresh, last_seen_at: fresh,
|
|
38
|
+
});
|
|
39
|
+
await route.fulfill({ response: r, json: { ...b, sessions: [mk('a·1'), mk('a·2')] } });
|
|
40
|
+
});
|
|
41
|
+
await ctx.route('**/api/hub/messages*', (r) => r.fulfill({ json: { messages: [] } }));
|
|
42
|
+
await ctx.route('**/api/hub/tasks*', (r) => r.fulfill({ json: { tasks: [] } }));
|
|
43
|
+
const page = await ctx.newPage();
|
|
44
|
+
await page.goto('http://127.0.0.1:3000/', { waitUntil: 'networkidle' });
|
|
45
|
+
await page.waitForSelector('[data-node-avatar-drop-shadow]', { timeout: 15000, state: 'attached' });
|
|
46
|
+
await page.waitForTimeout(500);
|
|
47
|
+
|
|
48
|
+
const rest = await page.evaluate(() => {
|
|
49
|
+
const el = document.querySelector('[data-node-avatar-drop-shadow]');
|
|
50
|
+
if (!el) return null;
|
|
51
|
+
const cs = getComputedStyle(el);
|
|
52
|
+
return {
|
|
53
|
+
filter: cs.filter,
|
|
54
|
+
transitionProperty: cs.transitionProperty,
|
|
55
|
+
dropShadowAttr: el.getAttribute('data-node-avatar-drop-shadow'),
|
|
56
|
+
brightnessAttr: el.getAttribute('data-node-avatar-brightness') || null,
|
|
57
|
+
rotateAttr: el.getAttribute('data-node-avatar-rotate'),
|
|
58
|
+
scaleAttr: el.getAttribute('data-node-avatar-scale'),
|
|
59
|
+
hoveredAttr: el.getAttribute('data-node-avatar-hovered'),
|
|
60
|
+
};
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
await browser.close();
|
|
64
|
+
|
|
65
|
+
const src = readFileSync('/home/vansin/agent-network-dashboard/app/components/TopoGraph.tsx', 'utf8');
|
|
66
|
+
const sourceImageDS = /data-node-avatar-drop-shadow=\{isAvatarHovered \? `0 0 4px \$\{pal\.legendAccent\}99` : 'none'\}/.test(src);
|
|
67
|
+
const sourceMonogramDS = /data-node-avatar-monogram-drop-shadow=\{isAvatarFallbackHovered \? `0 0 4px \$\{pal\.legendAccent\}99` : 'none'\}/.test(src);
|
|
68
|
+
const sourceFallbackDS = /data-node-avatar-fallback-drop-shadow=\{isAvatarFallbackHovered \? `0 0 4px \$\{pal\.legendAccent\}99` : 'none'\}/.test(src);
|
|
69
|
+
const sourceStackedFilters = (src.match(/`drop-shadow\(0 0 4px \$\{pal\.legendAccent\}99\) brightness\(1\.15\)`/g) || []).length >= 3;
|
|
70
|
+
|
|
71
|
+
const results = {
|
|
72
|
+
avatar_present: !!rest,
|
|
73
|
+
rest_filter_none: rest?.filter === 'none',
|
|
74
|
+
rest_drop_shadow_none: rest?.dropShadowAttr === 'none',
|
|
75
|
+
rest_hovered_false: rest?.hoveredAttr === 'false',
|
|
76
|
+
transition_has_filter: /filter/.test(rest?.transitionProperty || ''),
|
|
77
|
+
source_image_ds_attr: sourceImageDS,
|
|
78
|
+
source_monogram_ds: sourceMonogramDS,
|
|
79
|
+
source_fallback_ds: sourceFallbackDS,
|
|
80
|
+
source_3_stacked: sourceStackedFilters,
|
|
81
|
+
};
|
|
82
|
+
const ok = Object.values(results).every(Boolean);
|
|
83
|
+
console.log(`${ok ? '✅' : '❌'} R605 avatar drop-shadow (3/3 branches, 4-axis hover signature):`,
|
|
84
|
+
JSON.stringify(results, null, 2),
|
|
85
|
+
`\n rest: ${JSON.stringify(rest)}`);
|
|
86
|
+
process.exit(ok ? 0 : 1);
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/* Round 601 — extends R600 hover-rotate-3 to the 2 avatar
|
|
2
|
+
* fallback branches (vendor monogram + prefix-group initial),
|
|
3
|
+
* closing per-node avatar rotate coverage at 3/3 branches.
|
|
4
|
+
* Same R558 brightness-coverage closure pattern, now for rotate.
|
|
5
|
+
*
|
|
6
|
+
* Test phases:
|
|
7
|
+
* 1. mock node with non-vendor-logo runtime → monogram branch
|
|
8
|
+
* renders OR fallback branch renders (depends on vendor map)
|
|
9
|
+
* 2. rest: rotate='0deg' or 'none', rotate-attr='0'
|
|
10
|
+
* 3. computed transition-property contains 'rotate'
|
|
11
|
+
* 4. transform-origin set to node center coords
|
|
12
|
+
* 5. source: rotate conditional on BOTH branch elements
|
|
13
|
+
*/
|
|
14
|
+
import { chromium } from 'playwright';
|
|
15
|
+
import { readFileSync } from 'node:fs';
|
|
16
|
+
|
|
17
|
+
const TOKEN = JSON.parse(readFileSync('/home/vansin/.anet/config.json', 'utf8')).token;
|
|
18
|
+
const fresh = new Date(Date.now() - 60 * 1000).toISOString();
|
|
19
|
+
|
|
20
|
+
const browser = await chromium.launch({ headless: true });
|
|
21
|
+
const ctx = await browser.newContext({ viewport: { width: 1500, height: 1200 } });
|
|
22
|
+
await ctx.addCookies([{ name: 'anet_dashboard_session', value: `v3:${TOKEN}`, domain: '127.0.0.1', path: '/' }]);
|
|
23
|
+
await ctx.addInitScript(() => {
|
|
24
|
+
try {
|
|
25
|
+
localStorage.setItem('anet-theme', 'cyber');
|
|
26
|
+
localStorage.setItem('anet-topo-layout', 'ring');
|
|
27
|
+
sessionStorage.setItem('anet_v3_auth', '1');
|
|
28
|
+
} catch {}
|
|
29
|
+
});
|
|
30
|
+
await ctx.route('**/api/hub/status*', async (route) => {
|
|
31
|
+
const r = await route.fetch();
|
|
32
|
+
const b = await r.json();
|
|
33
|
+
const nid = (b.sessions || [])[0]?.network_id || 'default';
|
|
34
|
+
// Use an unknown vendor model to force fallback branch render
|
|
35
|
+
await route.fulfill({ response: r, json: { ...b, sessions: [
|
|
36
|
+
{ alias: 'unknown·1', status: 'idle', model: 'mystery-model-3000',
|
|
37
|
+
runtime: 'claude-code-cli', network_id: nid, project_dir: null,
|
|
38
|
+
created_at: fresh, updated_at: fresh, last_seen_at: fresh },
|
|
39
|
+
{ alias: 'unknown·2', status: 'idle', model: 'mystery-model-3000',
|
|
40
|
+
runtime: 'claude-code-cli', network_id: nid, project_dir: null,
|
|
41
|
+
created_at: fresh, updated_at: fresh, last_seen_at: fresh },
|
|
42
|
+
] } });
|
|
43
|
+
});
|
|
44
|
+
await ctx.route('**/api/hub/messages*', (r) => r.fulfill({ json: { messages: [] } }));
|
|
45
|
+
await ctx.route('**/api/hub/tasks*', (r) => r.fulfill({ json: { tasks: [] } }));
|
|
46
|
+
const page = await ctx.newPage();
|
|
47
|
+
await page.goto('http://127.0.0.1:3000/', { waitUntil: 'networkidle' });
|
|
48
|
+
// Either monogram or fallback should render based on vendor resolution
|
|
49
|
+
await page.waitForSelector('[data-node-avatar-fallback-rotate], [data-node-avatar-monogram-rotate]', { timeout: 15000, state: 'attached' });
|
|
50
|
+
await page.waitForTimeout(500);
|
|
51
|
+
|
|
52
|
+
const rest = await page.evaluate(() => {
|
|
53
|
+
const fallback = document.querySelector('[data-node-avatar-fallback-rotate]');
|
|
54
|
+
const monogram = document.querySelector('[data-node-avatar-monogram-rotate]');
|
|
55
|
+
const el = fallback || monogram;
|
|
56
|
+
if (!el) return null;
|
|
57
|
+
const cs = getComputedStyle(el);
|
|
58
|
+
return {
|
|
59
|
+
branch: fallback ? 'fallback' : 'monogram',
|
|
60
|
+
rotate: cs.rotate,
|
|
61
|
+
transformOrigin: cs.transformOrigin,
|
|
62
|
+
transitionProperty: cs.transitionProperty,
|
|
63
|
+
rotateAttr: el.getAttribute('data-node-avatar-fallback-rotate') || el.getAttribute('data-node-avatar-monogram-rotate'),
|
|
64
|
+
hoveredAttr: el.getAttribute('data-node-avatar-fallback-hovered') || el.getAttribute('data-node-avatar-monogram-hovered'),
|
|
65
|
+
};
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
await browser.close();
|
|
69
|
+
|
|
70
|
+
const src = readFileSync('/home/vansin/agent-network-dashboard/app/components/TopoGraph.tsx', 'utf8');
|
|
71
|
+
const sourceMonogramRotate = /data-node-avatar-monogram-rotate=\{isAvatarFallbackHovered \? '3' : '0'\}/.test(src);
|
|
72
|
+
const sourceFallbackRotate = /data-node-avatar-fallback-rotate=\{isAvatarFallbackHovered \? '3' : '0'\}/.test(src);
|
|
73
|
+
const sourceBothBranches = (src.match(/rotate: isAvatarFallbackHovered \? '3deg' : '0deg'/g) || []).length >= 2;
|
|
74
|
+
const sourceBothTransitions = (src.match(/transition: 'filter 200ms ease-out, rotate 200ms ease-out'/g) || []).length >= 3;
|
|
75
|
+
|
|
76
|
+
const results = {
|
|
77
|
+
branch_present: !!rest,
|
|
78
|
+
rest_rotate_zero: rest?.rotate === 'none' || rest?.rotate === '0deg',
|
|
79
|
+
rest_rotate_attr: rest?.rotateAttr === '0',
|
|
80
|
+
rest_hovered_false: rest?.hoveredAttr === 'false',
|
|
81
|
+
has_transform_origin: !!rest?.transformOrigin && rest.transformOrigin !== '',
|
|
82
|
+
transition_has_rotate: /rotate/.test(rest?.transitionProperty || ''),
|
|
83
|
+
source_monogram_rotate: sourceMonogramRotate,
|
|
84
|
+
source_fallback_rotate: sourceFallbackRotate,
|
|
85
|
+
source_both_branches: sourceBothBranches,
|
|
86
|
+
source_both_transitions: sourceBothTransitions,
|
|
87
|
+
};
|
|
88
|
+
const ok = Object.values(results).every(Boolean);
|
|
89
|
+
console.log(`${ok ? '✅' : '❌'} R601 avatar fallback rotate (3/3 branches closure):`,
|
|
90
|
+
JSON.stringify(results, null, 2),
|
|
91
|
+
`\n rest: ${JSON.stringify(rest)}`);
|
|
92
|
+
process.exit(ok ? 0 : 1);
|