@sleep2agi/agent-network-dashboard 0.5.3-preview.0 → 0.5.3-preview.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.next/BUILD_ID +1 -1
- package/.next/build-manifest.json +3 -3
- package/.next/diagnostics/route-bundle-stats.json +7 -7
- package/.next/fallback-build-manifest.json +3 -3
- package/.next/server/app/_global-error.html +1 -1
- package/.next/server/app/_global-error.rsc +1 -1
- package/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/.next/server/app/_not-found.html +2 -2
- package/.next/server/app/_not-found.rsc +2 -2
- package/.next/server/app/_not-found.segments/_full.segment.rsc +2 -2
- package/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/.next/server/app/_not-found.segments/_index.segment.rsc +2 -2
- package/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/admin/page_client-reference-manifest.js +1 -1
- package/.next/server/app/admin.html +2 -2
- package/.next/server/app/admin.rsc +2 -2
- package/.next/server/app/admin.segments/_full.segment.rsc +2 -2
- package/.next/server/app/admin.segments/_head.segment.rsc +1 -1
- package/.next/server/app/admin.segments/_index.segment.rsc +2 -2
- package/.next/server/app/admin.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/admin.segments/admin/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/admin.segments/admin.segment.rsc +1 -1
- package/.next/server/app/index.html +2 -2
- package/.next/server/app/index.rsc +3 -3
- package/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
- package/.next/server/app/index.segments/_full.segment.rsc +3 -3
- package/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/.next/server/app/index.segments/_index.segment.rsc +2 -2
- package/.next/server/app/index.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/login/page_client-reference-manifest.js +1 -1
- package/.next/server/app/login.html +2 -2
- package/.next/server/app/login.rsc +3 -3
- package/.next/server/app/login.segments/_full.segment.rsc +3 -3
- package/.next/server/app/login.segments/_head.segment.rsc +1 -1
- package/.next/server/app/login.segments/_index.segment.rsc +2 -2
- package/.next/server/app/login.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/login.segments/login/__PAGE__.segment.rsc +2 -2
- package/.next/server/app/login.segments/login.segment.rsc +1 -1
- package/.next/server/app/logs/page_client-reference-manifest.js +1 -1
- package/.next/server/app/logs.html +2 -2
- package/.next/server/app/logs.rsc +2 -2
- package/.next/server/app/logs.segments/_full.segment.rsc +2 -2
- package/.next/server/app/logs.segments/_head.segment.rsc +1 -1
- package/.next/server/app/logs.segments/_index.segment.rsc +2 -2
- package/.next/server/app/logs.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/logs.segments/logs/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/logs.segments/logs.segment.rsc +1 -1
- package/.next/server/app/messages/page_client-reference-manifest.js +1 -1
- package/.next/server/app/messages.html +2 -2
- package/.next/server/app/messages.rsc +2 -2
- package/.next/server/app/messages.segments/_full.segment.rsc +2 -2
- package/.next/server/app/messages.segments/_head.segment.rsc +1 -1
- package/.next/server/app/messages.segments/_index.segment.rsc +2 -2
- package/.next/server/app/messages.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/messages.segments/messages/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/messages.segments/messages.segment.rsc +1 -1
- package/.next/server/app/node/page_client-reference-manifest.js +1 -1
- package/.next/server/app/node.html +2 -2
- package/.next/server/app/node.rsc +2 -2
- package/.next/server/app/node.segments/_full.segment.rsc +2 -2
- package/.next/server/app/node.segments/_head.segment.rsc +1 -1
- package/.next/server/app/node.segments/_index.segment.rsc +2 -2
- package/.next/server/app/node.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/node.segments/node/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/node.segments/node.segment.rsc +1 -1
- package/.next/server/app/nodes/page_client-reference-manifest.js +1 -1
- package/.next/server/app/nodes.html +2 -2
- package/.next/server/app/nodes.rsc +2 -2
- package/.next/server/app/nodes.segments/_full.segment.rsc +2 -2
- package/.next/server/app/nodes.segments/_head.segment.rsc +1 -1
- package/.next/server/app/nodes.segments/_index.segment.rsc +2 -2
- package/.next/server/app/nodes.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/nodes.segments/nodes/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/nodes.segments/nodes.segment.rsc +1 -1
- package/.next/server/app/page_client-reference-manifest.js +1 -1
- package/.next/server/app/server-logs/page_client-reference-manifest.js +1 -1
- package/.next/server/app/server-logs.html +2 -2
- package/.next/server/app/server-logs.rsc +2 -2
- package/.next/server/app/server-logs.segments/_full.segment.rsc +2 -2
- package/.next/server/app/server-logs.segments/_head.segment.rsc +1 -1
- package/.next/server/app/server-logs.segments/_index.segment.rsc +2 -2
- package/.next/server/app/server-logs.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/server-logs.segments/server-logs/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/server-logs.segments/server-logs.segment.rsc +1 -1
- package/.next/server/app/settings/networks/page_client-reference-manifest.js +1 -1
- package/.next/server/app/settings/networks.html +2 -2
- package/.next/server/app/settings/networks.rsc +2 -2
- package/.next/server/app/settings/networks.segments/_full.segment.rsc +2 -2
- package/.next/server/app/settings/networks.segments/_head.segment.rsc +1 -1
- package/.next/server/app/settings/networks.segments/_index.segment.rsc +2 -2
- package/.next/server/app/settings/networks.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/settings/networks.segments/settings/networks/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/settings/networks.segments/settings/networks.segment.rsc +1 -1
- package/.next/server/app/settings/networks.segments/settings.segment.rsc +1 -1
- package/.next/server/app/settings/page_client-reference-manifest.js +1 -1
- package/.next/server/app/settings/tokens/page_client-reference-manifest.js +1 -1
- package/.next/server/app/settings/tokens.html +2 -2
- package/.next/server/app/settings/tokens.rsc +2 -2
- package/.next/server/app/settings/tokens.segments/_full.segment.rsc +2 -2
- package/.next/server/app/settings/tokens.segments/_head.segment.rsc +1 -1
- package/.next/server/app/settings/tokens.segments/_index.segment.rsc +2 -2
- package/.next/server/app/settings/tokens.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/settings/tokens.segments/settings/tokens/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/settings/tokens.segments/settings/tokens.segment.rsc +1 -1
- package/.next/server/app/settings/tokens.segments/settings.segment.rsc +1 -1
- package/.next/server/app/settings.html +2 -2
- package/.next/server/app/settings.rsc +3 -3
- package/.next/server/app/settings.segments/_full.segment.rsc +3 -3
- package/.next/server/app/settings.segments/_head.segment.rsc +1 -1
- package/.next/server/app/settings.segments/_index.segment.rsc +2 -2
- package/.next/server/app/settings.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/settings.segments/settings/__PAGE__.segment.rsc +2 -2
- package/.next/server/app/settings.segments/settings.segment.rsc +1 -1
- package/.next/server/app/tasks/[id]/page_client-reference-manifest.js +1 -1
- package/.next/server/app/tasks/page_client-reference-manifest.js +1 -1
- package/.next/server/app/tasks.html +2 -2
- package/.next/server/app/tasks.rsc +2 -2
- package/.next/server/app/tasks.segments/_full.segment.rsc +2 -2
- package/.next/server/app/tasks.segments/_head.segment.rsc +1 -1
- package/.next/server/app/tasks.segments/_index.segment.rsc +2 -2
- package/.next/server/app/tasks.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/tasks.segments/tasks/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/tasks.segments/tasks.segment.rsc +1 -1
- package/.next/server/chunks/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 +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/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/0686f~8limi6v.js +4 -0
- package/.next/static/chunks/0bc4e~z~9z0ei.js +1 -0
- package/.next/static/chunks/0c9naoez330em.js +1 -0
- package/.next/static/chunks/{0udv401.-i0wx.js → 0hn_4t-p28o89.js} +1 -1
- package/.next/static/chunks/0hndl9yzpqajt.css +2 -0
- package/.next/trace +2 -2
- package/.next/trace-build +1 -1
- package/app/components/TopoGraph.tsx +162 -22
- package/app/globals.css +68 -6
- package/package.json +1 -1
- package/scripts/topo-chip-row-press-test.mjs +93 -0
- package/scripts/topo-chrome-press-fullstrip-test.mjs +105 -0
- package/scripts/topo-chrome-press-scale-test.mjs +100 -0
- package/scripts/topo-filter-pills-press-test.mjs +96 -0
- package/scripts/topo-focus-outline-transition-test.mjs +107 -0
- package/scripts/topo-hover-ring-duration-test.mjs +87 -0
- package/scripts/topo-hovered-alias-attr-test.mjs +111 -0
- package/scripts/topo-hub-idle-breath-test.mjs +104 -0
- package/scripts/topo-svg-focus-transition-test.mjs +105 -0
- package/scripts/topo-vendor-activelinks-press-test.mjs +100 -0
- package/.next/static/chunks/06umjir3xxdkg.js +0 -1
- package/.next/static/chunks/0a4hmfvj-81x5.css +0 -2
- package/.next/static/chunks/0lpjexuspbsws.js +0 -4
- package/.next/static/chunks/0xv4drghck_7d.js +0 -1
- /package/.next/static/{Q7AfghHYz-a578rrDCx1S → Bnn92TNkQrpT-G6WKh2JI}/_buildManifest.js +0 -0
- /package/.next/static/{Q7AfghHYz-a578rrDCx1S → Bnn92TNkQrpT-G6WKh2JI}/_clientMiddlewareManifest.js +0 -0
- /package/.next/static/{Q7AfghHYz-a578rrDCx1S → Bnn92TNkQrpT-G6WKh2JI}/_ssgManifest.js +0 -0
|
@@ -1943,8 +1943,24 @@ export function TopoGraph({ sessions, sseSessions, renameSignal }: TopoGraphProp
|
|
|
1943
1943
|
// doesn't list letter-spacing, so without this the
|
|
1944
1944
|
// hover:tracking-wide would snap. Sibling change on
|
|
1945
1945
|
// the Grid button below.
|
|
1946
|
-
|
|
1947
|
-
|
|
1946
|
+
// Round 492 / Loop — add `active:scale-95` press feedback
|
|
1947
|
+
// alongside R196's `active:bg-cyan-500/25` color-deepen.
|
|
1948
|
+
// Pre-R492 the chrome-strip Ring/Grid buttons had color
|
|
1949
|
+
// tactile (deeper cyan on mouse-down) + R249 chrome-pop
|
|
1950
|
+
// on release, but no transform during the press itself —
|
|
1951
|
+
// the button stayed planted between mouse-down and pop.
|
|
1952
|
+
// Adding `active:scale-95` (5% compression) on the
|
|
1953
|
+
// pressed pseudo-state, with `transform 150ms ease-out`
|
|
1954
|
+
// bundled into the inline transition list, gives haptic-
|
|
1955
|
+
// like push-back feedback. The press-down (down to 95%
|
|
1956
|
+
// scale) eases in over 150ms in sync with the bg/color
|
|
1957
|
+
// deepen; the release auto-springs back to scale-100 via
|
|
1958
|
+
// the same transition, then R249's anet-chrome-pop class
|
|
1959
|
+
// overlays the release-pop. Matching `transform-gpu`
|
|
1960
|
+
// promotes the layer so the scale doesn't trigger
|
|
1961
|
+
// layout/paint thrash. Sibling change on Grid below.
|
|
1962
|
+
className={`px-2.5 py-1 focus:outline-none focus-visible:ring-1 focus-visible:ring-cyan-400/60 focus-visible:ring-inset hover:tracking-wide active:scale-95 transform-gpu ${layout === 'ring' ? 'bg-cyan-500/15 text-cyan-300 font-medium hover:bg-cyan-500/20 active:bg-cyan-500/25' : 'text-gray-400 hover:text-cyan-300 hover:bg-cyan-500/5 active:bg-cyan-500/15'} ${chromePopping === 'layout-ring' ? ' anet-chrome-pop' : ''}`}
|
|
1963
|
+
style={{ transition: 'background-color 150ms ease, color 150ms ease, letter-spacing 200ms ease-out, transform 150ms ease-out' }}
|
|
1948
1964
|
>
|
|
1949
1965
|
Ring
|
|
1950
1966
|
</button>
|
|
@@ -1963,7 +1979,10 @@ export function TopoGraph({ sessions, sseSessions, renameSignal }: TopoGraphProp
|
|
|
1963
1979
|
// all chrome buttons.
|
|
1964
1980
|
// R351 sibling — Grid button picks up hover:tracking-wide
|
|
1965
1981
|
// + inline transition spec. Same vocabulary as Ring.
|
|
1966
|
-
|
|
1982
|
+
// R492 sibling — Grid button picks up active:scale-95
|
|
1983
|
+
// press feedback + transform in transition list. Same
|
|
1984
|
+
// vocabulary as Ring above.
|
|
1985
|
+
className={`px-2.5 py-1 border-l focus:outline-none focus-visible:ring-1 focus-visible:ring-cyan-400/60 focus-visible:ring-inset hover:tracking-wide active:scale-95 transform-gpu ${layout === 'grid' ? 'bg-cyan-500/15 text-cyan-300 font-medium hover:bg-cyan-500/20 active:bg-cyan-500/25' : 'text-gray-400 hover:text-cyan-300 hover:bg-cyan-500/5 active:bg-cyan-500/15'} ${chromePopping === 'layout-grid' ? ' anet-chrome-pop' : ''}`}
|
|
1967
1986
|
/* Round 268 / Loop: Grid button's left border (the
|
|
1968
1987
|
internal divider between Ring and Grid) picks up
|
|
1969
1988
|
pal.containerBorder, matching the wrapper change at
|
|
@@ -1973,8 +1992,10 @@ export function TopoGraph({ sessions, sseSessions, renameSignal }: TopoGraphProp
|
|
|
1973
1992
|
transition list into the inline spec below so the
|
|
1974
1993
|
letter-spacing tween rides alongside without snapping
|
|
1975
1994
|
the border-color flip — border-color 200ms ease-out
|
|
1976
|
-
keeps R268's theme-toggle smoothness intact.
|
|
1977
|
-
|
|
1995
|
+
keeps R268's theme-toggle smoothness intact.
|
|
1996
|
+
R492 adds `transform 150ms ease-out` so active:scale-95
|
|
1997
|
+
eases smoothly. */
|
|
1998
|
+
style={{ borderColor: pal.containerBorder, transition: 'background-color 150ms ease, color 150ms ease, border-color 200ms ease-out, letter-spacing 200ms ease-out, transform 150ms ease-out' }}
|
|
1978
1999
|
>
|
|
1979
2000
|
Grid
|
|
1980
2001
|
</button>
|
|
@@ -2091,9 +2112,17 @@ export function TopoGraph({ sessions, sseSessions, renameSignal }: TopoGraphProp
|
|
|
2091
2112
|
// to R355 filter pin pill inner-span hover-brighten.
|
|
2092
2113
|
// Hover-brighten family extends from filter pills to
|
|
2093
2114
|
// chip-row chips at the inner-span scope.
|
|
2115
|
+
// Round 494 / Loop — chip-row working chip joins the
|
|
2116
|
+
// active:scale-95 press-feedback family (R492 Ring/Grid +
|
|
2117
|
+
// R493 chrome-strip rest). Gated on the clickable branch
|
|
2118
|
+
// (workingCount > 0) — when the chip is a placeholder
|
|
2119
|
+
// at count=0, scale-95 stays off to match the existing
|
|
2120
|
+
// R398 hover-lift conditional. Composes with hover:-
|
|
2121
|
+
// translate-y-px for the same lift-and-compress
|
|
2122
|
+
// tactile signature R493 brought to reset/fullscreen.
|
|
2094
2123
|
className={`group tabular-nums font-medium px-2.5 py-1 rounded-md border anet-topo-chip-focus transition-colors transition-transform duration-200 ease-out transform-gpu ${
|
|
2095
2124
|
workingCount > 0
|
|
2096
|
-
? 'bg-green-500/10 text-green-300 border-green-500/20 hover:bg-green-500/15 hover:border-green-500/30 hover:-translate-y-px'
|
|
2125
|
+
? 'bg-green-500/10 text-green-300 border-green-500/20 hover:bg-green-500/15 hover:border-green-500/30 hover:-translate-y-px active:scale-95'
|
|
2097
2126
|
: 'bg-green-500/10 text-green-300 border-green-500/20'
|
|
2098
2127
|
}`}
|
|
2099
2128
|
data-chip-hover-lift={workingCount > 0 ? 'true' : 'false'}
|
|
@@ -2193,9 +2222,12 @@ export function TopoGraph({ sessions, sseSessions, renameSignal }: TopoGraphProp
|
|
|
2193
2222
|
same digit-jitter physics on count crossings). */
|
|
2194
2223
|
// R398: hover translate-y lift on clickable variant — see working chip above.
|
|
2195
2224
|
// R414: `group` parent + inner unit span group-hover-brighten — see working chip above.
|
|
2225
|
+
// R494 sibling — online chip joins the active:scale-95 press
|
|
2226
|
+
// family (gated on onlineNodes.length > 0 clickable branch,
|
|
2227
|
+
// same conditional pattern as the working chip above).
|
|
2196
2228
|
className={`group tabular-nums font-medium px-2.5 py-1 rounded-md border anet-topo-chip-focus transition-colors transition-transform duration-200 ease-out transform-gpu ${
|
|
2197
2229
|
onlineNodes.length > 0
|
|
2198
|
-
? 'bg-cyan-500/10 text-cyan-300 border-cyan-500/20 hover:bg-cyan-500/15 hover:border-cyan-500/30 hover:-translate-y-px'
|
|
2230
|
+
? 'bg-cyan-500/10 text-cyan-300 border-cyan-500/20 hover:bg-cyan-500/15 hover:border-cyan-500/30 hover:-translate-y-px active:scale-95'
|
|
2199
2231
|
: 'bg-cyan-500/10 text-cyan-300 border-cyan-500/20'
|
|
2200
2232
|
}`}
|
|
2201
2233
|
data-chip-hover-lift={onlineNodes.length > 0 ? 'true' : 'false'}
|
|
@@ -2470,7 +2502,13 @@ export function TopoGraph({ sessions, sseSessions, renameSignal }: TopoGraphProp
|
|
|
2470
2502
|
// R355: `group` lets the inner opacity-70 spans (prefix
|
|
2471
2503
|
// `filter:` + count `· N`) brighten to 100 % on pill hover.
|
|
2472
2504
|
// Sibling treatment on group + vendor pills below.
|
|
2473
|
-
|
|
2505
|
+
// R495 — filter pills (3 sibling `group` variants) join the
|
|
2506
|
+
// active:scale-95 press-feedback family. R490's !important
|
|
2507
|
+
// transition list on .anet-topo-chip-focus already covers
|
|
2508
|
+
// transform, so just appending active:scale-95 to the
|
|
2509
|
+
// className wires the press tactile in one token. Compound
|
|
2510
|
+
// with R400-era hover:-translate-y-px gives lift-and-compress.
|
|
2511
|
+
className="group inline-flex items-center gap-1.5 px-2.5 py-1 rounded-md font-mono font-medium text-xs border anet-fade-in anet-topo-chip-focus transition-transform duration-200 ease-out hover:-translate-y-px active:scale-95 transform-gpu" data-topo-filter-pill-hover-lift="true"
|
|
2474
2512
|
title={matchCount > 0 ? `${matchPreview}${matchSuffix} — click to clear` : 'Click to clear filter'}
|
|
2475
2513
|
onClick={() => setPinnedStatus(null)}
|
|
2476
2514
|
style={{
|
|
@@ -2534,7 +2572,13 @@ export function TopoGraph({ sessions, sseSessions, renameSignal }: TopoGraphProp
|
|
|
2534
2572
|
data-filter-match-count={matchCount}
|
|
2535
2573
|
data-filter-match-aliases={matchAliases.join(',')}
|
|
2536
2574
|
// R355 sibling — `group` parent + group-hover on inner spans.
|
|
2537
|
-
|
|
2575
|
+
// R495 — filter pills (3 sibling `group` variants) join the
|
|
2576
|
+
// active:scale-95 press-feedback family. R490's !important
|
|
2577
|
+
// transition list on .anet-topo-chip-focus already covers
|
|
2578
|
+
// transform, so just appending active:scale-95 to the
|
|
2579
|
+
// className wires the press tactile in one token. Compound
|
|
2580
|
+
// with R400-era hover:-translate-y-px gives lift-and-compress.
|
|
2581
|
+
className="group inline-flex items-center gap-1.5 px-2.5 py-1 rounded-md font-mono font-medium text-xs border anet-fade-in anet-topo-chip-focus transition-transform duration-200 ease-out hover:-translate-y-px active:scale-95 transform-gpu" data-topo-filter-pill-hover-lift="true"
|
|
2538
2582
|
title={matchCount > 0 ? `${matchPreview}${matchSuffix} — click to clear` : 'Click to clear filter'}
|
|
2539
2583
|
onClick={() => setPinnedGroup(null)}
|
|
2540
2584
|
style={{
|
|
@@ -2600,7 +2644,13 @@ export function TopoGraph({ sessions, sseSessions, renameSignal }: TopoGraphProp
|
|
|
2600
2644
|
data-filter-match-count={matchCount}
|
|
2601
2645
|
data-filter-match-aliases={matchAliases.join(',')}
|
|
2602
2646
|
// R355 sibling — `group` parent + group-hover on inner spans.
|
|
2603
|
-
|
|
2647
|
+
// R495 — filter pills (3 sibling `group` variants) join the
|
|
2648
|
+
// active:scale-95 press-feedback family. R490's !important
|
|
2649
|
+
// transition list on .anet-topo-chip-focus already covers
|
|
2650
|
+
// transform, so just appending active:scale-95 to the
|
|
2651
|
+
// className wires the press tactile in one token. Compound
|
|
2652
|
+
// with R400-era hover:-translate-y-px gives lift-and-compress.
|
|
2653
|
+
className="group inline-flex items-center gap-1.5 px-2.5 py-1 rounded-md font-mono font-medium text-xs border anet-fade-in anet-topo-chip-focus transition-transform duration-200 ease-out hover:-translate-y-px active:scale-95 transform-gpu" data-topo-filter-pill-hover-lift="true"
|
|
2604
2654
|
title={matchCount > 0 ? `${matchPreview}${matchSuffix} — click to clear` : 'Click to clear vendor filter'}
|
|
2605
2655
|
onClick={() => setPinnedVendor(null)}
|
|
2606
2656
|
style={{
|
|
@@ -2663,7 +2713,10 @@ export function TopoGraph({ sessions, sseSessions, renameSignal }: TopoGraphProp
|
|
|
2663
2713
|
data-filter-match-count={link.count}
|
|
2664
2714
|
data-filter-match-aliases={`${link.from},${link.to}`}
|
|
2665
2715
|
data-active-filter-edge-hot={isHot ? 'true' : 'false'}
|
|
2666
|
-
|
|
2716
|
+
// R495 sibling — 4th filter pill (no `group` prefix variant)
|
|
2717
|
+
// joins active:scale-95 press family alongside the 3 group
|
|
2718
|
+
// variants above. Same recipe.
|
|
2719
|
+
className="inline-flex items-center gap-1.5 px-2.5 py-1 rounded-md font-mono font-medium text-xs border anet-fade-in anet-topo-chip-focus transition-transform duration-200 ease-out hover:-translate-y-px active:scale-95 transform-gpu" data-topo-filter-pill-hover-lift="true"
|
|
2667
2720
|
title={`${link.from} → ${link.to} (${link.count} msg${link.count === 1 ? '' : 's'}${isHot ? ', hot lane · ≥ 10' : ''}) — click to clear`}
|
|
2668
2721
|
onClick={() => setPinnedEdgeKey(null)}
|
|
2669
2722
|
style={{
|
|
@@ -3013,7 +3066,12 @@ export function TopoGraph({ sessions, sseSessions, renameSignal }: TopoGraphProp
|
|
|
3013
3066
|
// — sibling to R355 filter-pill prefix/suffix + R414
|
|
3014
3067
|
// chip-row unit brighten. Closes the inner-span
|
|
3015
3068
|
// hover-brighten family at the vendor chip surface.
|
|
3016
|
-
|
|
3069
|
+
// R496 — vendor letter chip joins active:scale-95 press
|
|
3070
|
+
// family. Last vendor-row clickable joining the family
|
|
3071
|
+
// R495 cashed via R490's transition-cascade dividend.
|
|
3072
|
+
// Same compound w/ R401 hover-lift idiom — lift-and-
|
|
3073
|
+
// compress on press, springs back on release.
|
|
3074
|
+
className="group tabular-nums font-medium inline-flex items-baseline gap-0.5 px-1 rounded anet-topo-chip-focus transition-transform duration-200 ease-out transform-gpu hover:-translate-y-px active:scale-95"
|
|
3017
3075
|
data-vendor-letter={v.initial}
|
|
3018
3076
|
data-vendor-letter-count={v.count}
|
|
3019
3077
|
data-vendor-letter-hover-lift="true"
|
|
@@ -3251,9 +3309,13 @@ export function TopoGraph({ sessions, sseSessions, renameSignal }: TopoGraphProp
|
|
|
3251
3309
|
data-chip-hover-lift attr exposes the lift surface
|
|
3252
3310
|
state ('true' clickable, 'false' empty) for tests. */
|
|
3253
3311
|
// R414: `group` parent + inner unit span group-hover-brighten — see working chip above.
|
|
3312
|
+
// R496 — active-links chip joins active:scale-95 press
|
|
3313
|
+
// family. Sibling to working+online chips (R494). Gated
|
|
3314
|
+
// on `isInteractive` (flowLinks.length > 0) — same R399
|
|
3315
|
+
// conditional pattern used for hover-lift.
|
|
3254
3316
|
className={`group tabular-nums font-medium hidden sm:inline px-2.5 py-1 rounded-md border anet-topo-chip-focus transition-transform duration-200 ease-out transform-gpu ${
|
|
3255
3317
|
isInteractive
|
|
3256
|
-
? 'bg-gray-500/10 text-gray-400 border-gray-500/20 hover:bg-cyan-500/10 hover:text-cyan-200 hover:border-cyan-500/30 hover:-translate-y-px'
|
|
3318
|
+
? 'bg-gray-500/10 text-gray-400 border-gray-500/20 hover:bg-cyan-500/10 hover:text-cyan-200 hover:border-cyan-500/30 hover:-translate-y-px active:scale-95'
|
|
3257
3319
|
: 'bg-gray-500/10 text-gray-400 border-gray-500/20'
|
|
3258
3320
|
}`}
|
|
3259
3321
|
data-chip-hover-lift={isInteractive ? 'true' : 'false'}
|
|
@@ -3545,8 +3607,26 @@ export function TopoGraph({ sessions, sseSessions, renameSignal }: TopoGraphProp
|
|
|
3545
3607
|
R469 data-topo-flow-count
|
|
3546
3608
|
R471 data-topo-layout canvas mode
|
|
3547
3609
|
R471 data-topo-theme canvas mode
|
|
3548
|
-
R487 data-topo-zoom canvas zoom
|
|
3610
|
+
R487 data-topo-zoom canvas zoom */
|
|
3549
3611
|
data-topo-zoom={view.zoom.toFixed(2)}
|
|
3612
|
+
/* Round 488 / Loop — pairs the R466 hover-aggregate BOOLEAN
|
|
3613
|
+
with the corresponding hover IDENTITY attr. Pre-R488 a
|
|
3614
|
+
test harness could query "is anything hovered" but had to
|
|
3615
|
+
traverse per-node `data-node` elements with focus-state
|
|
3616
|
+
attrs to recover WHICH alias. R488 surfaces it directly
|
|
3617
|
+
at canvas root. Empty string when null (always-present
|
|
3618
|
+
attr, consistent with the 10-attr state-surface set —
|
|
3619
|
+
never `undefined`-collapsed so observers can rely on a
|
|
3620
|
+
single `getAttribute('data-topo-hovered-alias')` returning
|
|
3621
|
+
either '' or the alias string).
|
|
3622
|
+
Note: only the `hoveredAlias` axis (R466's first source)
|
|
3623
|
+
gets the identity twin in R488. The other 5 hover sources
|
|
3624
|
+
(hoveredHub / hoveredEdgeKey / hoveredGroupLabel / hovered
|
|
3625
|
+
Status / hoveredVendor) are non-alias-shaped (hub center
|
|
3626
|
+
is singleton; edge has `from→to` key; status/vendor are
|
|
3627
|
+
categorical) — separate dedicated attrs if/when needed.
|
|
3628
|
+
Root svg attribute set now 11 attrs total. */
|
|
3629
|
+
data-topo-hovered-alias={hoveredAlias ?? ''}
|
|
3550
3630
|
/* Round 466 / Loop — aggregate hover signal on the root SVG.
|
|
3551
3631
|
Exposes a single boolean `data-topo-any-hover` that
|
|
3552
3632
|
reflects whether ANY hover state in the topology is
|
|
@@ -6519,11 +6599,36 @@ export function TopoGraph({ sessions, sseSessions, renameSignal }: TopoGraphProp
|
|
|
6519
6599
|
data-topo-hub-highlight-visible={workingCount > 0 ? 'false' : 'true'}
|
|
6520
6600
|
data-topo-hub-highlight-radius="5.5"
|
|
6521
6601
|
data-topo-hub-highlight-opacity={workingCount > 0 ? 0 : 0.95}
|
|
6602
|
+
data-topo-hub-highlight-breath={!reducedMotion && workingCount === 0 ? 'true' : 'false'}
|
|
6522
6603
|
style={{
|
|
6523
6604
|
pointerEvents: 'none',
|
|
6524
6605
|
transition: 'opacity 300ms ease-out',
|
|
6525
6606
|
}}
|
|
6526
|
-
|
|
6607
|
+
>
|
|
6608
|
+
{/* Round 497 / Loop — idle-state breath (呼吸感 theme pivot
|
|
6609
|
+
from the R492-R496 press-family arc). Pre-R497 the hub
|
|
6610
|
+
idle highlight read as a static dim disc — present but
|
|
6611
|
+
motionless, visually mute. R497 adds a 4s opacity breath
|
|
6612
|
+
(0.85 ↔ 1.0 ↔ 0.85) so the hub reads "alive but quiet"
|
|
6613
|
+
instead of "frozen", giving the empty-fleet state a
|
|
6614
|
+
subtle living signature.
|
|
6615
|
+
Gates:
|
|
6616
|
+
- !reducedMotion (R29 a11y blanket) — reducedMotion
|
|
6617
|
+
users see static 0.95 disc, no animate
|
|
6618
|
+
- workingCount === 0 — when fleet is busy, the
|
|
6619
|
+
highlight is invisible (opacity=0) so the animate
|
|
6620
|
+
would waste paint cycles. Gating saves work.
|
|
6621
|
+
SMIL <animate> overrides the static opacity={0.95}
|
|
6622
|
+
during its run; falls back to 0.95 when reducedMotion
|
|
6623
|
+
flips on (the animate node simply doesn't render).
|
|
6624
|
+
4s cycle is long enough to feel like ambient breath
|
|
6625
|
+
rather than a pulse, matching the "quiet" semantic.
|
|
6626
|
+
data-topo-hub-highlight-breath attr exposes the
|
|
6627
|
+
resolved gate state for tests. */}
|
|
6628
|
+
{!reducedMotion && workingCount === 0 && (
|
|
6629
|
+
<animate attributeName="opacity" values="0.85;1;0.85" dur="4s" repeatCount="indefinite" />
|
|
6630
|
+
)}
|
|
6631
|
+
</circle>
|
|
6527
6632
|
{/* R115 / Loop: hover hint ring. Stroke-only circle at r=14
|
|
6528
6633
|
that fades in when the hub is hovered — the same idea
|
|
6529
6634
|
R44 used for node avatars (group-hover stroke). r=14
|
|
@@ -6866,7 +6971,17 @@ export function TopoGraph({ sessions, sseSessions, renameSignal }: TopoGraphProp
|
|
|
6866
6971
|
in when the cursor enters the node, signalling clickability
|
|
6867
6972
|
(real-user feedback for the chat-popover open). Pure CSS via
|
|
6868
6973
|
Tailwind group-hover, so it costs nothing per frame and
|
|
6869
|
-
respects prefers-reduced-motion via the global media query.
|
|
6974
|
+
respects prefers-reduced-motion via the global media query.
|
|
6975
|
+
Round 489 / Loop — duration harmonized from 150ms → 200ms
|
|
6976
|
+
to join the Hero D #147 motion-coherence stack (R459-R475
|
|
6977
|
+
cluster surfaces + cadence-sync family). R2 originally
|
|
6978
|
+
picked 150ms for a "snappier feel" before the 200ms ease-
|
|
6979
|
+
out vocabulary was banked as the canvas-wide motion
|
|
6980
|
+
default. Bringing this ring into the family means hover-
|
|
6981
|
+
in / hover-out / cluster cadence / pip-strip transitions
|
|
6982
|
+
all settle on the same timing — the canvas now reads as
|
|
6983
|
+
one motion vocabulary instead of two competing tempos.
|
|
6984
|
+
11th surface in the motion-coherence stack. */}
|
|
6870
6985
|
<circle
|
|
6871
6986
|
cx={pos.x}
|
|
6872
6987
|
cy={pos.y}
|
|
@@ -6878,7 +6993,7 @@ export function TopoGraph({ sessions, sseSessions, renameSignal }: TopoGraphProp
|
|
|
6878
6993
|
// exact widths and would mis-count this invisible hover
|
|
6879
6994
|
// ring as a node footprint.
|
|
6880
6995
|
strokeWidth="2"
|
|
6881
|
-
className="opacity-0 group-hover:opacity-70 transition-opacity duration-
|
|
6996
|
+
className="opacity-0 group-hover:opacity-70 transition-opacity duration-200"
|
|
6882
6997
|
style={{ pointerEvents: 'none' }}
|
|
6883
6998
|
/>
|
|
6884
6999
|
{/* Round 11 / Loop: chat-focus ring — when the ChatPopover is
|
|
@@ -10939,7 +11054,15 @@ export function TopoGraph({ sessions, sseSessions, renameSignal }: TopoGraphProp
|
|
|
10939
11054
|
/ fullscreen) preview their active state on hover.
|
|
10940
11055
|
Pure actions (zoom -/+, reset) stay white — they
|
|
10941
11056
|
aren't toggles, have no active state to preview. */
|
|
10942
|
-
|
|
11057
|
+
// Round 493 / Loop — extends R492 chrome-strip press-feedback
|
|
11058
|
+
// family to nodeSize S/M/L buttons. Adds active:scale-95
|
|
11059
|
+
// alongside the existing color-deepen (R196) + chrome-pop
|
|
11060
|
+
// (R249). transition-transform + duration-200 + ease-out
|
|
11061
|
+
// + transform-gpu added since this className previously had
|
|
11062
|
+
// transition-colors only — without the transform transition,
|
|
11063
|
+
// active:scale-95 would hard-cut. transform-gpu promotes the
|
|
11064
|
+
// layer so scale doesn't trigger paint thrash.
|
|
11065
|
+
className={`px-2 py-1 transition-colors transition-transform duration-200 ease-out transform-gpu active:scale-95 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-cyan-400/60 focus-visible:ring-inset ${idx > 0 ? 'border-l' : ''} ${nodeScale === v ? 'bg-cyan-500/15 text-cyan-300 font-medium hover:bg-cyan-500/20 active:bg-cyan-500/25' : 'hover:bg-cyan-500/5 active:bg-cyan-500/15'}${chromePopping === popKey ? ' anet-chrome-pop' : ''}`}
|
|
10943
11066
|
style={{ color: nodeScale === v ? undefined : pal.legendText, borderColor: pal.containerBorder }}
|
|
10944
11067
|
>
|
|
10945
11068
|
{lbl}
|
|
@@ -10981,7 +11104,11 @@ export function TopoGraph({ sessions, sseSessions, renameSignal }: TopoGraphProp
|
|
|
10981
11104
|
// → white/10) so mouse-down has a tactile dim before the
|
|
10982
11105
|
// R186 icon pop fires on release.
|
|
10983
11106
|
// R352: `group` lets the inner svg respond via group-hover.
|
|
10984
|
-
|
|
11107
|
+
// R493 — zoom +/− buttons join the chrome-strip active:scale-95
|
|
11108
|
+
// press-feedback family (R492 + nodeSize above). transition-
|
|
11109
|
+
// transform + duration-200 + ease-out + transform-gpu added
|
|
11110
|
+
// since the className had only transition-colors.
|
|
11111
|
+
className="group px-2 py-1 hover:bg-white/5 active:bg-white/10 transition-colors transition-transform duration-200 ease-out transform-gpu active:scale-95 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-cyan-400/60 focus-visible:ring-inset"
|
|
10985
11112
|
style={{ color: pal.legendText }}
|
|
10986
11113
|
aria-label="Zoom out"
|
|
10987
11114
|
title="Zoom out (−)"
|
|
@@ -11121,7 +11248,11 @@ export function TopoGraph({ sessions, sseSessions, renameSignal }: TopoGraphProp
|
|
|
11121
11248
|
data-topo-chrome-zoom-in-popping={chromePopping === 'zoom-in' ? 'true' : 'false'}
|
|
11122
11249
|
// R196: press-state (mirror of zoom-out above).
|
|
11123
11250
|
// R352: `group` lets the inner svg respond via group-hover.
|
|
11124
|
-
|
|
11251
|
+
// R493 — zoom +/− buttons join the chrome-strip active:scale-95
|
|
11252
|
+
// press-feedback family (R492 + nodeSize above). transition-
|
|
11253
|
+
// transform + duration-200 + ease-out + transform-gpu added
|
|
11254
|
+
// since the className had only transition-colors.
|
|
11255
|
+
className="group px-2 py-1 hover:bg-white/5 active:bg-white/10 transition-colors transition-transform duration-200 ease-out transform-gpu active:scale-95 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-cyan-400/60 focus-visible:ring-inset"
|
|
11125
11256
|
style={{ color: pal.legendText }}
|
|
11126
11257
|
aria-label="Zoom in"
|
|
11127
11258
|
title="Zoom in (+)"
|
|
@@ -11173,7 +11304,14 @@ export function TopoGraph({ sessions, sseSessions, renameSignal }: TopoGraphProp
|
|
|
11173
11304
|
Every standalone interactive HTML surface in TopoGraph
|
|
11174
11305
|
now lifts on hover. data-topo-chrome-reset-hover-lift
|
|
11175
11306
|
attr surfaces the lift for tests. */
|
|
11176
|
-
|
|
11307
|
+
// R493 — reset button joins the chrome-strip active:scale-95
|
|
11308
|
+
// press-feedback family. The button already has transition-
|
|
11309
|
+
// transform + transform-gpu (R350 reset spin + R400 hover lift),
|
|
11310
|
+
// so just appending active:scale-95 plugs straight in. Compound
|
|
11311
|
+
// active state during press = hover-lift (-1px) + scale-95
|
|
11312
|
+
// composes as translateY(-1px) scale(0.95) — lift-and-compress
|
|
11313
|
+
// for tactile click feel.
|
|
11314
|
+
className="p-1.5 rounded-md border hover:bg-white/5 active:bg-white/10 hover:-translate-y-px active:scale-95 transition-colors transition-transform duration-200 ease-out transform-gpu focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-cyan-400/60"
|
|
11177
11315
|
data-topo-chrome-reset-hover-lift="true"
|
|
11178
11316
|
style={{ background: pal.legendBox.fill, borderColor: pal.containerBorder, color: pal.legendText }}
|
|
11179
11317
|
aria-label="Reset view"
|
|
@@ -11266,7 +11404,9 @@ export function TopoGraph({ sessions, sseSessions, renameSignal }: TopoGraphProp
|
|
|
11266
11404
|
// fullscreen now all carry an icon-level hover gesture in
|
|
11267
11405
|
// addition to the bg hover).
|
|
11268
11406
|
// R400: hover translateY(-1px) lift — see reset button above for family doc.
|
|
11269
|
-
|
|
11407
|
+
// R493 — fullscreen joins active:scale-95 press family (same as
|
|
11408
|
+
// reset above: lift-and-compress compound transform on press).
|
|
11409
|
+
className={`group p-1.5 rounded-md border hover:-translate-y-px active:scale-95 transition-colors transition-transform duration-200 ease-out transform-gpu focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-cyan-400/60 ${
|
|
11270
11410
|
isFullscreen
|
|
11271
11411
|
? 'bg-cyan-500/15 text-cyan-300 font-medium hover:bg-cyan-500/20 active:bg-cyan-500/25'
|
|
11272
11412
|
: 'hover:bg-cyan-500/5 active:bg-cyan-500/15'
|
package/app/globals.css
CHANGED
|
@@ -900,10 +900,47 @@ body {
|
|
|
900
900
|
and doesn't fight box-shadow, so we use it here. `currentColor`
|
|
901
901
|
inherits the chip's own accent (green for working, cyan for online,
|
|
902
902
|
per-vendor for letters, etc.). Only fires on :focus-visible
|
|
903
|
-
(keyboard) — mouse focus stays unstyled.
|
|
904
|
-
|
|
905
|
-
|
|
903
|
+
(keyboard) — mouse focus stays unstyled.
|
|
904
|
+
Round 490 / Loop — focus outline transitions on color rather than
|
|
905
|
+
hard-cutting. Pre-R490 the keyboard focus ring snapped in/out
|
|
906
|
+
instantly (no `transition` declaration), while every other hover/
|
|
907
|
+
pin state on the same chip eased through the Hero D 200ms ease-out
|
|
908
|
+
vocabulary (R459-R475 cluster + R489 hover ring). Keyboard users
|
|
909
|
+
tabbing through chips saw discontinuous focus jumps — pointer
|
|
910
|
+
users saw smooth motion. R490 unifies the two by holding a
|
|
911
|
+
permanent transparent outline (no painted footprint, no layout
|
|
912
|
+
shift — `outline` is drawn outside the border-box and doesn't
|
|
913
|
+
trigger reflow) and transitioning ONLY outline-color when focus
|
|
914
|
+
arrives/leaves. The cyber-theme dark canvas keyboard nav now
|
|
915
|
+
reads as one motion vocabulary with pointer hover. */
|
|
916
|
+
.anet-topo-chip-focus {
|
|
917
|
+
outline: 2px solid transparent;
|
|
906
918
|
outline-offset: 1px;
|
|
919
|
+
/* R490 (revised) — Tailwind utility classes on the chips (transition-
|
|
920
|
+
colors / transition-transform / duration-200) set their own
|
|
921
|
+
`transition-property` list at the same selector specificity (0,1,0),
|
|
922
|
+
and since Tailwind's stylesheet loads after globals.css they win
|
|
923
|
+
the cascade — without `!important` my outline-color transition is
|
|
924
|
+
ignored. The unified list below replaces Tailwind's narrower list
|
|
925
|
+
with a superset (color, bg, border, opacity, box-shadow, transform
|
|
926
|
+
all preserved) plus `outline-color` for R490. All at 200ms ease-
|
|
927
|
+
out, matching the chip-row's existing Tailwind duration-200 ease-
|
|
928
|
+
out so visible animations on the chip are unchanged.
|
|
929
|
+
Trade-off: chips with inline `style.transition` (e.g. R210
|
|
930
|
+
pressure-bar segments at 220ms width / 150ms boxShadow / 150ms
|
|
931
|
+
filter, line 2338 in TopoGraph.tsx) keep their inline value
|
|
932
|
+
because inline style wins over class rules regardless of
|
|
933
|
+
!important. That's intentional — those custom timings were
|
|
934
|
+
deliberate and stay scoped to their element. */
|
|
935
|
+
transition-property:
|
|
936
|
+
outline-color, color, background-color, border-color,
|
|
937
|
+
text-decoration-color, fill, stroke, opacity, box-shadow, transform
|
|
938
|
+
!important;
|
|
939
|
+
transition-duration: 200ms !important;
|
|
940
|
+
transition-timing-function: ease-out !important;
|
|
941
|
+
}
|
|
942
|
+
.anet-topo-chip-focus:focus-visible {
|
|
943
|
+
outline-color: currentColor;
|
|
907
944
|
}
|
|
908
945
|
|
|
909
946
|
/* R156 — focus-visible outline for SVG-side TopoGraph interactives.
|
|
@@ -914,10 +951,35 @@ body {
|
|
|
914
951
|
R144/R151/R152). Browser default focus outline on SVG is hard
|
|
915
952
|
to spot against the canvas; explicit cyan-300 ring matches the
|
|
916
953
|
dashboard's legendAccent. 2-px outline-offset gives breathing
|
|
917
|
-
room around the painted bounding box.
|
|
918
|
-
|
|
919
|
-
|
|
954
|
+
room around the painted bounding box.
|
|
955
|
+
Round 491 / Loop — SVG-side counterpart to R490's chip-focus
|
|
956
|
+
outline-color transition. Pre-R491 keyboard focus on SVG g
|
|
957
|
+
elements (recent rows, legend rows, group labels, edge badges,
|
|
958
|
+
nodes, "+N more") snapped instantly; HTML chips (post-R490) now
|
|
959
|
+
ease through 200ms ease-out but SVG g still hard-cut. Same
|
|
960
|
+
baseline-transparent + transition-outline-color recipe brings
|
|
961
|
+
the SVG canvas into the unified keyboard motion vocabulary —
|
|
962
|
+
keyboard users tabbing between chip-row and SVG canvas see
|
|
963
|
+
ONE smooth fade timing instead of HTML-smooth-then-SVG-snap.
|
|
964
|
+
The cyan-300 (#67e8f9) target color matches R156's original
|
|
965
|
+
choice (legendAccent visual identity); only the transition
|
|
966
|
+
timing is new.
|
|
967
|
+
Note on cascade: SVG g elements rarely carry Tailwind
|
|
968
|
+
transition-* utility classes (Tailwind defaults are HTML-
|
|
969
|
+
centric), so the (0,1,0) specificity of .anet-topo-svg-focus
|
|
970
|
+
typically wins without !important. Adding !important defensively
|
|
971
|
+
anyway since the React component may add future inline styles
|
|
972
|
+
or Tailwind classes. Same trade-off as R490 (inline
|
|
973
|
+
style.transition still wins if added). */
|
|
974
|
+
.anet-topo-svg-focus {
|
|
975
|
+
outline: 2px solid transparent;
|
|
920
976
|
outline-offset: 2px;
|
|
977
|
+
transition-property: outline-color !important;
|
|
978
|
+
transition-duration: 200ms !important;
|
|
979
|
+
transition-timing-function: ease-out !important;
|
|
980
|
+
}
|
|
981
|
+
.anet-topo-svg-focus:focus-visible {
|
|
982
|
+
outline-color: #67e8f9;
|
|
921
983
|
}
|
|
922
984
|
|
|
923
985
|
/* Round 46 — animated dashed spokes flowing from hub outward. Each spoke
|
package/package.json
CHANGED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/* Round 494 verification: chip-row working + online chips gain
|
|
2
|
+
* `active:scale-95` press feedback, gated on the clickable branch
|
|
3
|
+
* (workingCount > 0 / onlineNodes.length > 0). Extends the chrome-
|
|
4
|
+
* strip press family (R492 Ring/Grid + R493 5 chrome buttons) into
|
|
5
|
+
* the chip-row scope.
|
|
6
|
+
*
|
|
7
|
+
* Verifies per chip:
|
|
8
|
+
* - DOM element resolvable (data-working-chip / data-online-chip)
|
|
9
|
+
* - className contains `active:scale-95` (since fixture has both chips
|
|
10
|
+
* with > 0 count → clickable branch active)
|
|
11
|
+
* - computed transition-property includes `transform`
|
|
12
|
+
* - source-file regex confirms class string wired
|
|
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, status) => ({
|
|
35
|
+
alias, status, 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
|
+
// Need both working and online > 0 so both chip variants enter clickable branch
|
|
40
|
+
await route.fulfill({ response: r, json: { ...b, sessions: [
|
|
41
|
+
mk('alpha·a1', 'working'),
|
|
42
|
+
mk('alpha·a2', 'idle'),
|
|
43
|
+
] } });
|
|
44
|
+
});
|
|
45
|
+
await ctx.route('**/api/hub/messages*', (r) => r.fulfill({ json: { messages: [] } }));
|
|
46
|
+
await ctx.route('**/api/hub/tasks*', (r) => r.fulfill({ json: { tasks: [] } }));
|
|
47
|
+
const page = await ctx.newPage();
|
|
48
|
+
await page.goto('http://127.0.0.1:3000/', { waitUntil: 'networkidle' });
|
|
49
|
+
await page.waitForSelector('[data-working-chip]', { timeout: 15000 });
|
|
50
|
+
await page.waitForTimeout(1000);
|
|
51
|
+
|
|
52
|
+
const probe = async (sel) => {
|
|
53
|
+
return await page.evaluate((s) => {
|
|
54
|
+
const el = document.querySelector(s);
|
|
55
|
+
if (!el) return null;
|
|
56
|
+
const cs = window.getComputedStyle(el);
|
|
57
|
+
return {
|
|
58
|
+
cls: el.className || '',
|
|
59
|
+
cls_has_scale95: /active:scale-95/.test(el.className || ''),
|
|
60
|
+
cls_has_translate: /hover:-translate-y-px/.test(el.className || ''),
|
|
61
|
+
tp: cs.transitionProperty,
|
|
62
|
+
td: cs.transitionDuration,
|
|
63
|
+
tp_has_transform: /transform/i.test(cs.transitionProperty || ''),
|
|
64
|
+
};
|
|
65
|
+
}, sel);
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
const wInfo = await probe('[data-working-chip]');
|
|
69
|
+
const oInfo = await probe('[data-online-chip]');
|
|
70
|
+
|
|
71
|
+
await browser.close();
|
|
72
|
+
|
|
73
|
+
const src = readFileSync('/home/vansin/agent-network-dashboard/app/components/TopoGraph.tsx', 'utf8');
|
|
74
|
+
const sWorking = /workingCount > 0\s*\?\s*'bg-green-500\/10 text-green-300 border-green-500\/20 hover:bg-green-500\/15 hover:border-green-500\/30 hover:-translate-y-px active:scale-95'/.test(src);
|
|
75
|
+
const sOnline = /onlineNodes\.length > 0\s*\?\s*'bg-cyan-500\/10 text-cyan-300 border-cyan-500\/20 hover:bg-cyan-500\/15 hover:border-cyan-500\/30 hover:-translate-y-px active:scale-95'/.test(src);
|
|
76
|
+
|
|
77
|
+
const results = {
|
|
78
|
+
working_dom_found: !!wInfo,
|
|
79
|
+
working_has_scale95: wInfo && wInfo.cls_has_scale95,
|
|
80
|
+
working_has_lift: wInfo && wInfo.cls_has_translate,
|
|
81
|
+
working_tp_transform: wInfo && wInfo.tp_has_transform,
|
|
82
|
+
online_dom_found: !!oInfo,
|
|
83
|
+
online_has_scale95: oInfo && oInfo.cls_has_scale95,
|
|
84
|
+
online_has_lift: oInfo && oInfo.cls_has_translate,
|
|
85
|
+
online_tp_transform: oInfo && oInfo.tp_has_transform,
|
|
86
|
+
source_working_wired: sWorking,
|
|
87
|
+
source_online_wired: sOnline,
|
|
88
|
+
};
|
|
89
|
+
const ok = Object.values(results).every(Boolean);
|
|
90
|
+
console.log(`${ok ? '✅' : '❌'} chip-row working+online active:scale-95 (R494):`, JSON.stringify(results),
|
|
91
|
+
'\n working tp:', wInfo && wInfo.tp,
|
|
92
|
+
'\n online tp:', oInfo && oInfo.tp);
|
|
93
|
+
process.exit(ok ? 0 : 1);
|