@sleep2agi/agent-network-dashboard 0.5.1-preview.14 → 0.5.1-preview.141
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.next/BUILD_ID +1 -1
- package/.next/build-manifest.json +3 -3
- package/.next/diagnostics/route-bundle-stats.json +32 -32
- package/.next/fallback-build-manifest.json +3 -3
- package/.next/prerender-manifest.json +3 -3
- package/.next/server/app/_global-error.html +1 -1
- package/.next/server/app/_global-error.rsc +1 -1
- package/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/.next/server/app/_not-found.html +2 -2
- package/.next/server/app/_not-found.rsc +12 -12
- package/.next/server/app/_not-found.segments/_full.segment.rsc +12 -12
- package/.next/server/app/_not-found.segments/_head.segment.rsc +4 -4
- package/.next/server/app/_not-found.segments/_index.segment.rsc +7 -7
- package/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +2 -2
- package/.next/server/app/_not-found.segments/_not-found.segment.rsc +3 -3
- package/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/admin/page_client-reference-manifest.js +1 -1
- package/.next/server/app/admin.html +2 -2
- package/.next/server/app/admin.rsc +14 -14
- package/.next/server/app/admin.segments/_full.segment.rsc +14 -14
- package/.next/server/app/admin.segments/_head.segment.rsc +4 -4
- package/.next/server/app/admin.segments/_index.segment.rsc +7 -7
- package/.next/server/app/admin.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/admin.segments/admin/__PAGE__.segment.rsc +4 -4
- package/.next/server/app/admin.segments/admin.segment.rsc +3 -3
- package/.next/server/app/index.html +2 -2
- package/.next/server/app/index.rsc +14 -14
- package/.next/server/app/index.segments/__PAGE__.segment.rsc +4 -4
- package/.next/server/app/index.segments/_full.segment.rsc +14 -14
- package/.next/server/app/index.segments/_head.segment.rsc +4 -4
- package/.next/server/app/index.segments/_index.segment.rsc +7 -7
- package/.next/server/app/index.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/login/page_client-reference-manifest.js +1 -1
- package/.next/server/app/login.html +2 -2
- package/.next/server/app/login.rsc +14 -14
- package/.next/server/app/login.segments/_full.segment.rsc +14 -14
- package/.next/server/app/login.segments/_head.segment.rsc +4 -4
- package/.next/server/app/login.segments/_index.segment.rsc +7 -7
- package/.next/server/app/login.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/login.segments/login/__PAGE__.segment.rsc +4 -4
- package/.next/server/app/login.segments/login.segment.rsc +3 -3
- package/.next/server/app/logs/page_client-reference-manifest.js +1 -1
- package/.next/server/app/logs.html +2 -2
- package/.next/server/app/logs.rsc +14 -14
- package/.next/server/app/logs.segments/_full.segment.rsc +14 -14
- package/.next/server/app/logs.segments/_head.segment.rsc +4 -4
- package/.next/server/app/logs.segments/_index.segment.rsc +7 -7
- package/.next/server/app/logs.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/logs.segments/logs/__PAGE__.segment.rsc +4 -4
- package/.next/server/app/logs.segments/logs.segment.rsc +3 -3
- package/.next/server/app/messages/page_client-reference-manifest.js +1 -1
- package/.next/server/app/messages.html +2 -2
- package/.next/server/app/messages.rsc +14 -14
- package/.next/server/app/messages.segments/_full.segment.rsc +14 -14
- package/.next/server/app/messages.segments/_head.segment.rsc +4 -4
- package/.next/server/app/messages.segments/_index.segment.rsc +7 -7
- package/.next/server/app/messages.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/messages.segments/messages/__PAGE__.segment.rsc +4 -4
- package/.next/server/app/messages.segments/messages.segment.rsc +3 -3
- package/.next/server/app/node/page_client-reference-manifest.js +1 -1
- package/.next/server/app/node.html +2 -2
- package/.next/server/app/node.rsc +14 -14
- package/.next/server/app/node.segments/_full.segment.rsc +14 -14
- package/.next/server/app/node.segments/_head.segment.rsc +4 -4
- package/.next/server/app/node.segments/_index.segment.rsc +7 -7
- package/.next/server/app/node.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/node.segments/node/__PAGE__.segment.rsc +4 -4
- package/.next/server/app/node.segments/node.segment.rsc +3 -3
- package/.next/server/app/nodes/page_client-reference-manifest.js +1 -1
- package/.next/server/app/nodes.html +2 -2
- package/.next/server/app/nodes.rsc +14 -14
- package/.next/server/app/nodes.segments/_full.segment.rsc +14 -14
- package/.next/server/app/nodes.segments/_head.segment.rsc +4 -4
- package/.next/server/app/nodes.segments/_index.segment.rsc +7 -7
- package/.next/server/app/nodes.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/nodes.segments/nodes/__PAGE__.segment.rsc +4 -4
- package/.next/server/app/nodes.segments/nodes.segment.rsc +3 -3
- package/.next/server/app/page.js.nft.json +1 -1
- package/.next/server/app/page_client-reference-manifest.js +1 -1
- package/.next/server/app/server-logs/page_client-reference-manifest.js +1 -1
- package/.next/server/app/server-logs.html +2 -2
- package/.next/server/app/server-logs.rsc +14 -14
- package/.next/server/app/server-logs.segments/_full.segment.rsc +14 -14
- package/.next/server/app/server-logs.segments/_head.segment.rsc +4 -4
- package/.next/server/app/server-logs.segments/_index.segment.rsc +7 -7
- package/.next/server/app/server-logs.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/server-logs.segments/server-logs/__PAGE__.segment.rsc +4 -4
- package/.next/server/app/server-logs.segments/server-logs.segment.rsc +3 -3
- package/.next/server/app/settings/networks/page_client-reference-manifest.js +1 -1
- package/.next/server/app/settings/networks.html +2 -2
- package/.next/server/app/settings/networks.rsc +14 -14
- package/.next/server/app/settings/networks.segments/_full.segment.rsc +14 -14
- package/.next/server/app/settings/networks.segments/_head.segment.rsc +4 -4
- package/.next/server/app/settings/networks.segments/_index.segment.rsc +7 -7
- package/.next/server/app/settings/networks.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/settings/networks.segments/settings/networks/__PAGE__.segment.rsc +4 -4
- package/.next/server/app/settings/networks.segments/settings/networks.segment.rsc +3 -3
- package/.next/server/app/settings/networks.segments/settings.segment.rsc +3 -3
- package/.next/server/app/settings/page_client-reference-manifest.js +1 -1
- package/.next/server/app/settings/tokens/page_client-reference-manifest.js +1 -1
- package/.next/server/app/settings/tokens.html +2 -2
- package/.next/server/app/settings/tokens.rsc +14 -14
- package/.next/server/app/settings/tokens.segments/_full.segment.rsc +14 -14
- package/.next/server/app/settings/tokens.segments/_head.segment.rsc +4 -4
- package/.next/server/app/settings/tokens.segments/_index.segment.rsc +7 -7
- package/.next/server/app/settings/tokens.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/settings/tokens.segments/settings/tokens/__PAGE__.segment.rsc +4 -4
- package/.next/server/app/settings/tokens.segments/settings/tokens.segment.rsc +3 -3
- package/.next/server/app/settings/tokens.segments/settings.segment.rsc +3 -3
- package/.next/server/app/settings.html +2 -2
- package/.next/server/app/settings.rsc +14 -14
- package/.next/server/app/settings.segments/_full.segment.rsc +14 -14
- package/.next/server/app/settings.segments/_head.segment.rsc +4 -4
- package/.next/server/app/settings.segments/_index.segment.rsc +7 -7
- package/.next/server/app/settings.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/settings.segments/settings/__PAGE__.segment.rsc +4 -4
- package/.next/server/app/settings.segments/settings.segment.rsc +3 -3
- package/.next/server/app/tasks/[id]/page_client-reference-manifest.js +1 -1
- package/.next/server/app/tasks/page_client-reference-manifest.js +1 -1
- package/.next/server/app/tasks.html +2 -2
- package/.next/server/app/tasks.rsc +14 -14
- package/.next/server/app/tasks.segments/_full.segment.rsc +14 -14
- package/.next/server/app/tasks.segments/_head.segment.rsc +4 -4
- package/.next/server/app/tasks.segments/_index.segment.rsc +7 -7
- package/.next/server/app/tasks.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/tasks.segments/tasks/__PAGE__.segment.rsc +4 -4
- package/.next/server/app/tasks.segments/tasks.segment.rsc +3 -3
- package/.next/server/chunks/ssr/{[root-of-the-server]__03b.f76._.js → [root-of-the-server]__0sv~g.o._.js} +2 -2
- package/.next/server/chunks/ssr/[root-of-the-server]__0sv~g.o._.js.map +1 -0
- 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/pages/404.html +2 -2
- package/.next/server/pages/500.html +1 -1
- package/.next/server/server-reference-manifest.js +1 -1
- package/.next/server/server-reference-manifest.json +1 -1
- package/.next/static/chunks/{0l_~q07bhpkcx.js → 03a4--7ncekmk.js} +1 -1
- package/.next/static/chunks/05kol0eq4~_d5.js +4 -0
- package/.next/static/chunks/{03~~oirxz7~vc.js → 07gxjdi4w5ot1.js} +1 -1
- package/.next/static/chunks/0a4hmfvj-81x5.css +2 -0
- package/.next/static/chunks/0b_0vo6gv.2d0.js +1 -0
- package/.next/static/chunks/0o~yjk9gw3w3d.js +1 -0
- package/.next/trace +2 -2
- package/.next/trace-build +1 -1
- package/app/components/ServersDrawer.tsx +17 -0
- package/app/components/TopoGraph.tsx +2558 -188
- package/package.json +1 -1
- package/screenshots/v0.10.2-disk-verify/disk-render-full.png +0 -0
- package/screenshots/v0.10.2-disk-verify/disk-render.png +0 -0
- package/screenshots/v0.11.0-147/after.png +0 -0
- package/scripts/p0-147-screenshot.mjs +53 -0
- package/scripts/p0-servers-drawer-screenshot.mjs +2 -0
- package/scripts/topo-active-links-chip-hover-lift-test.mjs +93 -0
- package/scripts/topo-chip-digit-fontweight-test.mjs +105 -0
- package/scripts/topo-chip-digit-hover-bold-test.mjs +94 -0
- package/scripts/topo-chip-row-group-hover-brighten-test.mjs +107 -0
- package/scripts/topo-chip-row-hover-lift-test.mjs +95 -0
- package/scripts/topo-chrome-button-hover-lift-test.mjs +94 -0
- package/scripts/topo-chrome-fullscreen-icon-sw-test.mjs +92 -0
- package/scripts/topo-chrome-reset-icon-sw-test.mjs +80 -0
- package/scripts/topo-chrome-segmented-radius-test.mjs +100 -0
- package/scripts/topo-chrome-zoom-icon-sw-test.mjs +90 -0
- package/scripts/topo-click-ripple-opacity-test.mjs +99 -0
- package/scripts/topo-dashboard-version-attr-test.mjs +69 -0
- package/scripts/topo-dense-alias-opacity-test.mjs +68 -0
- package/scripts/topo-edge-badge-digit-fw-test.mjs +103 -0
- package/scripts/topo-edge-badge-fontsize-test.mjs +90 -0
- package/scripts/topo-edge-badge-hover-opacity-test.mjs +94 -0
- package/scripts/topo-edge-badge-hover-stroke-test.mjs +92 -0
- package/scripts/topo-edge-badge-letter-spacing-test.mjs +86 -0
- package/scripts/topo-edge-badge-opacity-test.mjs +80 -0
- package/scripts/topo-edge-badge-pin-opacity-test.mjs +86 -0
- package/scripts/topo-edge-badge-stroke-test.mjs +92 -0
- package/scripts/topo-edge-endpoint-hover-sw-test.mjs +127 -0
- package/scripts/topo-edge-freshness-floor-test.mjs +99 -0
- package/scripts/topo-edge-particle-hover-r-test.mjs +113 -0
- package/scripts/topo-edge-particle-radius-test.mjs +76 -0
- package/scripts/topo-edge-visible-linecap-test.mjs +89 -0
- package/scripts/topo-endpoint-ring-r-hover-test.mjs +89 -0
- package/scripts/topo-filter-pill-hover-lift-test.mjs +101 -0
- package/scripts/topo-filter-pill-hover-opacity-test.mjs +110 -0
- package/scripts/topo-filter-pill-value-fw-test.mjs +88 -0
- package/scripts/topo-filter-pill-x-hover-scale-test.mjs +99 -0
- package/scripts/topo-flow-rail-hover-sw-test.mjs +113 -0
- package/scripts/topo-flow-rail-linecap-test.mjs +79 -0
- package/scripts/topo-freshness-chip-hierarchy-test.mjs +93 -0
- package/scripts/topo-freshness-chip-tabular-test.mjs +41 -0
- package/scripts/topo-freshness-floor-lift-test.mjs +92 -0
- package/scripts/topo-freshness-suffix-tabular-test.mjs +88 -0
- package/scripts/topo-group-box-geom-transition-test.mjs +110 -0
- package/scripts/topo-group-box-rx-pin-test.mjs +103 -0
- package/scripts/topo-group-box-stroke-test.mjs +105 -0
- package/scripts/topo-group-label-count-fontweight-test.mjs +108 -0
- package/scripts/topo-group-label-count-fw-test.mjs +100 -0
- package/scripts/topo-group-label-fw-pin-test.mjs +99 -0
- package/scripts/topo-group-label-letter-spacing-test.mjs +113 -0
- package/scripts/topo-group-label-tint-geom-test.mjs +94 -0
- package/scripts/topo-group-label-tint-transition-test.mjs +97 -0
- package/scripts/topo-group-pip-fontsize-test.mjs +106 -0
- package/scripts/topo-group-tint-rx-pin-test.mjs +107 -0
- package/scripts/topo-hover-detail-body-fw-test.mjs +101 -0
- package/scripts/topo-hover-detail-model-fw-test.mjs +98 -0
- package/scripts/topo-hover-detail-opacity-test.mjs +98 -0
- package/scripts/topo-hover-detail-rx-test.mjs +81 -0
- package/scripts/topo-hub-core-fill-hover-test.mjs +85 -0
- package/scripts/topo-hub-digit-fontsize-test.mjs +86 -0
- package/scripts/topo-hub-digit-fw-hover-test.mjs +102 -0
- package/scripts/topo-hub-halo-light-trough-test.mjs +88 -0
- package/scripts/topo-hub-halo-r-hover-test.mjs +82 -0
- package/scripts/topo-hub-halo-radius-test.mjs +86 -0
- package/scripts/topo-hub-halo-trough-test.mjs +83 -0
- package/scripts/topo-hub-highlight-opacity-test.mjs +88 -0
- package/scripts/topo-hub-highlight-radius-test.mjs +90 -0
- package/scripts/topo-hub-hover-ring-opacity-test.mjs +96 -0
- package/scripts/topo-hub-hover-ring-stroke-test.mjs +86 -0
- package/scripts/topo-hub-spoke-hover-opacity-test.mjs +119 -0
- package/scripts/topo-hub-spoke-hover-sw-test.mjs +121 -0
- package/scripts/topo-hub-spoke-linecap-test.mjs +80 -0
- package/scripts/topo-label-card-opacity-hover-test.mjs +99 -0
- package/scripts/topo-layout-toggle-radius-test.mjs +87 -0
- package/scripts/topo-legend-count-active-opacity-test.mjs +102 -0
- package/scripts/topo-legend-count-pin-fw-test.mjs +90 -0
- package/scripts/topo-legend-label-fontweight-test.mjs +94 -0
- package/scripts/topo-legend-pin-ring-stroke-test.mjs +101 -0
- package/scripts/topo-legend-row-letter-spacing-test.mjs +101 -0
- package/scripts/topo-minimap-offline-opacity-test.mjs +90 -0
- package/scripts/topo-minimap-online-hover-opacity-test.mjs +92 -0
- package/scripts/topo-minimap-online-opacity-test.mjs +93 -0
- package/scripts/topo-minimap-online-radius-test.mjs +85 -0
- package/scripts/topo-minimap-viewport-linejoin-test.mjs +75 -0
- package/scripts/topo-minimap-viewport-opacity-test.mjs +96 -0
- package/scripts/topo-minimap-viewport-rx-test.mjs +85 -0
- package/scripts/topo-more-flows-fontweight-test.mjs +103 -0
- package/scripts/topo-node-alias-letter-spacing-test.mjs +112 -0
- package/scripts/topo-node-halo-hover-opacity-test.mjs +104 -0
- package/scripts/topo-node-halo-light-offline-test.mjs +80 -0
- package/scripts/topo-node-halo-offline-opacity-test.mjs +87 -0
- package/scripts/topo-node-label-card-rx-test.mjs +85 -0
- package/scripts/topo-node-pulse-peak-test.mjs +89 -0
- package/scripts/topo-node-pulse-trough-test.mjs +91 -0
- package/scripts/topo-node-sub-text-fw-test.mjs +75 -0
- package/scripts/topo-node-sub-text-letter-spacing-test.mjs +115 -0
- package/scripts/topo-overlap-stale-build-guard-test.mjs +66 -0
- package/scripts/topo-overlap-test.mjs +42 -1
- package/scripts/topo-panel-count-fw-hover-test.mjs +105 -0
- package/scripts/topo-panel-stroke-hover-test.mjs +110 -0
- package/scripts/topo-pressure-bar-height-test.mjs +92 -0
- package/scripts/topo-pressure-kicker-fontweight-test.mjs +76 -0
- package/scripts/topo-recent-pip-radius-2-test.mjs +72 -0
- package/scripts/topo-recent-pip-radius-test.mjs +76 -0
- package/scripts/topo-recent-row-content-opacity-test.mjs +81 -0
- package/scripts/topo-recent-row-count-pin-fw-test.mjs +106 -0
- package/scripts/topo-recent-row-letter-spacing-test.mjs +109 -0
- package/scripts/topo-recent-row-pip-hover-r-test.mjs +104 -0
- package/scripts/topo-recent-row-text-fontweight-test.mjs +90 -0
- package/scripts/topo-runtime-icon-hover-test.mjs +96 -0
- package/scripts/topo-spoke-active-opacity-test.mjs +104 -0
- package/scripts/topo-spoke-active-stroke-test.mjs +95 -0
- package/scripts/topo-spoke-idle-opacity-test.mjs +91 -0
- package/scripts/topo-status-ring-hover-sw-test.mjs +105 -0
- package/scripts/topo-vendor-chip-hover-lift-test.mjs +87 -0
- package/scripts/topo-vendor-glyph-fontweight-test.mjs +102 -0
- package/scripts/topo-vendor-letter-hover-scale-test.mjs +129 -0
- package/scripts/topo-vendor-suffix-hover-brighten-test.mjs +87 -0
- package/scripts/topo-zoom-level-hover-fw-test.mjs +95 -0
- package/.next/server/chunks/ssr/[root-of-the-server]__03b.f76._.js.map +0 -1
- package/.next/static/chunks/03mfrl9fd9smg.js +0 -1
- package/.next/static/chunks/0kt7qs66ra2.2.css +0 -2
- package/.next/static/chunks/116zy6jdhuaa2.js +0 -1
- package/.next/static/chunks/12m~64tlig.y4.js +0 -4
- /package/.next/static/{rDAS8dVgx4ldg7AtRGdUB → Bv_r6o_p1UTgHlTvQaZNt}/_buildManifest.js +0 -0
- /package/.next/static/{rDAS8dVgx4ldg7AtRGdUB → Bv_r6o_p1UTgHlTvQaZNt}/_clientMiddlewareManifest.js +0 -0
- /package/.next/static/{rDAS8dVgx4ldg7AtRGdUB → Bv_r6o_p1UTgHlTvQaZNt}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/* Round 387 verification: hover-detail panel cyber rest opacity
|
|
2
|
+
* 0.94 → 0.97. Theme-consistency / canvas-presence polish family
|
|
3
|
+
* (5th anchor) after R370 hub-ring 0.7→0.8 cyber, R371 edge-badge
|
|
4
|
+
* 0.82→0.85 cyber, R372 minimap offline 0.5→0.6, R386 hub-highlight
|
|
5
|
+
* idle 0.9→0.95. Unifies the active-hover product card's cyber
|
|
6
|
+
* backdrop with the R348 recent-signal/legend panel HOVER state
|
|
7
|
+
* (0.97 cyber) so all active-hover panels paint with the same
|
|
8
|
+
* confident backdrop.
|
|
9
|
+
*
|
|
10
|
+
* Contract:
|
|
11
|
+
* - On hover, the hover-detail panel mounts and:
|
|
12
|
+
* * <rect> opacity attr === '0.97' (cyber theme)
|
|
13
|
+
* * data-topo-hover-detail-opacity === '0.97' (cyber theme)
|
|
14
|
+
* - Pre-R387 invariants preserved:
|
|
15
|
+
* * <rect> rx === '8'
|
|
16
|
+
* * <rect> stroke is non-empty (pal.legendAccent)
|
|
17
|
+
* * data-topo-hover-detail is present (alias-keyed)
|
|
18
|
+
* * R348 drop-shadow filter is present
|
|
19
|
+
* - Light theme stays at opacity 0.98 (separately tested below).
|
|
20
|
+
*
|
|
21
|
+
* Fixture: 2 idle sessions so hover-detail mounts cleanly without
|
|
22
|
+
* the dense-layout >16-node gate (R387 inherits the same gate).
|
|
23
|
+
*/
|
|
24
|
+
import { chromium } from 'playwright';
|
|
25
|
+
import { readFileSync } from 'node:fs';
|
|
26
|
+
|
|
27
|
+
const TOKEN = JSON.parse(readFileSync('/home/vansin/.anet/config.json', 'utf8')).token;
|
|
28
|
+
const fresh = new Date(Date.now() - 60 * 1000).toISOString();
|
|
29
|
+
|
|
30
|
+
async function probeWith(theme) {
|
|
31
|
+
const browser = await chromium.launch({ headless: true });
|
|
32
|
+
const ctx = await browser.newContext({ viewport: { width: 1500, height: 1500 } });
|
|
33
|
+
await ctx.addCookies([{ name: 'anet_dashboard_session', value: `v3:${TOKEN}`, domain: '127.0.0.1', path: '/' }]);
|
|
34
|
+
await ctx.addInitScript((t) => {
|
|
35
|
+
try { localStorage.setItem('anet-theme', t); sessionStorage.setItem('anet_v3_auth', '1'); } catch {}
|
|
36
|
+
}, theme);
|
|
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('alpha'), mk('beta') ] } });
|
|
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: 'domcontentloaded' });
|
|
52
|
+
await page.waitForSelector('g[data-node]', { timeout: 15000 });
|
|
53
|
+
await page.waitForTimeout(300);
|
|
54
|
+
// Hover the first node to mount hover-detail
|
|
55
|
+
await page.hover('g[data-node]');
|
|
56
|
+
await page.waitForSelector('[data-topo-hover-detail]', { timeout: 5000 });
|
|
57
|
+
await page.waitForTimeout(300);
|
|
58
|
+
const probe = await page.evaluate(() => {
|
|
59
|
+
const card = document.querySelector('[data-topo-hover-detail]');
|
|
60
|
+
if (!card) return null;
|
|
61
|
+
const rect = card.querySelector('rect');
|
|
62
|
+
return {
|
|
63
|
+
alias: card.getAttribute('data-topo-hover-detail'),
|
|
64
|
+
opacityAttr: rect?.getAttribute('opacity') ?? null,
|
|
65
|
+
opacityData: rect?.getAttribute('data-topo-hover-detail-opacity') ?? null,
|
|
66
|
+
rxAttr: rect?.getAttribute('rx') ?? null,
|
|
67
|
+
strokeAttr: rect?.getAttribute('stroke') ?? null,
|
|
68
|
+
filterStyle: rect?.getAttribute('style') ?? '',
|
|
69
|
+
};
|
|
70
|
+
});
|
|
71
|
+
await browser.close();
|
|
72
|
+
return probe;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const cyber = await probeWith('cyber');
|
|
76
|
+
const light = await probeWith('light');
|
|
77
|
+
|
|
78
|
+
const results = {
|
|
79
|
+
// Cyber: lifted from 0.94 → 0.97
|
|
80
|
+
cyber_opacity_attr_0_97: cyber?.opacityAttr === '0.97',
|
|
81
|
+
cyber_opacity_data_0_97: cyber?.opacityData === '0.97',
|
|
82
|
+
// Light: stays at 0.98 (R387 doesn't touch light)
|
|
83
|
+
light_opacity_attr_0_98: light?.opacityAttr === '0.98',
|
|
84
|
+
light_opacity_data_0_98: light?.opacityData === '0.98',
|
|
85
|
+
// Pre-R387 invariants on both themes
|
|
86
|
+
cyber_rx_8: cyber?.rxAttr === '8',
|
|
87
|
+
light_rx_8: light?.rxAttr === '8',
|
|
88
|
+
cyber_stroke_present: !!cyber?.strokeAttr && cyber.strokeAttr !== 'none',
|
|
89
|
+
light_stroke_present: !!light?.strokeAttr && light.strokeAttr !== 'none',
|
|
90
|
+
cyber_drop_shadow: cyber?.filterStyle.includes('drop-shadow'),
|
|
91
|
+
light_drop_shadow: light?.filterStyle.includes('drop-shadow'),
|
|
92
|
+
cyber_alias_present: !!cyber?.alias && cyber.alias.length > 0,
|
|
93
|
+
};
|
|
94
|
+
const ok = Object.values(results).every(Boolean);
|
|
95
|
+
console.log(`${ok ? '✅' : '❌'} hover-detail panel cyber opacity 0.94 → 0.97:`, JSON.stringify(results),
|
|
96
|
+
'\n cyber:', cyber,
|
|
97
|
+
'\n light:', light);
|
|
98
|
+
process.exit(ok ? 0 : 1);
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/* Round 390 verification: hover-detail card rx 8 → 10. Aligns the
|
|
2
|
+
* card with the R331 panel tier (recent-signal, legend at rx=10)
|
|
3
|
+
* instead of the R332/R375/R376 compact-chrome / segmented-control
|
|
4
|
+
* tier (rx=8). Pure paint change — no layout shift, no bbox change.
|
|
5
|
+
*
|
|
6
|
+
* Contract:
|
|
7
|
+
* - On hover, the hover-detail card mounts and:
|
|
8
|
+
* * <rect> rx attr === '10'
|
|
9
|
+
* * data-topo-hover-detail-rx === '10'
|
|
10
|
+
* * Stays clear of the R332 minimap viewport (different element)
|
|
11
|
+
* - Pre-R390 invariants preserved:
|
|
12
|
+
* * R348 drop-shadow filter present
|
|
13
|
+
* * R387 opacity attr === '0.97' (cyber)
|
|
14
|
+
* * stroke present (pal.legendAccent)
|
|
15
|
+
* * width / height (192 / 88) unchanged
|
|
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: 1500 } });
|
|
25
|
+
await ctx.addCookies([{ name: 'anet_dashboard_session', value: `v3:${TOKEN}`, domain: '127.0.0.1', path: '/' }]);
|
|
26
|
+
await ctx.addInitScript(() => {
|
|
27
|
+
try { localStorage.setItem('anet-theme', 'cyber'); sessionStorage.setItem('anet_v3_auth', '1'); } catch {}
|
|
28
|
+
});
|
|
29
|
+
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('alpha'), mk('beta') ] } });
|
|
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
|
+
|
|
43
|
+
const page = await ctx.newPage();
|
|
44
|
+
await page.goto('http://127.0.0.1:3000/', { waitUntil: 'domcontentloaded' });
|
|
45
|
+
await page.waitForSelector('g[data-node]', { timeout: 15000 });
|
|
46
|
+
await page.waitForTimeout(300);
|
|
47
|
+
await page.hover('g[data-node]');
|
|
48
|
+
await page.waitForSelector('[data-topo-hover-detail]', { timeout: 5000 });
|
|
49
|
+
await page.waitForTimeout(300);
|
|
50
|
+
|
|
51
|
+
const probe = await page.evaluate(() => {
|
|
52
|
+
const card = document.querySelector('[data-topo-hover-detail]');
|
|
53
|
+
if (!card) return null;
|
|
54
|
+
const rect = card.querySelector('rect');
|
|
55
|
+
return {
|
|
56
|
+
rxAttr: rect?.getAttribute('rx') ?? null,
|
|
57
|
+
rxData: rect?.getAttribute('data-topo-hover-detail-rx') ?? null,
|
|
58
|
+
opacityAttr: rect?.getAttribute('opacity') ?? null,
|
|
59
|
+
widthAttr: rect?.getAttribute('width') ?? null,
|
|
60
|
+
heightAttr: rect?.getAttribute('height') ?? null,
|
|
61
|
+
strokeAttr: rect?.getAttribute('stroke') ?? null,
|
|
62
|
+
styleAttr: rect?.getAttribute('style') ?? '',
|
|
63
|
+
};
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
await browser.close();
|
|
67
|
+
|
|
68
|
+
const results = {
|
|
69
|
+
// R390: rx 8 → 10
|
|
70
|
+
rx_attr_10: probe?.rxAttr === '10',
|
|
71
|
+
rx_data_10: probe?.rxData === '10',
|
|
72
|
+
// Pre-R390 invariants preserved
|
|
73
|
+
opacity_cyber_0_97: probe?.opacityAttr === '0.97', // R387 invariant
|
|
74
|
+
width_192: probe?.widthAttr === '192',
|
|
75
|
+
height_88: probe?.heightAttr === '88',
|
|
76
|
+
stroke_present: !!probe?.strokeAttr && probe.strokeAttr !== 'none',
|
|
77
|
+
drop_shadow_present: probe?.styleAttr.includes('drop-shadow'),
|
|
78
|
+
};
|
|
79
|
+
const ok = Object.values(results).every(Boolean);
|
|
80
|
+
console.log(`${ok ? '✅' : '❌'} hover-detail card rx 8 → 10:`, JSON.stringify(results), '\n probe:', probe);
|
|
81
|
+
process.exit(ok ? 0 : 1);
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/* Round 441 verification: hub center core fill brighten on hoveredHub.
|
|
2
|
+
* Cyber emerald-500 #10b981 → emerald-400 #34d399.
|
|
3
|
+
*
|
|
4
|
+
* Contract:
|
|
5
|
+
* - rest: core fill = '#10b981' + hovered='false'
|
|
6
|
+
* - hover the hub <g>: core fill = '#34d399' + hovered='true'
|
|
7
|
+
*/
|
|
8
|
+
import { chromium } from 'playwright';
|
|
9
|
+
import { readFileSync } from 'node:fs';
|
|
10
|
+
|
|
11
|
+
const TOKEN = JSON.parse(readFileSync('/home/vansin/.anet/config.json', 'utf8')).token;
|
|
12
|
+
const fresh = new Date(Date.now() - 60 * 1000).toISOString();
|
|
13
|
+
|
|
14
|
+
const browser = await chromium.launch({ headless: true });
|
|
15
|
+
const ctx = await browser.newContext({ viewport: { width: 1500, height: 1500 } });
|
|
16
|
+
await ctx.addCookies([{ name: 'anet_dashboard_session', value: `v3:${TOKEN}`, domain: '127.0.0.1', path: '/' }]);
|
|
17
|
+
await ctx.addInitScript(() => {
|
|
18
|
+
try { localStorage.setItem('anet-theme', 'cyber'); sessionStorage.setItem('anet_v3_auth', '1'); } catch {}
|
|
19
|
+
});
|
|
20
|
+
await ctx.route('**/api/hub/status*', async (route) => {
|
|
21
|
+
const r = await route.fetch();
|
|
22
|
+
const b = await r.json();
|
|
23
|
+
const nid = (b.sessions || [])[0]?.network_id || 'default';
|
|
24
|
+
const mk = (alias, status) => ({
|
|
25
|
+
alias, status, model: 'claude-opus-4', runtime: 'claude-code-cli',
|
|
26
|
+
network_id: nid, project_dir: null,
|
|
27
|
+
created_at: fresh, updated_at: fresh, last_seen_at: fresh,
|
|
28
|
+
});
|
|
29
|
+
await route.fulfill({ response: r, json: { ...b, sessions: [
|
|
30
|
+
mk('alpha', 'working'),
|
|
31
|
+
mk('beta', 'idle'),
|
|
32
|
+
] } });
|
|
33
|
+
});
|
|
34
|
+
await ctx.route('**/api/hub/messages*', (r) => r.fulfill({ json: { messages: [] } }));
|
|
35
|
+
await ctx.route('**/api/hub/tasks*', (r) => r.fulfill({ json: { tasks: [] } }));
|
|
36
|
+
|
|
37
|
+
const page = await ctx.newPage();
|
|
38
|
+
await page.goto('http://127.0.0.1:3000/', { waitUntil: 'domcontentloaded' });
|
|
39
|
+
await page.waitForSelector('[data-topo-hub-core]', { timeout: 15000 });
|
|
40
|
+
await page.waitForTimeout(400);
|
|
41
|
+
|
|
42
|
+
const readCore = () => page.evaluate(() => {
|
|
43
|
+
const c = document.querySelector('[data-topo-hub-core]');
|
|
44
|
+
return c ? {
|
|
45
|
+
fill_attr: c.getAttribute('fill'),
|
|
46
|
+
fill_data: c.getAttribute('data-topo-hub-core-fill'),
|
|
47
|
+
hovered: c.getAttribute('data-topo-hub-core-hovered'),
|
|
48
|
+
r: c.getAttribute('r'),
|
|
49
|
+
} : null;
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
const rest = await readCore();
|
|
53
|
+
|
|
54
|
+
const hubBox = await page.evaluate(() => {
|
|
55
|
+
const hub = document.querySelector('[data-topo-hub]');
|
|
56
|
+
if (!hub) return null;
|
|
57
|
+
const b = hub.getBoundingClientRect();
|
|
58
|
+
return { x: b.x + b.width / 2, y: b.y + b.height / 2 };
|
|
59
|
+
});
|
|
60
|
+
let hover = null;
|
|
61
|
+
if (hubBox) {
|
|
62
|
+
await page.mouse.move(hubBox.x, hubBox.y);
|
|
63
|
+
await page.waitForTimeout(300);
|
|
64
|
+
hover = await readCore();
|
|
65
|
+
await page.mouse.move(0, 0);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const fileText = readFileSync('/home/vansin/agent-network-dashboard/app/components/TopoGraph.tsx', 'utf8');
|
|
69
|
+
const sourceWired = /const coreFill = isLight\s*\n\s*\?\s*\(isCoreHovered \? '#10b981' : '#059669'\)\s*\n\s*:\s*\(isCoreHovered \? '#34d399' : '#10b981'\)/.test(fileText);
|
|
70
|
+
|
|
71
|
+
await browser.close();
|
|
72
|
+
|
|
73
|
+
const results = {
|
|
74
|
+
rest_mounted: !!rest,
|
|
75
|
+
rest_fill_emerald_500: rest?.fill_data === '#10b981',
|
|
76
|
+
rest_hovered_false: rest?.hovered === 'false',
|
|
77
|
+
rest_r_10: rest?.r === '10',
|
|
78
|
+
hover_fill_emerald_400: hover?.fill_data === '#34d399',
|
|
79
|
+
hover_hovered_true: hover?.hovered === 'true',
|
|
80
|
+
source_wired: sourceWired,
|
|
81
|
+
};
|
|
82
|
+
const ok = Object.values(results).every(Boolean);
|
|
83
|
+
console.log(`${ok ? '✅' : '❌'} hub core fill hover:`, JSON.stringify(results),
|
|
84
|
+
'\n rest:', rest, '\n hover:', hover);
|
|
85
|
+
process.exit(ok ? 0 : 1);
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/* Round 360 verification: hub working-count digit fontSize 11 → 12.
|
|
2
|
+
* The hub is the canvas's focal point — its digit is the most-read
|
|
3
|
+
* scalar on the whole topology. R130 sized it at 11 inside the
|
|
4
|
+
* r=10 / 20-px core; R360 nudges to 12 (~13 px wide × 12 px tall,
|
|
5
|
+
* still well inside) for ~9 % more presence. Sibling visual-weight
|
|
6
|
+
* bump family with R287/R295/R359.
|
|
7
|
+
*
|
|
8
|
+
* Contract:
|
|
9
|
+
* - Hub digit font-size attr === '12'.
|
|
10
|
+
* - data-topo-hub-working-count-font-size === '12'.
|
|
11
|
+
* - data-topo-hub-working-count surfaces the count (>0 with mocked
|
|
12
|
+
* working sessions).
|
|
13
|
+
* - Pre-R360 invariants: R225 tabular-nums + R209 scale-on-hover
|
|
14
|
+
* transform-box still set, fontWeight=700, dy="0.36em" preserved.
|
|
15
|
+
* - Overlap-test stays green (digit is inside hub <g>, not a node
|
|
16
|
+
* the overlap probe scans).
|
|
17
|
+
*/
|
|
18
|
+
import { chromium } from 'playwright';
|
|
19
|
+
import { readFileSync } from 'node:fs';
|
|
20
|
+
|
|
21
|
+
const TOKEN = JSON.parse(readFileSync('/home/vansin/.anet/config.json', 'utf8')).token;
|
|
22
|
+
const browser = await chromium.launch({ headless: true });
|
|
23
|
+
const ctx = await browser.newContext({ viewport: { width: 1500, height: 1500 } });
|
|
24
|
+
await ctx.addCookies([{ name: 'anet_dashboard_session', value: `v3:${TOKEN}`, domain: '127.0.0.1', path: '/' }]);
|
|
25
|
+
await ctx.addInitScript(() => {
|
|
26
|
+
try { localStorage.setItem('anet-theme', 'cyber'); sessionStorage.setItem('anet_v3_auth', '1'); } catch {}
|
|
27
|
+
});
|
|
28
|
+
const fresh = new Date(Date.now() - 60 * 1000).toISOString();
|
|
29
|
+
await ctx.route('**/api/hub/status*', async (route) => {
|
|
30
|
+
const r = await route.fetch();
|
|
31
|
+
const b = await r.json();
|
|
32
|
+
const nid = (b.sessions || [])[0]?.network_id || 'default';
|
|
33
|
+
const mk = (alias) => ({
|
|
34
|
+
alias, status: 'working', 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
|
+
// 3 working sessions → workingCount=3 → digit visible.
|
|
39
|
+
await route.fulfill({ response: r, json: { ...b, sessions: [ mk('a'), mk('b'), mk('c') ] } });
|
|
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
|
+
|
|
44
|
+
const page = await ctx.newPage();
|
|
45
|
+
await page.goto('http://127.0.0.1:3000/', { waitUntil: 'domcontentloaded' });
|
|
46
|
+
await page.waitForSelector('[data-topo-hub-working-count]', { timeout: 15000 });
|
|
47
|
+
await page.waitForTimeout(300);
|
|
48
|
+
|
|
49
|
+
const probe = await page.evaluate(() => {
|
|
50
|
+
const t = document.querySelector('[data-topo-hub-working-count]');
|
|
51
|
+
const cs = t ? getComputedStyle(t) : null;
|
|
52
|
+
return {
|
|
53
|
+
fontSizeAttr: t?.getAttribute('font-size') ?? null,
|
|
54
|
+
fontSizeData: t?.getAttribute('data-topo-hub-working-count-font-size') ?? null,
|
|
55
|
+
countValue: t?.getAttribute('data-topo-hub-working-count') ?? null,
|
|
56
|
+
fontWeight: t?.getAttribute('font-weight') ?? null,
|
|
57
|
+
dy: t?.getAttribute('dy') ?? null,
|
|
58
|
+
fontVariant: cs?.fontVariantNumeric ?? null,
|
|
59
|
+
transformBox: cs?.transformBox ?? null,
|
|
60
|
+
transformOrigin: cs?.transformOrigin ?? null,
|
|
61
|
+
transition: cs?.transition ?? null,
|
|
62
|
+
opacity: t?.getAttribute('opacity') ?? null,
|
|
63
|
+
};
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
await browser.close();
|
|
67
|
+
|
|
68
|
+
const hasTrans = (s, prop) =>
|
|
69
|
+
new RegExp(`${prop}\\s+\\d*\\.?\\d*s|${prop}\\s+\\d+ms`, 'i').test(s || '');
|
|
70
|
+
|
|
71
|
+
const results = {
|
|
72
|
+
font_size_attr_12: probe.fontSizeAttr === '12',
|
|
73
|
+
data_font_size_12: probe.fontSizeData === '12',
|
|
74
|
+
count_value_3: probe.countValue === '3', // 3 mocked working sessions
|
|
75
|
+
font_weight_700: probe.fontWeight === '700',
|
|
76
|
+
dy_0_36em: probe.dy === '0.36em',
|
|
77
|
+
tabular_nums: /tabular-nums/.test(probe.fontVariant || ''), // R225
|
|
78
|
+
transform_box_fill: probe.transformBox === 'fill-box', // R209
|
|
79
|
+
trans_has_transform: hasTrans(probe.transition, 'transform'), // R209
|
|
80
|
+
trans_has_fill: hasTrans(probe.transition, 'fill'), // R253
|
|
81
|
+
opacity_visible: probe.opacity === '1',
|
|
82
|
+
};
|
|
83
|
+
const ok = Object.values(results).every(Boolean);
|
|
84
|
+
console.log(`${ok ? '✅' : '❌'} hub digit fontSize 11 → 12:`, JSON.stringify(results),
|
|
85
|
+
'\n probe:', probe);
|
|
86
|
+
process.exit(ok ? 0 : 1);
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/* Round 425 verification: hub digit fontWeight 700 → 800 on
|
|
2
|
+
* hoveredHub. Closes the "data tightens under attention" pattern
|
|
3
|
+
* across three focal scopes:
|
|
4
|
+
* chip-digit (R416, chip scope)
|
|
5
|
+
* panel-digit (R424, panel-header scope)
|
|
6
|
+
* hub-digit (R425, hub focal scope)
|
|
7
|
+
*
|
|
8
|
+
* Contract:
|
|
9
|
+
* - rest state: hub digit attr font-weight === '700'
|
|
10
|
+
* - hover state: digit attr font-weight === '800'
|
|
11
|
+
* - geometry/family invariants preserved:
|
|
12
|
+
* fontSize=12 (R360), tabular-nums (R225),
|
|
13
|
+
* R209 scale-1.08 transform on hover
|
|
14
|
+
* - source-file probe confirms wired conditional + transition list
|
|
15
|
+
*/
|
|
16
|
+
import { chromium } from 'playwright';
|
|
17
|
+
import { readFileSync } from 'node:fs';
|
|
18
|
+
|
|
19
|
+
const TOKEN = JSON.parse(readFileSync('/home/vansin/.anet/config.json', 'utf8')).token;
|
|
20
|
+
const fresh = new Date(Date.now() - 60 * 1000).toISOString();
|
|
21
|
+
|
|
22
|
+
const browser = await chromium.launch({ headless: true });
|
|
23
|
+
const ctx = await browser.newContext({ viewport: { width: 1500, height: 1500 } });
|
|
24
|
+
await ctx.addCookies([{ name: 'anet_dashboard_session', value: `v3:${TOKEN}`, domain: '127.0.0.1', path: '/' }]);
|
|
25
|
+
await ctx.addInitScript(() => {
|
|
26
|
+
try { localStorage.setItem('anet-theme', 'cyber'); sessionStorage.setItem('anet_v3_auth', '1'); } catch {}
|
|
27
|
+
});
|
|
28
|
+
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, status) => ({
|
|
33
|
+
alias, status, 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
|
+
// include working sessions so workingCount > 0 → digit visible
|
|
38
|
+
await route.fulfill({ response: r, json: { ...b, sessions: [
|
|
39
|
+
mk('alpha', 'working'),
|
|
40
|
+
mk('beta', 'working'),
|
|
41
|
+
mk('gamma', 'idle'),
|
|
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
|
+
|
|
47
|
+
const page = await ctx.newPage();
|
|
48
|
+
await page.goto('http://127.0.0.1:3000/', { waitUntil: 'domcontentloaded' });
|
|
49
|
+
await page.waitForSelector('[data-topo-hub-working-count]', { timeout: 15000 });
|
|
50
|
+
await page.waitForTimeout(400);
|
|
51
|
+
|
|
52
|
+
const readDigit = () => page.evaluate(() => {
|
|
53
|
+
const t = document.querySelector('[data-topo-hub-working-count]');
|
|
54
|
+
if (!t) return null;
|
|
55
|
+
return {
|
|
56
|
+
text: t.textContent,
|
|
57
|
+
fw: t.getAttribute('font-weight'),
|
|
58
|
+
fontSize: t.getAttribute('font-size'),
|
|
59
|
+
hovered: t.getAttribute('data-topo-hub-working-count-hovered'),
|
|
60
|
+
count_attr: t.getAttribute('data-topo-hub-working-count'),
|
|
61
|
+
};
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
const rest = await readDigit();
|
|
65
|
+
|
|
66
|
+
// Trigger hub hover via the hub <g> element (data-topo-hub).
|
|
67
|
+
const hubBox = await page.evaluate(() => {
|
|
68
|
+
const hub = document.querySelector('[data-topo-hub]');
|
|
69
|
+
if (!hub) return null;
|
|
70
|
+
const b = hub.getBoundingClientRect();
|
|
71
|
+
return { x: b.x + b.width / 2, y: b.y + b.height / 2 };
|
|
72
|
+
});
|
|
73
|
+
let hover = null;
|
|
74
|
+
if (hubBox) {
|
|
75
|
+
await page.mouse.move(hubBox.x, hubBox.y);
|
|
76
|
+
await page.waitForTimeout(300);
|
|
77
|
+
hover = await readDigit();
|
|
78
|
+
// move mouse away to release hover for clean teardown
|
|
79
|
+
await page.mouse.move(0, 0);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// Source-file verification
|
|
83
|
+
const fileText = readFileSync('/home/vansin/agent-network-dashboard/app/components/TopoGraph.tsx', 'utf8');
|
|
84
|
+
const sourceWired = /fontWeight=\{hoveredHub \? '800' : '700'\}/.test(fileText);
|
|
85
|
+
const sourceTransition = /transition: 'transform 200ms ease-out, opacity 300ms ease-out, fill 200ms ease-out, font-weight 200ms ease-out'/.test(fileText);
|
|
86
|
+
|
|
87
|
+
await browser.close();
|
|
88
|
+
|
|
89
|
+
const results = {
|
|
90
|
+
rest_mounted: !!rest,
|
|
91
|
+
rest_fw_700: rest?.fw === '700',
|
|
92
|
+
rest_font_size_12: rest?.fontSize === '12',
|
|
93
|
+
rest_hovered_false: rest?.hovered === 'false',
|
|
94
|
+
hover_fw_800: hover?.fw === '800',
|
|
95
|
+
hover_hovered_true: hover?.hovered === 'true',
|
|
96
|
+
source_hover_wired: sourceWired,
|
|
97
|
+
source_transition_wired: sourceTransition,
|
|
98
|
+
};
|
|
99
|
+
const ok = Object.values(results).every(Boolean);
|
|
100
|
+
console.log(`${ok ? '✅' : '❌'} hub digit fw hover:`, JSON.stringify(results),
|
|
101
|
+
'\n rest:', rest, '\n hover:', hover);
|
|
102
|
+
process.exit(ok ? 0 : 1);
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/* Round 405 verification: hub-halo LIGHT trough 0.32 → 0.34 —
|
|
2
|
+
* symmetrizes R404 cyber treatment across both themes. Probes
|
|
3
|
+
* both cyber and light theme states via two browser contexts.
|
|
4
|
+
*
|
|
5
|
+
* Contract:
|
|
6
|
+
* - Idle fixture (workingCount=0, bucket=0):
|
|
7
|
+
* * cyber: data-topo-hub-halo-trough === '0.1' (R404 invariant)
|
|
8
|
+
* * light: data-topo-hub-halo-trough === '0.34' (R405 lift)
|
|
9
|
+
* * both: data-hub-busyness === '0'
|
|
10
|
+
* * both: data-topo-hub-halo-peak per-theme invariant
|
|
11
|
+
* (cyber 0.16, light 0.52)
|
|
12
|
+
* - Source-file verification:
|
|
13
|
+
* * const troughLight = 0.34;
|
|
14
|
+
* * const troughDark = 0.10;
|
|
15
|
+
*/
|
|
16
|
+
import { chromium } from 'playwright';
|
|
17
|
+
import { readFileSync } from 'node:fs';
|
|
18
|
+
|
|
19
|
+
const TOKEN = JSON.parse(readFileSync('/home/vansin/.anet/config.json', 'utf8')).token;
|
|
20
|
+
const fresh = new Date(Date.now() - 60 * 1000).toISOString();
|
|
21
|
+
|
|
22
|
+
async function probeTheme(theme) {
|
|
23
|
+
const browser = await chromium.launch({ headless: true });
|
|
24
|
+
const ctx = await browser.newContext({ viewport: { width: 1500, height: 1500 } });
|
|
25
|
+
await ctx.addCookies([{ name: 'anet_dashboard_session', value: `v3:${TOKEN}`, domain: '127.0.0.1', path: '/' }]);
|
|
26
|
+
await ctx.addInitScript((t) => {
|
|
27
|
+
try { localStorage.setItem('anet-theme', t); sessionStorage.setItem('anet_v3_auth', '1'); } catch {}
|
|
28
|
+
}, theme);
|
|
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('alpha'), mk('beta') ] } });
|
|
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: 'domcontentloaded' });
|
|
44
|
+
await page.waitForSelector('[data-hub-busyness]', { timeout: 15000 });
|
|
45
|
+
await page.waitForTimeout(400);
|
|
46
|
+
const probe = await page.evaluate(() => {
|
|
47
|
+
const halo = document.querySelector('[data-hub-busyness]');
|
|
48
|
+
if (!halo) return null;
|
|
49
|
+
return {
|
|
50
|
+
busyness: halo.getAttribute('data-hub-busyness'),
|
|
51
|
+
trough: halo.getAttribute('data-topo-hub-halo-trough'),
|
|
52
|
+
peak: halo.getAttribute('data-topo-hub-halo-peak'),
|
|
53
|
+
fill: halo.getAttribute('fill'),
|
|
54
|
+
};
|
|
55
|
+
});
|
|
56
|
+
await browser.close();
|
|
57
|
+
return probe;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const cyber = await probeTheme('cyber');
|
|
61
|
+
const light = await probeTheme('light');
|
|
62
|
+
|
|
63
|
+
const fileText = readFileSync('/home/vansin/agent-network-dashboard/app/components/TopoGraph.tsx', 'utf8');
|
|
64
|
+
const sourceLight034 = /const troughLight\s*=\s*0\.34;/.test(fileText);
|
|
65
|
+
const sourceDark010 = /const troughDark\s*=\s*0\.10;/.test(fileText);
|
|
66
|
+
const sourceLightPeak = /const peakLight\s*=\s*\[0\.52, 0\.58, 0\.65, 0\.72\]\[busy\];/.test(fileText);
|
|
67
|
+
|
|
68
|
+
const results = {
|
|
69
|
+
// Cyber R404 invariant
|
|
70
|
+
cyber_busy_0: cyber?.busyness === '0',
|
|
71
|
+
cyber_trough_0_1: cyber?.trough === '0.1',
|
|
72
|
+
cyber_peak_0_16: cyber?.peak === '0.16',
|
|
73
|
+
cyber_fill_dark: cyber?.fill === '#10b981',
|
|
74
|
+
// Light R405 lift
|
|
75
|
+
light_busy_0: light?.busyness === '0',
|
|
76
|
+
light_trough_0_34: light?.trough === '0.34',
|
|
77
|
+
light_peak_0_52: light?.peak === '0.52',
|
|
78
|
+
light_fill_light: light?.fill === '#d1fae5',
|
|
79
|
+
// Source-file canonical wire
|
|
80
|
+
source_light_034: sourceLight034,
|
|
81
|
+
source_dark_010: sourceDark010,
|
|
82
|
+
source_light_peak: sourceLightPeak,
|
|
83
|
+
};
|
|
84
|
+
const ok = Object.values(results).every(Boolean);
|
|
85
|
+
console.log(`${ok ? '✅' : '❌'} hub-halo light trough 0.32 → 0.34:`, JSON.stringify(results),
|
|
86
|
+
'\n cyber:', cyber,
|
|
87
|
+
'\n light:', light);
|
|
88
|
+
process.exit(ok ? 0 : 1);
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/* Round 451 verification: hub center halo radius hover lift —
|
|
2
|
+
* r 20 → 22 on hoveredHub.
|
|
3
|
+
*
|
|
4
|
+
* Contract:
|
|
5
|
+
* - rest: hub halo reports data-topo-hub-halo-radius '20' + hovered='false'
|
|
6
|
+
* - hover the hub <g>: halo lifts to r '22' + hovered='true'
|
|
7
|
+
*/
|
|
8
|
+
import { chromium } from 'playwright';
|
|
9
|
+
import { readFileSync } from 'node:fs';
|
|
10
|
+
|
|
11
|
+
const TOKEN = JSON.parse(readFileSync('/home/vansin/.anet/config.json', 'utf8')).token;
|
|
12
|
+
const fresh = new Date(Date.now() - 60 * 1000).toISOString();
|
|
13
|
+
|
|
14
|
+
const browser = await chromium.launch({ headless: true });
|
|
15
|
+
const ctx = await browser.newContext({ viewport: { width: 1500, height: 1500 } });
|
|
16
|
+
await ctx.addCookies([{ name: 'anet_dashboard_session', value: `v3:${TOKEN}`, domain: '127.0.0.1', path: '/' }]);
|
|
17
|
+
await ctx.addInitScript(() => {
|
|
18
|
+
try { localStorage.setItem('anet-theme', 'cyber'); sessionStorage.setItem('anet_v3_auth', '1'); } catch {}
|
|
19
|
+
});
|
|
20
|
+
await ctx.route('**/api/hub/status*', async (route) => {
|
|
21
|
+
const r = await route.fetch();
|
|
22
|
+
const b = await r.json();
|
|
23
|
+
const nid = (b.sessions || [])[0]?.network_id || 'default';
|
|
24
|
+
const mk = (alias, status) => ({
|
|
25
|
+
alias, status, model: 'claude-opus-4', runtime: 'claude-code-cli',
|
|
26
|
+
network_id: nid, project_dir: null,
|
|
27
|
+
created_at: fresh, updated_at: fresh, last_seen_at: fresh,
|
|
28
|
+
});
|
|
29
|
+
await route.fulfill({ response: r, json: { ...b, sessions: [
|
|
30
|
+
mk('alpha', 'working'),
|
|
31
|
+
mk('beta', 'idle'),
|
|
32
|
+
] } });
|
|
33
|
+
});
|
|
34
|
+
await ctx.route('**/api/hub/messages*', (r) => r.fulfill({ json: { messages: [] } }));
|
|
35
|
+
await ctx.route('**/api/hub/tasks*', (r) => r.fulfill({ json: { tasks: [] } }));
|
|
36
|
+
|
|
37
|
+
const page = await ctx.newPage();
|
|
38
|
+
await page.goto('http://127.0.0.1:3000/', { waitUntil: 'domcontentloaded' });
|
|
39
|
+
await page.waitForSelector('[data-topo-hub-halo-radius]', { timeout: 15000 });
|
|
40
|
+
await page.waitForTimeout(400);
|
|
41
|
+
|
|
42
|
+
const readHalo = () => page.evaluate(() => {
|
|
43
|
+
const c = document.querySelector('[data-topo-hub-halo-radius]');
|
|
44
|
+
return c ? {
|
|
45
|
+
r_data: parseFloat(c.getAttribute('data-topo-hub-halo-radius') || '0'),
|
|
46
|
+
hovered: c.getAttribute('data-topo-hub-halo-hovered'),
|
|
47
|
+
} : null;
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
const rest = await readHalo();
|
|
51
|
+
|
|
52
|
+
let hover = null;
|
|
53
|
+
const hubBox = await page.evaluate(() => {
|
|
54
|
+
const hub = document.querySelector('[data-topo-hub]');
|
|
55
|
+
if (!hub) return null;
|
|
56
|
+
const b = hub.getBoundingClientRect();
|
|
57
|
+
return { x: b.x + b.width / 2, y: b.y + b.height / 2 };
|
|
58
|
+
});
|
|
59
|
+
if (hubBox) {
|
|
60
|
+
await page.mouse.move(hubBox.x, hubBox.y);
|
|
61
|
+
await page.waitForTimeout(300);
|
|
62
|
+
hover = await readHalo();
|
|
63
|
+
await page.mouse.move(0, 0);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const fileText = readFileSync('/home/vansin/agent-network-dashboard/app/components/TopoGraph.tsx', 'utf8');
|
|
67
|
+
const sourceWired = /const haloR = isHaloHovered \? 22 : 20/.test(fileText);
|
|
68
|
+
|
|
69
|
+
await browser.close();
|
|
70
|
+
|
|
71
|
+
const results = {
|
|
72
|
+
rest_mounted: !!rest,
|
|
73
|
+
rest_r_20: rest?.r_data === 20,
|
|
74
|
+
rest_hovered_false: rest?.hovered === 'false',
|
|
75
|
+
hover_r_22: hover?.r_data === 22,
|
|
76
|
+
hover_hovered_true: hover?.hovered === 'true',
|
|
77
|
+
source_wired: sourceWired,
|
|
78
|
+
};
|
|
79
|
+
const ok = Object.values(results).every(Boolean);
|
|
80
|
+
console.log(`${ok ? '✅' : '❌'} hub halo hover r:`, JSON.stringify(results),
|
|
81
|
+
'\n rest:', rest, '\n hover:', hover);
|
|
82
|
+
process.exit(ok ? 0 : 1);
|