@sleep2agi/agent-network-dashboard 0.5.3-preview.14 → 0.5.3-preview.140
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/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_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]__0sv~g.o._.js +1 -1
- package/.next/server/chunks/ssr/[root-of-the-server]__0sv~g.o._.js.map +1 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_09kk21a._.js +4 -4
- package/.next/server/chunks/ssr/agent-network-dashboard_09kk21a._.js.map +1 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_app_01jhlxz._.js +1 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_app_01jhlxz._.js.map +1 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_app_09d29my._.js +1 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_app_09d29my._.js.map +1 -1
- package/.next/server/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/static/chunks/006dxnaf1ojoc.js +1 -0
- package/.next/static/chunks/05-~ezd16iskp.css +2 -0
- package/.next/static/chunks/069b9-o1a2f0v.js +4 -0
- package/.next/static/chunks/{16p3.8p0yi.1p.js → 0bbv-sge~hmdb.js} +1 -1
- package/.next/static/chunks/0k930mbg_qx0j.js +1 -0
- package/.next/static/chunks/{03a4--7ncekmk.js → 0v4-5tng.uh.7.js} +2 -2
- package/.next/trace +2 -2
- package/.next/trace-build +1 -1
- package/app/components/ServersDrawer.tsx +16 -3
- package/app/components/TopoGraph.tsx +3688 -162
- package/app/globals.css +58 -7
- package/package.json +4 -4
- package/scripts/p157-servers-copy-test.mjs +95 -0
- package/scripts/topo-active-chrome-hover-text-test.mjs +107 -0
- package/scripts/topo-alias-chat-brightness-test.mjs +79 -0
- package/scripts/topo-avatar-chat-gate-test.mjs +77 -0
- package/scripts/topo-avatar-drop-shadow-test.mjs +86 -0
- package/scripts/topo-avatar-fallback-hover-test.mjs +104 -0
- package/scripts/topo-avatar-fallback-rotate-test.mjs +92 -0
- package/scripts/topo-avatar-rotate-test.mjs +85 -0
- package/scripts/topo-avatar-scale-test.mjs +89 -0
- package/scripts/topo-badge-chat-gate-test.mjs +74 -0
- package/scripts/topo-brand-drop-shadow-test.mjs +71 -0
- package/scripts/topo-brand-logo-breath-test.mjs +102 -0
- package/scripts/topo-brand-logo-hover-brightness-test.mjs +105 -0
- package/scripts/topo-brand-logo-hover-rotate-test.mjs +93 -0
- package/scripts/topo-brand-logo-hover-test.mjs +85 -0
- package/scripts/topo-card-chat-brightness-test.mjs +86 -0
- package/scripts/topo-chat-ring-brightness-test.mjs +80 -0
- package/scripts/topo-chip-row-digit-ls-test.mjs +135 -0
- package/scripts/topo-chip-row-member-alias-lit-test.mjs +154 -0
- package/scripts/topo-chip-row-tier-glow-brightness-test.mjs +99 -0
- package/scripts/topo-chip-row-unit-hover-tracking-test.mjs +124 -0
- package/scripts/topo-click-ripple-glow-test.mjs +86 -0
- package/scripts/topo-cluster-count-attr-test.mjs +80 -0
- package/scripts/topo-crescent-breath-test.mjs +104 -0
- package/scripts/topo-crescent-recede-test.mjs +111 -0
- package/scripts/topo-edge-badge-circle-brightness-test.mjs +82 -0
- package/scripts/topo-edge-badge-hover-glow-test.mjs +90 -0
- package/scripts/topo-edge-badge-text-brightness-test.mjs +83 -0
- package/scripts/topo-edge-chat-gate-test.mjs +71 -0
- package/scripts/topo-edge-particle-brightness-test.mjs +82 -0
- package/scripts/topo-edge-pill-glow-test.mjs +67 -0
- package/scripts/topo-edge-visible-brightness-test.mjs +84 -0
- package/scripts/topo-endpoint-ring-brightness-test.mjs +83 -0
- package/scripts/topo-filter-pill-glow-test.mjs +90 -0
- package/scripts/topo-fleet-density-tier-test.mjs +84 -0
- package/scripts/topo-flow-arrow-brightness-test.mjs +82 -0
- package/scripts/topo-flow-rail-brightness-test.mjs +80 -0
- package/scripts/topo-freshness-chip-fade-test.mjs +105 -0
- package/scripts/topo-fullscreen-attr-test.mjs +73 -0
- package/scripts/topo-fullscreen-brightness-test.mjs +84 -0
- package/scripts/topo-fullscreen-icon-rotate-test.mjs +93 -0
- package/scripts/topo-grid-content-bottom-attr-test.mjs +72 -0
- package/scripts/topo-group-box-brightness-test.mjs +84 -0
- package/scripts/topo-group-chat-gate-test.mjs +77 -0
- package/scripts/topo-group-label-brightness-test.mjs +84 -0
- package/scripts/topo-group-label-hover-glow-test.mjs +86 -0
- package/scripts/topo-group-label-member-alias-hover-test.mjs +125 -0
- package/scripts/topo-group-pill-glow-test.mjs +76 -0
- package/scripts/topo-group-tint-brightness-test.mjs +82 -0
- package/scripts/topo-halo-chat-gate-test.mjs +72 -0
- package/scripts/topo-hub-core-brightness-test.mjs +82 -0
- package/scripts/topo-hub-digit-brightness-test.mjs +79 -0
- package/scripts/topo-hub-digit-ls-test.mjs +119 -0
- package/scripts/topo-hub-halo-brightness-test.mjs +80 -0
- package/scripts/topo-hub-halo-glow-test.mjs +96 -0
- package/scripts/topo-hub-highlight-amplify-test.mjs +139 -0
- package/scripts/topo-hub-highlight-brightness-test.mjs +84 -0
- package/scripts/topo-hub-highlight-fill-transition-test.mjs +84 -0
- package/scripts/topo-hub-highlight-glow-test.mjs +99 -0
- package/scripts/topo-hub-highlight-r-test.mjs +112 -0
- package/scripts/topo-hub-highlight-recede-test.mjs +144 -0
- package/scripts/topo-hub-highlight-theme-fill-test.mjs +83 -0
- package/scripts/topo-hub-hover-ring-brightness-test.mjs +79 -0
- package/scripts/topo-hub-hover-ring-glow-test.mjs +97 -0
- package/scripts/topo-hub-idle-breath-test.mjs +7 -2
- package/scripts/topo-hub-recede-test.mjs +124 -0
- package/scripts/topo-hub-spoke-brightness-test.mjs +77 -0
- package/scripts/topo-hub-spoke-glow-test.mjs +112 -0
- package/scripts/topo-label-card-brightness-test.mjs +81 -0
- package/scripts/topo-layout-hover-fw-test.mjs +98 -0
- package/scripts/topo-layout-toggle-brightness-test.mjs +94 -0
- package/scripts/topo-legend-count-brightness-test.mjs +80 -0
- package/scripts/topo-legend-count-letter-spacing-test.mjs +108 -0
- package/scripts/topo-legend-label-fw-test.mjs +107 -0
- package/scripts/topo-legend-pin-ring-brightness-test.mjs +82 -0
- package/scripts/topo-legend-row-count-brightness-test.mjs +85 -0
- package/scripts/topo-legend-row-label-glow-test.mjs +102 -0
- package/scripts/topo-legend-swatch-glow-test.mjs +109 -0
- package/scripts/topo-legend-swatch-member-alias-match-test.mjs +139 -0
- package/scripts/topo-legend-tint-brightness-test.mjs +83 -0
- package/scripts/topo-minimap-hover-glow-test.mjs +109 -0
- package/scripts/topo-more-footer-brightness-test.mjs +94 -0
- package/scripts/topo-node-alias-brightness-test.mjs +84 -0
- package/scripts/topo-node-sub-text-brightness-test.mjs +88 -0
- package/scripts/topo-nodesize-brightness-test.mjs +82 -0
- package/scripts/topo-nodesize-hover-fw-test.mjs +99 -0
- package/scripts/topo-orphan-box-dash-test.mjs +89 -0
- package/scripts/topo-orphan-fill-opacity-test.mjs +91 -0
- package/scripts/topo-orphan-label-opacity-test.mjs +98 -0
- package/scripts/topo-panel-count-hover-ls-test.mjs +87 -0
- package/scripts/topo-panel-row-brightness-test.mjs +116 -0
- package/scripts/topo-panel-title-brightness-test.mjs +98 -0
- package/scripts/topo-panel-title-glow-test.mjs +111 -0
- package/scripts/topo-pill-x-rotate-test.mjs +96 -0
- package/scripts/topo-pinned-aspect-test.mjs +89 -0
- package/scripts/topo-pip-brightness-test.mjs +85 -0
- package/scripts/topo-pressure-seg-glow-test.mjs +92 -0
- package/scripts/topo-pressure-seg-member-alias-match-test.mjs +133 -0
- package/scripts/topo-pressure-seg-motion-test.mjs +101 -0
- package/scripts/topo-recent-count-brightness-test.mjs +84 -0
- package/scripts/topo-recent-more-fw-test.mjs +126 -0
- package/scripts/topo-recent-row-chat-gate-test.mjs +75 -0
- package/scripts/topo-recent-row-fw-test.mjs +115 -0
- package/scripts/topo-recent-row-text-glow-test.mjs +86 -0
- package/scripts/topo-recent-tint-brightness-test.mjs +80 -0
- package/scripts/topo-recent-ts-brightness-test.mjs +86 -0
- package/scripts/topo-reduced-motion-attr-test.mjs +69 -0
- package/scripts/topo-reset-brightness-test.mjs +83 -0
- package/scripts/topo-reset-icon-hover-scale-test.mjs +102 -0
- package/scripts/topo-runtime-badge-brightness-test.mjs +78 -0
- package/scripts/topo-runtime-badge-glow-test.mjs +108 -0
- package/scripts/topo-runtime-badge-rotate-test.mjs +85 -0
- package/scripts/topo-spoke-chat-gate-test.mjs +72 -0
- package/scripts/topo-starfield-hue-test.mjs +109 -0
- package/scripts/topo-status-ring-brightness-test.mjs +84 -0
- package/scripts/topo-status-ring-chat-gate-test.mjs +72 -0
- package/scripts/topo-sub-text-chat-brightness-test.mjs +81 -0
- package/scripts/topo-titleblock-h2-hover-fw-test.mjs +109 -0
- package/scripts/topo-titleblock-h2-hover-tracking-test.mjs +128 -0
- package/scripts/topo-titleblock-kicker-hover-test.mjs +134 -0
- package/scripts/topo-vendor-chip-glow-test.mjs +97 -0
- package/scripts/topo-vendor-pill-glow-test.mjs +98 -0
- package/scripts/topo-watermark-breath-test.mjs +100 -0
- package/scripts/topo-watermark-recede-test.mjs +114 -0
- package/scripts/topo-zoom-buttons-brightness-test.mjs +94 -0
- package/scripts/topo-zoom-level-brightness-test.mjs +83 -0
- package/scripts/topo-zoom-level-color-test.mjs +105 -0
- package/.next/static/chunks/0ckoz2evm~lvq.js +0 -1
- package/.next/static/chunks/0m.1mvl~t.avc.css +0 -2
- package/.next/static/chunks/0qf8ynb6zk1~~.js +0 -4
- package/.next/static/chunks/10s69w5k6v8cr.js +0 -1
- /package/.next/static/{Q8lkSZiF_OETF8cugX0IW → AGbxLByQywWb5JcOo5dTf}/_buildManifest.js +0 -0
- /package/.next/static/{Q8lkSZiF_OETF8cugX0IW → AGbxLByQywWb5JcOo5dTf}/_clientMiddlewareManifest.js +0 -0
- /package/.next/static/{Q8lkSZiF_OETF8cugX0IW → AGbxLByQywWb5JcOo5dTf}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/* Round 622 — extend hub-spoke isHoveredSpoke gate to include
|
|
2
|
+
* chatAlias. Single conceptual change cascades the spoke's
|
|
3
|
+
* opacity + sw axes to also fire on chat-target. 8th anchor in
|
|
4
|
+
* chat-target-gated brightness family.
|
|
5
|
+
*
|
|
6
|
+
* Test phases:
|
|
7
|
+
* 1. mock 2 idle nodes → hub-spokes render
|
|
8
|
+
* 2. rest: spoke at idle opacity (0.50) + idle sw (1)
|
|
9
|
+
* 3. source: isHoveredSpoke declaration uses gate union
|
|
10
|
+
* (hoveredAlias || chatAlias)
|
|
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-topo-hub-spoke-hovered]', { timeout: 15000, state: 'attached' });
|
|
44
|
+
await page.waitForTimeout(500);
|
|
45
|
+
|
|
46
|
+
const rest = await page.evaluate(() => {
|
|
47
|
+
const el = document.querySelector('[data-topo-hub-spoke-hovered]');
|
|
48
|
+
if (!el) return null;
|
|
49
|
+
return {
|
|
50
|
+
hoveredAttr: el.getAttribute('data-topo-hub-spoke-hovered'),
|
|
51
|
+
opacityAttr: el.getAttribute('data-topo-hub-spoke-opacity'),
|
|
52
|
+
swAttr: el.getAttribute('data-topo-hub-spoke-stroke-width'),
|
|
53
|
+
};
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
await browser.close();
|
|
57
|
+
|
|
58
|
+
const src = readFileSync('/home/vansin/agent-network-dashboard/app/components/TopoGraph.tsx', 'utf8');
|
|
59
|
+
const sourceGate = /const isHoveredSpoke = !reducedMotion && \(hoveredAlias === session\.alias \|\| chatAlias === session\.alias\)/.test(src);
|
|
60
|
+
|
|
61
|
+
const results = {
|
|
62
|
+
spoke_present: !!rest,
|
|
63
|
+
rest_hovered_false: rest?.hoveredAttr === 'false',
|
|
64
|
+
rest_opacity_idle: rest?.opacityAttr === '0.5', // idle no-hover
|
|
65
|
+
rest_sw_idle: rest?.swAttr === '1', // idle no-hover
|
|
66
|
+
source_gate_or: sourceGate,
|
|
67
|
+
};
|
|
68
|
+
const ok = Object.values(results).every(Boolean);
|
|
69
|
+
console.log(`${ok ? '✅' : '❌'} R622 hub-spoke chat-target gate (chat-gated family 8th anchor):`,
|
|
70
|
+
JSON.stringify(results, null, 2),
|
|
71
|
+
`\n rest: ${JSON.stringify(rest)}`);
|
|
72
|
+
process.exit(ok ? 0 : 1);
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/* Round 523 verification: starfield gains 3-hue deterministic color
|
|
2
|
+
* rotation (indigo / cyan / slate) instead of flat #a5b4fc. 配色 family
|
|
3
|
+
* 3rd anchor (cyber theme; light theme unaffected per starfield gate).
|
|
4
|
+
*
|
|
5
|
+
* Test phases:
|
|
6
|
+
* 1. cyber: 14 dots present, each carries data-topo-starfield-dot-hue
|
|
7
|
+
* with one of: indigo / cyan / slate
|
|
8
|
+
* 2. distribution: dots at i % 3 === 0 → indigo (#a5b4fc),
|
|
9
|
+
* i % 3 === 1 → cyan (#67e8f9), i % 3 === 2 → slate (#cbd5e1)
|
|
10
|
+
* → 14 dots → 5 indigo + 5 cyan + 4 slate (indices 0..13)
|
|
11
|
+
* 3. all three hues present
|
|
12
|
+
* 4. light theme: starfield not rendered at all (existing gate)
|
|
13
|
+
* 5. source-side regex confirms hues array + dot-hue attr wired
|
|
14
|
+
*/
|
|
15
|
+
import { chromium } from 'playwright';
|
|
16
|
+
import { readFileSync } from 'node:fs';
|
|
17
|
+
|
|
18
|
+
const TOKEN = JSON.parse(readFileSync('/home/vansin/.anet/config.json', 'utf8')).token;
|
|
19
|
+
const fresh = new Date(Date.now() - 60 * 1000).toISOString();
|
|
20
|
+
|
|
21
|
+
async function probe(theme) {
|
|
22
|
+
const browser = await chromium.launch({ headless: true });
|
|
23
|
+
const ctx = await browser.newContext({ viewport: { width: 1500, height: 1200 } });
|
|
24
|
+
await ctx.addCookies([{ name: 'anet_dashboard_session', value: `v3:${TOKEN}`, domain: '127.0.0.1', path: '/' }]);
|
|
25
|
+
await ctx.addInitScript((t) => {
|
|
26
|
+
try {
|
|
27
|
+
localStorage.setItem('anet-theme', t);
|
|
28
|
+
localStorage.setItem('anet-topo-layout', 'ring');
|
|
29
|
+
sessionStorage.setItem('anet_v3_auth', '1');
|
|
30
|
+
} catch {}
|
|
31
|
+
}, theme);
|
|
32
|
+
await ctx.route('**/api/hub/status*', async (route) => {
|
|
33
|
+
const r = await route.fetch();
|
|
34
|
+
const b = await r.json();
|
|
35
|
+
const nid = (b.sessions || [])[0]?.network_id || 'default';
|
|
36
|
+
const mk = (alias) => ({
|
|
37
|
+
alias, status: 'idle', model: 'claude-opus-4', runtime: 'claude-code-cli',
|
|
38
|
+
network_id: nid, project_dir: null,
|
|
39
|
+
created_at: fresh, updated_at: fresh, last_seen_at: fresh,
|
|
40
|
+
});
|
|
41
|
+
await route.fulfill({ response: r, json: { ...b, sessions: [mk('a·1')] } });
|
|
42
|
+
});
|
|
43
|
+
await ctx.route('**/api/hub/messages*', (r) => r.fulfill({ json: { messages: [] } }));
|
|
44
|
+
await ctx.route('**/api/hub/tasks*', (r) => r.fulfill({ json: { tasks: [] } }));
|
|
45
|
+
const page = await ctx.newPage();
|
|
46
|
+
await page.goto('http://127.0.0.1:3000/', { waitUntil: 'networkidle' });
|
|
47
|
+
await page.waitForSelector('svg[data-topo-layout]', { timeout: 15000 });
|
|
48
|
+
await page.waitForTimeout(800);
|
|
49
|
+
const data = await page.evaluate(() => {
|
|
50
|
+
const dots = Array.from(document.querySelectorAll('[data-topo-starfield-dot]'));
|
|
51
|
+
return dots.map((el) => ({
|
|
52
|
+
idx: el.getAttribute('data-topo-starfield-dot'),
|
|
53
|
+
hue: el.getAttribute('data-topo-starfield-dot-hue'),
|
|
54
|
+
fill: el.getAttribute('fill'),
|
|
55
|
+
}));
|
|
56
|
+
});
|
|
57
|
+
await browser.close();
|
|
58
|
+
return data;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const cyber = await probe('cyber');
|
|
62
|
+
const light = await probe('light');
|
|
63
|
+
|
|
64
|
+
// Source regex
|
|
65
|
+
const src = readFileSync('/home/vansin/agent-network-dashboard/app/components/TopoGraph.tsx', 'utf8');
|
|
66
|
+
const sourceHuesArr =
|
|
67
|
+
/const hues = \['#a5b4fc', '#67e8f9', '#cbd5e1'\] as const;/.test(src);
|
|
68
|
+
const sourceNamesArr =
|
|
69
|
+
/const hueNames = \['indigo', 'cyan', 'slate'\] as const;/.test(src);
|
|
70
|
+
const sourceAttrWired =
|
|
71
|
+
/data-topo-starfield-dot-hue=\{hueNames\[hueIdx\]\}/.test(src);
|
|
72
|
+
|
|
73
|
+
// Cyber: 14 dots, distribution by i % 3
|
|
74
|
+
const cyberHueCounts = { indigo: 0, cyan: 0, slate: 0 };
|
|
75
|
+
for (const d of cyber) {
|
|
76
|
+
if (d.hue && cyberHueCounts[d.hue] !== undefined) cyberHueCounts[d.hue]++;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Verify each idx has the right hue per i % 3
|
|
80
|
+
const cyberIdxMatch = cyber.every((d) => {
|
|
81
|
+
const i = parseInt(d.idx, 10);
|
|
82
|
+
const expected = ['indigo', 'cyan', 'slate'][i % 3];
|
|
83
|
+
return d.hue === expected;
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
// Verify fill matches the hue
|
|
87
|
+
const cyberFillMatch = cyber.every((d) => {
|
|
88
|
+
const expectedFill = { indigo: '#a5b4fc', cyan: '#67e8f9', slate: '#cbd5e1' }[d.hue];
|
|
89
|
+
return d.fill === expectedFill;
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
const results = {
|
|
93
|
+
cyber_dot_count_14: cyber.length === 14,
|
|
94
|
+
cyber_indigo_count_5: cyberHueCounts.indigo === 5, // i=0,3,6,9,12 → 5
|
|
95
|
+
cyber_cyan_count_5: cyberHueCounts.cyan === 5, // i=1,4,7,10,13 → 5
|
|
96
|
+
cyber_slate_count_4: cyberHueCounts.slate === 4, // i=2,5,8,11 → 4
|
|
97
|
+
cyber_idx_to_hue_match: cyberIdxMatch,
|
|
98
|
+
cyber_hue_to_fill_match: cyberFillMatch,
|
|
99
|
+
light_starfield_empty: light.length === 0,
|
|
100
|
+
source_hues_array: sourceHuesArr,
|
|
101
|
+
source_names_array: sourceNamesArr,
|
|
102
|
+
source_attr_wired: sourceAttrWired,
|
|
103
|
+
};
|
|
104
|
+
const ok = Object.values(results).every(Boolean);
|
|
105
|
+
console.log(`${ok ? '✅' : '❌'} R523 starfield 3-hue rotation:`,
|
|
106
|
+
JSON.stringify(results, null, 2),
|
|
107
|
+
'\n cyber distribution:', JSON.stringify(cyberHueCounts),
|
|
108
|
+
'\n light count:', light.length);
|
|
109
|
+
process.exit(ok ? 0 : 1);
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/* Round 584 verification: node status ring gains filter
|
|
2
|
+
* brightness(1.15) on hover. 23rd anchor in per-element
|
|
3
|
+
* brightness family. Stacks with url(#topo-glow) on
|
|
4
|
+
* cyber+online; plain brightness on light or cyber+offline.
|
|
5
|
+
*
|
|
6
|
+
* Test phases:
|
|
7
|
+
* 1. mock 2 idle nodes → status rings render
|
|
8
|
+
* 2. rest (cyber+online): filter='url("#topo-glow")'
|
|
9
|
+
* (no brightness stacked, no hover state)
|
|
10
|
+
* 3. brightness-attr='1' at rest
|
|
11
|
+
* 4. transition-property contains 'filter'
|
|
12
|
+
* 5. source: filter conditional (three-way tree) + data-attr
|
|
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-status-ring]', { timeout: 15000, state: 'attached' });
|
|
46
|
+
await page.waitForTimeout(500);
|
|
47
|
+
|
|
48
|
+
const rest = await page.evaluate(() => {
|
|
49
|
+
const el = document.querySelector('[data-node-status-ring]');
|
|
50
|
+
if (!el) return null;
|
|
51
|
+
const cs = getComputedStyle(el);
|
|
52
|
+
return {
|
|
53
|
+
filter: cs.filter,
|
|
54
|
+
transitionProperty: cs.transitionProperty,
|
|
55
|
+
brightnessAttr: el.getAttribute('data-node-status-ring-brightness'),
|
|
56
|
+
hoveredAttr: el.getAttribute('data-node-status-ring-hovered'),
|
|
57
|
+
label: el.getAttribute('data-node-status-ring'),
|
|
58
|
+
};
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
await browser.close();
|
|
62
|
+
|
|
63
|
+
const src = readFileSync('/home/vansin/agent-network-dashboard/app/components/TopoGraph.tsx', 'utf8');
|
|
64
|
+
const sourceFilter = /filter: isRingHovered\s*\?\s*\(isLight\s*\?\s*'brightness\(1\.15\)'\s*:\s*\(isOnline\s*\?\s*'url\(#topo-glow\) brightness\(1\.15\)'\s*:\s*'brightness\(1\.15\)'\)\)\s*:\s*undefined/.test(src);
|
|
65
|
+
const sourceAttr = /data-node-status-ring-brightness=\{isRingHovered \? '1\.15' : '1'\}/.test(src);
|
|
66
|
+
const sourceTransition = /transition: 'fill 300ms ease-out, stroke 300ms ease-out, stroke-width 300ms ease-out, filter 300ms ease-out'/.test(src);
|
|
67
|
+
|
|
68
|
+
const results = {
|
|
69
|
+
ring_present: !!rest,
|
|
70
|
+
// On cyber+online (mock default), SVG attribute filter applies at rest
|
|
71
|
+
rest_filter_has_url: /url\(/.test(rest?.filter || ''),
|
|
72
|
+
rest_filter_no_brightness: !/brightness\(/.test(rest?.filter || ''),
|
|
73
|
+
rest_brightness_1: rest?.brightnessAttr === '1',
|
|
74
|
+
rest_hovered_false: rest?.hoveredAttr === 'false',
|
|
75
|
+
transition_has_filter: /filter/.test(rest?.transitionProperty || ''),
|
|
76
|
+
source_filter: sourceFilter,
|
|
77
|
+
source_attr: sourceAttr,
|
|
78
|
+
source_transition: sourceTransition,
|
|
79
|
+
};
|
|
80
|
+
const ok = Object.values(results).every(Boolean);
|
|
81
|
+
console.log(`${ok ? '✅' : '❌'} R584 status-ring brightness (23rd anchor):`,
|
|
82
|
+
JSON.stringify(results, null, 2),
|
|
83
|
+
`\n rest: ${JSON.stringify(rest)}`);
|
|
84
|
+
process.exit(ok ? 0 : 1);
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/* Round 621 — extend isRingHovered gate to include chatAlias.
|
|
2
|
+
* Single conceptual change cascades both status-ring axes
|
|
3
|
+
* (R438 sw + R584 brightness) to also fire on chat-target.
|
|
4
|
+
* 7th anchor in chat-target-gated brightness family.
|
|
5
|
+
*
|
|
6
|
+
* Test phases:
|
|
7
|
+
* 1. mock 2 idle nodes → status ring renders
|
|
8
|
+
* 2. rest: ring at idle sw (3 online) + no brightness filter
|
|
9
|
+
* 3. source: isRingHovered declaration uses gate union
|
|
10
|
+
* (hoveredAlias || chatAlias)
|
|
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-status-ring]', { timeout: 15000, state: 'attached' });
|
|
44
|
+
await page.waitForTimeout(500);
|
|
45
|
+
|
|
46
|
+
const rest = await page.evaluate(() => {
|
|
47
|
+
const el = document.querySelector('[data-node-status-ring]');
|
|
48
|
+
if (!el) return null;
|
|
49
|
+
return {
|
|
50
|
+
hoveredAttr: el.getAttribute('data-node-status-ring-hovered'),
|
|
51
|
+
swAttr: el.getAttribute('data-node-status-ring-stroke-width'),
|
|
52
|
+
brightnessAttr: el.getAttribute('data-node-status-ring-brightness'),
|
|
53
|
+
};
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
await browser.close();
|
|
57
|
+
|
|
58
|
+
const src = readFileSync('/home/vansin/agent-network-dashboard/app/components/TopoGraph.tsx', 'utf8');
|
|
59
|
+
const sourceGate = /const isRingHovered = !reducedMotion && \(hoveredAlias === session\.alias \|\| chatAlias === session\.alias\)/.test(src);
|
|
60
|
+
|
|
61
|
+
const results = {
|
|
62
|
+
ring_present: !!rest,
|
|
63
|
+
rest_hovered_false: rest?.hoveredAttr === 'false',
|
|
64
|
+
rest_sw_idle: rest?.swAttr === '3', // idle status (online, no hover)
|
|
65
|
+
rest_brightness_1: rest?.brightnessAttr === '1',
|
|
66
|
+
source_gate_or: sourceGate,
|
|
67
|
+
};
|
|
68
|
+
const ok = Object.values(results).every(Boolean);
|
|
69
|
+
console.log(`${ok ? '✅' : '❌'} R621 status-ring chat-target gate (chat-gated family 7th anchor):`,
|
|
70
|
+
JSON.stringify(results, null, 2),
|
|
71
|
+
`\n rest: ${JSON.stringify(rest)}`);
|
|
72
|
+
process.exit(ok ? 0 : 1);
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/* Round 617 — sub-text brightness gate extends from hover-only to
|
|
2
|
+
* (hover || chat-target). 3rd anchor in chat-target-gated
|
|
3
|
+
* brightness family (sibling to R615 chat ring + R616 alias text).
|
|
4
|
+
*
|
|
5
|
+
* Test phases:
|
|
6
|
+
* 1. mock 2 idle nodes → sub-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-sub-text]', { timeout: 15000, state: 'attached' });
|
|
44
|
+
await page.waitForTimeout(500);
|
|
45
|
+
|
|
46
|
+
const rest = await page.evaluate(() => {
|
|
47
|
+
const el = document.querySelector('[data-node-sub-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-sub-text-brightness'),
|
|
54
|
+
hoveredAttr: el.getAttribute('data-node-sub-text-hovered'),
|
|
55
|
+
chatTargetAttr: el.getAttribute('data-node-sub-text-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*'brightness\(1\.15\)'\s*:\s*undefined/.test(src);
|
|
63
|
+
const sourceAttr = /data-node-sub-text-brightness=\{!reducedMotion && \(hoveredAlias === session\.alias \|\| chatAlias === session\.alias\) \? '1\.15' : '1'\}/.test(src);
|
|
64
|
+
const sourceChatAttr = /data-node-sub-text-chat-target=\{chatAlias === session\.alias \? 'true' : 'false'\}/.test(src);
|
|
65
|
+
|
|
66
|
+
const results = {
|
|
67
|
+
sub_text_present: !!rest,
|
|
68
|
+
rest_filter_none: rest?.filter === 'none',
|
|
69
|
+
rest_brightness_1: rest?.brightnessAttr === '1',
|
|
70
|
+
rest_hovered_false: rest?.hoveredAttr === 'false',
|
|
71
|
+
rest_chat_target_false: rest?.chatTargetAttr === 'false',
|
|
72
|
+
transition_has_filter: /filter/.test(rest?.transitionProperty || ''),
|
|
73
|
+
source_filter_or_gate: sourceFilter,
|
|
74
|
+
source_attr_or_gate: sourceAttr,
|
|
75
|
+
source_chat_attr: sourceChatAttr,
|
|
76
|
+
};
|
|
77
|
+
const ok = Object.values(results).every(Boolean);
|
|
78
|
+
console.log(`${ok ? '✅' : '❌'} R617 sub-text chat-target brightness (chat-gated family 3rd anchor):`,
|
|
79
|
+
JSON.stringify(results, null, 2),
|
|
80
|
+
`\n rest: ${JSON.stringify(rest)}`);
|
|
81
|
+
process.exit(ok ? 0 : 1);
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/* Round 556 verification: title-block H2 "Command mesh" gains
|
|
2
|
+
* a 2nd editorial-emphasis axis — group-hover:font-bold paired
|
|
3
|
+
* with R554's group-hover:tracking-tighter.
|
|
4
|
+
*
|
|
5
|
+
* Test phases:
|
|
6
|
+
* 1. rest: fontWeight = 600 (semibold), letter-spacing ≈ -0.45px
|
|
7
|
+
* 2. hover brand logo (sibling, propagates via group-hover):
|
|
8
|
+
* H2 fontWeight = 700 (bold), letter-spacing ≈ -0.9px
|
|
9
|
+
* 3. transition-property contains BOTH letter-spacing AND font-weight
|
|
10
|
+
* 4. source-side regex confirms group-hover:font-bold wired
|
|
11
|
+
*/
|
|
12
|
+
import { chromium } from 'playwright';
|
|
13
|
+
import { readFileSync } from 'node:fs';
|
|
14
|
+
|
|
15
|
+
const TOKEN = JSON.parse(readFileSync('/home/vansin/.anet/config.json', 'utf8')).token;
|
|
16
|
+
const fresh = new Date(Date.now() - 60 * 1000).toISOString();
|
|
17
|
+
|
|
18
|
+
const browser = await chromium.launch({ headless: true });
|
|
19
|
+
const ctx = await browser.newContext({ viewport: { width: 1500, height: 1200 } });
|
|
20
|
+
await ctx.addCookies([{ name: 'anet_dashboard_session', value: `v3:${TOKEN}`, domain: '127.0.0.1', path: '/' }]);
|
|
21
|
+
await ctx.addInitScript(() => {
|
|
22
|
+
try {
|
|
23
|
+
localStorage.setItem('anet-theme', 'cyber');
|
|
24
|
+
localStorage.setItem('anet-topo-layout', 'ring');
|
|
25
|
+
sessionStorage.setItem('anet_v3_auth', '1');
|
|
26
|
+
} catch {}
|
|
27
|
+
});
|
|
28
|
+
await ctx.route('**/api/hub/status*', async (route) => {
|
|
29
|
+
const r = await route.fetch();
|
|
30
|
+
const b = await r.json();
|
|
31
|
+
const nid = (b.sessions || [])[0]?.network_id || 'default';
|
|
32
|
+
const mk = (alias) => ({
|
|
33
|
+
alias, status: 'idle', model: 'claude-opus-4', runtime: 'claude-code-cli',
|
|
34
|
+
network_id: nid, project_dir: null,
|
|
35
|
+
created_at: fresh, updated_at: fresh, last_seen_at: fresh,
|
|
36
|
+
});
|
|
37
|
+
await route.fulfill({ response: r, json: { ...b, sessions: [mk('a·1')] } });
|
|
38
|
+
});
|
|
39
|
+
await ctx.route('**/api/hub/messages*', (r) => r.fulfill({ json: { messages: [] } }));
|
|
40
|
+
await ctx.route('**/api/hub/tasks*', (r) => r.fulfill({ json: { tasks: [] } }));
|
|
41
|
+
const page = await ctx.newPage();
|
|
42
|
+
await page.goto('http://127.0.0.1:3000/', { waitUntil: 'networkidle' });
|
|
43
|
+
await page.waitForSelector('[data-topo-section-title]', { timeout: 15000 });
|
|
44
|
+
await page.waitForTimeout(500);
|
|
45
|
+
|
|
46
|
+
const h2Sel = '[data-topo-section-title]';
|
|
47
|
+
const logoSel = '[data-topo-brand-logo]';
|
|
48
|
+
|
|
49
|
+
const parsePx = (s) => parseFloat((s || '').replace(/px$/, ''));
|
|
50
|
+
|
|
51
|
+
// Phase 1: rest
|
|
52
|
+
const rest = await page.evaluate((s) => {
|
|
53
|
+
const el = document.querySelector(s);
|
|
54
|
+
if (!el) return null;
|
|
55
|
+
const cs = getComputedStyle(el);
|
|
56
|
+
return {
|
|
57
|
+
fontWeight: cs.fontWeight,
|
|
58
|
+
letterSpacing: cs.letterSpacing,
|
|
59
|
+
transitionProperty: cs.transitionProperty,
|
|
60
|
+
transitionDuration: cs.transitionDuration,
|
|
61
|
+
hoverFwAttr: el.getAttribute('data-topo-section-title-hover-fw'),
|
|
62
|
+
hoverTrackingAttr: el.getAttribute('data-topo-section-title-hover-tracking'),
|
|
63
|
+
};
|
|
64
|
+
}, h2Sel);
|
|
65
|
+
|
|
66
|
+
// Phase 2: hover brand logo (sibling) → group-hover propagates
|
|
67
|
+
await page.hover(logoSel);
|
|
68
|
+
await page.waitForTimeout(400);
|
|
69
|
+
const hover = await page.evaluate((s) => {
|
|
70
|
+
const el = document.querySelector(s);
|
|
71
|
+
if (!el) return null;
|
|
72
|
+
const cs = getComputedStyle(el);
|
|
73
|
+
return { fontWeight: cs.fontWeight, letterSpacing: cs.letterSpacing };
|
|
74
|
+
}, h2Sel);
|
|
75
|
+
|
|
76
|
+
await browser.close();
|
|
77
|
+
|
|
78
|
+
const src = readFileSync('/home/vansin/agent-network-dashboard/app/components/TopoGraph.tsx', 'utf8');
|
|
79
|
+
const sourceFwWired = /group-hover:font-bold/.test(src);
|
|
80
|
+
const sourceTransition = /transition-\[letter-spacing,font-weight\] duration-200 ease-out/.test(src);
|
|
81
|
+
const sourceFwAttr = /data-topo-section-title-hover-fw="700"/.test(src);
|
|
82
|
+
|
|
83
|
+
const restPx = parsePx(rest?.letterSpacing);
|
|
84
|
+
const hoverPx = parsePx(hover?.letterSpacing);
|
|
85
|
+
|
|
86
|
+
const results = {
|
|
87
|
+
rest_fw_semibold: rest?.fontWeight === '600',
|
|
88
|
+
rest_tracking_tight: Math.abs(restPx - (-0.45)) < 0.05,
|
|
89
|
+
hover_fw_bold: hover?.fontWeight === '700',
|
|
90
|
+
hover_tracking_tighter: Math.abs(hoverPx - (-0.9)) < 0.05,
|
|
91
|
+
// Both axes intensify together — confirm by directionality
|
|
92
|
+
fw_intensifies: parseInt(hover?.fontWeight || '0') > parseInt(rest?.fontWeight || '0'),
|
|
93
|
+
tracking_intensifies: hoverPx < restPx - 0.3, // more negative = tighter
|
|
94
|
+
transition_has_ls: /letter-spacing/.test(rest?.transitionProperty || ''),
|
|
95
|
+
transition_has_fw: /font-weight/.test(rest?.transitionProperty || ''),
|
|
96
|
+
transition_duration: rest?.transitionDuration === '0.2s',
|
|
97
|
+
rest_hover_fw_attr: rest?.hoverFwAttr === '700',
|
|
98
|
+
rest_hover_tracking_attr: rest?.hoverTrackingAttr === 'tracking-tighter',
|
|
99
|
+
source_fw_wired: sourceFwWired,
|
|
100
|
+
source_transition: sourceTransition,
|
|
101
|
+
source_fw_attr: sourceFwAttr,
|
|
102
|
+
};
|
|
103
|
+
const ok = Object.values(results).every(Boolean);
|
|
104
|
+
console.log(`${ok ? '✅' : '❌'} R556 title-block H2 group-hover:font-bold (2-axis editorial emphasis):`,
|
|
105
|
+
JSON.stringify(results, null, 2),
|
|
106
|
+
`\n rest: fw=${rest?.fontWeight}, ls=${rest?.letterSpacing}`,
|
|
107
|
+
`\n hover: fw=${hover?.fontWeight}, ls=${hover?.letterSpacing}`,
|
|
108
|
+
`\n transition: ${rest?.transitionProperty}`);
|
|
109
|
+
process.exit(ok ? 0 : 1);
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/* Round 554 verification: title-block H2 "Command mesh" gains
|
|
2
|
+
* group-hover:tracking-tighter via the wrapper's `group` flag.
|
|
3
|
+
* Hovering the brand logo OR the title text should tighten the
|
|
4
|
+
* H2's kerning from -0.025em → -0.05em.
|
|
5
|
+
*
|
|
6
|
+
* Tailwind tracking utilities map to letter-spacing CSS:
|
|
7
|
+
* tracking-tight -0.025em
|
|
8
|
+
* tracking-tighter -0.05em
|
|
9
|
+
*
|
|
10
|
+
* At text-lg (18px font-size):
|
|
11
|
+
* tracking-tight = -0.45px
|
|
12
|
+
* tracking-tighter = -0.9px
|
|
13
|
+
*
|
|
14
|
+
* Test phases:
|
|
15
|
+
* 1. rest: H2 letter-spacing ≈ -0.45px (tracking-tight)
|
|
16
|
+
* 2. hover brand logo: H2 letter-spacing ≈ -0.9px (tracking-tighter)
|
|
17
|
+
* Verifies group-hover propagation from sibling element.
|
|
18
|
+
* 3. hover H2 itself: letter-spacing ≈ -0.9px (same)
|
|
19
|
+
* 4. source: wrapper has `group`, H2 has group-hover:tracking-tighter
|
|
20
|
+
*/
|
|
21
|
+
import { chromium } from 'playwright';
|
|
22
|
+
import { readFileSync } from 'node:fs';
|
|
23
|
+
|
|
24
|
+
const TOKEN = JSON.parse(readFileSync('/home/vansin/.anet/config.json', 'utf8')).token;
|
|
25
|
+
const fresh = new Date(Date.now() - 60 * 1000).toISOString();
|
|
26
|
+
|
|
27
|
+
const browser = await chromium.launch({ headless: true });
|
|
28
|
+
const ctx = await browser.newContext({ viewport: { width: 1500, height: 1200 } });
|
|
29
|
+
await ctx.addCookies([{ name: 'anet_dashboard_session', value: `v3:${TOKEN}`, domain: '127.0.0.1', path: '/' }]);
|
|
30
|
+
await ctx.addInitScript(() => {
|
|
31
|
+
try {
|
|
32
|
+
localStorage.setItem('anet-theme', 'cyber');
|
|
33
|
+
localStorage.setItem('anet-topo-layout', 'ring');
|
|
34
|
+
sessionStorage.setItem('anet_v3_auth', '1');
|
|
35
|
+
} catch {}
|
|
36
|
+
});
|
|
37
|
+
await ctx.route('**/api/hub/status*', async (route) => {
|
|
38
|
+
const r = await route.fetch();
|
|
39
|
+
const b = await r.json();
|
|
40
|
+
const nid = (b.sessions || [])[0]?.network_id || 'default';
|
|
41
|
+
const mk = (alias) => ({
|
|
42
|
+
alias, status: 'idle', model: 'claude-opus-4', runtime: 'claude-code-cli',
|
|
43
|
+
network_id: nid, project_dir: null,
|
|
44
|
+
created_at: fresh, updated_at: fresh, last_seen_at: fresh,
|
|
45
|
+
});
|
|
46
|
+
await route.fulfill({ response: r, json: { ...b, sessions: [mk('a·1')] } });
|
|
47
|
+
});
|
|
48
|
+
await ctx.route('**/api/hub/messages*', (r) => r.fulfill({ json: { messages: [] } }));
|
|
49
|
+
await ctx.route('**/api/hub/tasks*', (r) => r.fulfill({ json: { tasks: [] } }));
|
|
50
|
+
const page = await ctx.newPage();
|
|
51
|
+
await page.goto('http://127.0.0.1:3000/', { waitUntil: 'networkidle' });
|
|
52
|
+
await page.waitForSelector('[data-topo-section-title]', { timeout: 15000 });
|
|
53
|
+
await page.waitForTimeout(500);
|
|
54
|
+
|
|
55
|
+
const h2Sel = '[data-topo-section-title]';
|
|
56
|
+
const logoSel = '[data-topo-brand-logo]';
|
|
57
|
+
|
|
58
|
+
const parsePx = (s) => parseFloat((s || '').replace(/px$/, ''));
|
|
59
|
+
|
|
60
|
+
// Phase 1: rest
|
|
61
|
+
const rest = await page.evaluate((s) => {
|
|
62
|
+
const el = document.querySelector(s);
|
|
63
|
+
if (!el) return null;
|
|
64
|
+
const cs = getComputedStyle(el);
|
|
65
|
+
return {
|
|
66
|
+
letterSpacing: cs.letterSpacing,
|
|
67
|
+
transitionProperty: cs.transitionProperty,
|
|
68
|
+
transitionDuration: cs.transitionDuration,
|
|
69
|
+
fontSize: cs.fontSize,
|
|
70
|
+
hoverAttr: el.getAttribute('data-topo-section-title-hover-tracking'),
|
|
71
|
+
};
|
|
72
|
+
}, h2Sel);
|
|
73
|
+
|
|
74
|
+
// Phase 2: hover brand logo (different element, but same group → H2 should tighten)
|
|
75
|
+
await page.hover(logoSel);
|
|
76
|
+
await page.waitForTimeout(400);
|
|
77
|
+
const hoverLogo = await page.evaluate((s) => {
|
|
78
|
+
const el = document.querySelector(s);
|
|
79
|
+
if (!el) return null;
|
|
80
|
+
const cs = getComputedStyle(el);
|
|
81
|
+
return { letterSpacing: cs.letterSpacing };
|
|
82
|
+
}, h2Sel);
|
|
83
|
+
|
|
84
|
+
// Phase 3: hover H2 itself (cross-confirm)
|
|
85
|
+
await page.mouse.move(0, 0);
|
|
86
|
+
await page.waitForTimeout(300);
|
|
87
|
+
await page.hover(h2Sel);
|
|
88
|
+
await page.waitForTimeout(400);
|
|
89
|
+
const hoverH2 = await page.evaluate((s) => {
|
|
90
|
+
const el = document.querySelector(s);
|
|
91
|
+
if (!el) return null;
|
|
92
|
+
const cs = getComputedStyle(el);
|
|
93
|
+
return { letterSpacing: cs.letterSpacing };
|
|
94
|
+
}, h2Sel);
|
|
95
|
+
|
|
96
|
+
await browser.close();
|
|
97
|
+
|
|
98
|
+
const src = readFileSync('/home/vansin/agent-network-dashboard/app/components/TopoGraph.tsx', 'utf8');
|
|
99
|
+
const sourceGroupWrapper = /<div className="group flex items-center gap-2\.5" data-topo-section-titleblock-group>/.test(src);
|
|
100
|
+
const sourceH2HoverTracking = /group-hover:tracking-tighter/.test(src);
|
|
101
|
+
const sourceH2HoverAttr = /data-topo-section-title-hover-tracking="tracking-tighter"/.test(src);
|
|
102
|
+
|
|
103
|
+
// Rest ≈ -0.45px (-0.025em × 18px), hover ≈ -0.9px (-0.05em × 18px)
|
|
104
|
+
const restPx = parsePx(rest?.letterSpacing);
|
|
105
|
+
const hoverLogoPx = parsePx(hoverLogo?.letterSpacing);
|
|
106
|
+
const hoverH2Px = parsePx(hoverH2?.letterSpacing);
|
|
107
|
+
|
|
108
|
+
const results = {
|
|
109
|
+
rest_attr_present: rest?.hoverAttr === 'tracking-tighter',
|
|
110
|
+
rest_tracking_tight: Math.abs(restPx - (-0.45)) < 0.05,
|
|
111
|
+
hover_via_logo_tightens: Math.abs(hoverLogoPx - (-0.9)) < 0.05,
|
|
112
|
+
hover_via_h2_tightens: Math.abs(hoverH2Px - (-0.9)) < 0.05,
|
|
113
|
+
hover_tighter_than_rest: hoverLogoPx < restPx - 0.3,
|
|
114
|
+
transition_has_letter_spacing: /letter-spacing/.test(rest?.transitionProperty || ''),
|
|
115
|
+
transition_duration_200ms: rest?.transitionDuration === '0.2s',
|
|
116
|
+
source_group_wrapper: sourceGroupWrapper,
|
|
117
|
+
source_h2_group_hover: sourceH2HoverTracking,
|
|
118
|
+
source_h2_attr: sourceH2HoverAttr,
|
|
119
|
+
};
|
|
120
|
+
const ok = Object.values(results).every(Boolean);
|
|
121
|
+
console.log(`${ok ? '✅' : '❌'} R554 title-block H2 group-hover:tracking-tighter:`,
|
|
122
|
+
JSON.stringify(results, null, 2),
|
|
123
|
+
`\n rest letter-spacing: ${rest?.letterSpacing} (expect ≈ -0.45px)`,
|
|
124
|
+
`\n hover-via-logo: ${hoverLogo?.letterSpacing} (expect ≈ -0.9px)`,
|
|
125
|
+
`\n hover-via-h2: ${hoverH2?.letterSpacing} (expect ≈ -0.9px)`,
|
|
126
|
+
`\n font-size: ${rest?.fontSize}`,
|
|
127
|
+
`\n transition-property: ${rest?.transitionProperty}`);
|
|
128
|
+
process.exit(ok ? 0 : 1);
|