@sleep2agi/agent-network-dashboard 0.5.3-preview.22 → 0.5.3-preview.220

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.
Files changed (358) hide show
  1. package/.next/BUILD_ID +1 -1
  2. package/.next/build-manifest.json +3 -3
  3. package/.next/diagnostics/route-bundle-stats.json +7 -7
  4. package/.next/fallback-build-manifest.json +3 -3
  5. package/.next/server/app/_global-error.html +1 -1
  6. package/.next/server/app/_global-error.rsc +1 -1
  7. package/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  8. package/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  9. package/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  10. package/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  11. package/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  12. package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  13. package/.next/server/app/_not-found.html +2 -2
  14. package/.next/server/app/_not-found.rsc +2 -2
  15. package/.next/server/app/_not-found.segments/_full.segment.rsc +2 -2
  16. package/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  17. package/.next/server/app/_not-found.segments/_index.segment.rsc +2 -2
  18. package/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  19. package/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  20. package/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  21. package/.next/server/app/admin/page_client-reference-manifest.js +1 -1
  22. package/.next/server/app/admin.html +2 -2
  23. package/.next/server/app/admin.rsc +2 -2
  24. package/.next/server/app/admin.segments/_full.segment.rsc +2 -2
  25. package/.next/server/app/admin.segments/_head.segment.rsc +1 -1
  26. package/.next/server/app/admin.segments/_index.segment.rsc +2 -2
  27. package/.next/server/app/admin.segments/_tree.segment.rsc +2 -2
  28. package/.next/server/app/admin.segments/admin/__PAGE__.segment.rsc +1 -1
  29. package/.next/server/app/admin.segments/admin.segment.rsc +1 -1
  30. package/.next/server/app/index.html +2 -2
  31. package/.next/server/app/index.rsc +3 -3
  32. package/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  33. package/.next/server/app/index.segments/_full.segment.rsc +3 -3
  34. package/.next/server/app/index.segments/_head.segment.rsc +1 -1
  35. package/.next/server/app/index.segments/_index.segment.rsc +2 -2
  36. package/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  37. package/.next/server/app/login/page_client-reference-manifest.js +1 -1
  38. package/.next/server/app/login.html +2 -2
  39. package/.next/server/app/login.rsc +3 -3
  40. package/.next/server/app/login.segments/_full.segment.rsc +3 -3
  41. package/.next/server/app/login.segments/_head.segment.rsc +1 -1
  42. package/.next/server/app/login.segments/_index.segment.rsc +2 -2
  43. package/.next/server/app/login.segments/_tree.segment.rsc +2 -2
  44. package/.next/server/app/login.segments/login/__PAGE__.segment.rsc +2 -2
  45. package/.next/server/app/login.segments/login.segment.rsc +1 -1
  46. package/.next/server/app/logs/page_client-reference-manifest.js +1 -1
  47. package/.next/server/app/logs.html +2 -2
  48. package/.next/server/app/logs.rsc +2 -2
  49. package/.next/server/app/logs.segments/_full.segment.rsc +2 -2
  50. package/.next/server/app/logs.segments/_head.segment.rsc +1 -1
  51. package/.next/server/app/logs.segments/_index.segment.rsc +2 -2
  52. package/.next/server/app/logs.segments/_tree.segment.rsc +2 -2
  53. package/.next/server/app/logs.segments/logs/__PAGE__.segment.rsc +1 -1
  54. package/.next/server/app/logs.segments/logs.segment.rsc +1 -1
  55. package/.next/server/app/messages/page_client-reference-manifest.js +1 -1
  56. package/.next/server/app/messages.html +2 -2
  57. package/.next/server/app/messages.rsc +2 -2
  58. package/.next/server/app/messages.segments/_full.segment.rsc +2 -2
  59. package/.next/server/app/messages.segments/_head.segment.rsc +1 -1
  60. package/.next/server/app/messages.segments/_index.segment.rsc +2 -2
  61. package/.next/server/app/messages.segments/_tree.segment.rsc +2 -2
  62. package/.next/server/app/messages.segments/messages/__PAGE__.segment.rsc +1 -1
  63. package/.next/server/app/messages.segments/messages.segment.rsc +1 -1
  64. package/.next/server/app/node/page_client-reference-manifest.js +1 -1
  65. package/.next/server/app/node.html +2 -2
  66. package/.next/server/app/node.rsc +2 -2
  67. package/.next/server/app/node.segments/_full.segment.rsc +2 -2
  68. package/.next/server/app/node.segments/_head.segment.rsc +1 -1
  69. package/.next/server/app/node.segments/_index.segment.rsc +2 -2
  70. package/.next/server/app/node.segments/_tree.segment.rsc +2 -2
  71. package/.next/server/app/node.segments/node/__PAGE__.segment.rsc +1 -1
  72. package/.next/server/app/node.segments/node.segment.rsc +1 -1
  73. package/.next/server/app/nodes/page_client-reference-manifest.js +1 -1
  74. package/.next/server/app/nodes.html +2 -2
  75. package/.next/server/app/nodes.rsc +2 -2
  76. package/.next/server/app/nodes.segments/_full.segment.rsc +2 -2
  77. package/.next/server/app/nodes.segments/_head.segment.rsc +1 -1
  78. package/.next/server/app/nodes.segments/_index.segment.rsc +2 -2
  79. package/.next/server/app/nodes.segments/_tree.segment.rsc +2 -2
  80. package/.next/server/app/nodes.segments/nodes/__PAGE__.segment.rsc +1 -1
  81. package/.next/server/app/nodes.segments/nodes.segment.rsc +1 -1
  82. package/.next/server/app/page_client-reference-manifest.js +1 -1
  83. package/.next/server/app/server-logs/page_client-reference-manifest.js +1 -1
  84. package/.next/server/app/server-logs.html +2 -2
  85. package/.next/server/app/server-logs.rsc +2 -2
  86. package/.next/server/app/server-logs.segments/_full.segment.rsc +2 -2
  87. package/.next/server/app/server-logs.segments/_head.segment.rsc +1 -1
  88. package/.next/server/app/server-logs.segments/_index.segment.rsc +2 -2
  89. package/.next/server/app/server-logs.segments/_tree.segment.rsc +2 -2
  90. package/.next/server/app/server-logs.segments/server-logs/__PAGE__.segment.rsc +1 -1
  91. package/.next/server/app/server-logs.segments/server-logs.segment.rsc +1 -1
  92. package/.next/server/app/settings/networks/page_client-reference-manifest.js +1 -1
  93. package/.next/server/app/settings/networks.html +2 -2
  94. package/.next/server/app/settings/networks.rsc +2 -2
  95. package/.next/server/app/settings/networks.segments/_full.segment.rsc +2 -2
  96. package/.next/server/app/settings/networks.segments/_head.segment.rsc +1 -1
  97. package/.next/server/app/settings/networks.segments/_index.segment.rsc +2 -2
  98. package/.next/server/app/settings/networks.segments/_tree.segment.rsc +2 -2
  99. package/.next/server/app/settings/networks.segments/settings/networks/__PAGE__.segment.rsc +1 -1
  100. package/.next/server/app/settings/networks.segments/settings/networks.segment.rsc +1 -1
  101. package/.next/server/app/settings/networks.segments/settings.segment.rsc +1 -1
  102. package/.next/server/app/settings/page_client-reference-manifest.js +1 -1
  103. package/.next/server/app/settings/tokens/page_client-reference-manifest.js +1 -1
  104. package/.next/server/app/settings/tokens.html +2 -2
  105. package/.next/server/app/settings/tokens.rsc +2 -2
  106. package/.next/server/app/settings/tokens.segments/_full.segment.rsc +2 -2
  107. package/.next/server/app/settings/tokens.segments/_head.segment.rsc +1 -1
  108. package/.next/server/app/settings/tokens.segments/_index.segment.rsc +2 -2
  109. package/.next/server/app/settings/tokens.segments/_tree.segment.rsc +2 -2
  110. package/.next/server/app/settings/tokens.segments/settings/tokens/__PAGE__.segment.rsc +1 -1
  111. package/.next/server/app/settings/tokens.segments/settings/tokens.segment.rsc +1 -1
  112. package/.next/server/app/settings/tokens.segments/settings.segment.rsc +1 -1
  113. package/.next/server/app/settings.html +2 -2
  114. package/.next/server/app/settings.rsc +3 -3
  115. package/.next/server/app/settings.segments/_full.segment.rsc +3 -3
  116. package/.next/server/app/settings.segments/_head.segment.rsc +1 -1
  117. package/.next/server/app/settings.segments/_index.segment.rsc +2 -2
  118. package/.next/server/app/settings.segments/_tree.segment.rsc +2 -2
  119. package/.next/server/app/settings.segments/settings/__PAGE__.segment.rsc +2 -2
  120. package/.next/server/app/settings.segments/settings.segment.rsc +1 -1
  121. package/.next/server/app/tasks/[id]/page_client-reference-manifest.js +1 -1
  122. package/.next/server/app/tasks/page_client-reference-manifest.js +1 -1
  123. package/.next/server/app/tasks.html +2 -2
  124. package/.next/server/app/tasks.rsc +2 -2
  125. package/.next/server/app/tasks.segments/_full.segment.rsc +2 -2
  126. package/.next/server/app/tasks.segments/_head.segment.rsc +1 -1
  127. package/.next/server/app/tasks.segments/_index.segment.rsc +2 -2
  128. package/.next/server/app/tasks.segments/_tree.segment.rsc +2 -2
  129. package/.next/server/app/tasks.segments/tasks/__PAGE__.segment.rsc +1 -1
  130. package/.next/server/app/tasks.segments/tasks.segment.rsc +1 -1
  131. package/.next/server/chunks/ssr/[root-of-the-server]__0sv~g.o._.js +1 -1
  132. package/.next/server/chunks/ssr/[root-of-the-server]__0sv~g.o._.js.map +1 -1
  133. package/.next/server/chunks/ssr/agent-network-dashboard_09kk21a._.js +4 -4
  134. package/.next/server/chunks/ssr/agent-network-dashboard_09kk21a._.js.map +1 -1
  135. package/.next/server/chunks/ssr/agent-network-dashboard_app_01jhlxz._.js +1 -1
  136. package/.next/server/chunks/ssr/agent-network-dashboard_app_01jhlxz._.js.map +1 -1
  137. package/.next/server/chunks/ssr/agent-network-dashboard_app_09d29my._.js +1 -1
  138. package/.next/server/chunks/ssr/agent-network-dashboard_app_09d29my._.js.map +1 -1
  139. package/.next/server/middleware-build-manifest.js +3 -3
  140. package/.next/server/pages/404.html +2 -2
  141. package/.next/server/pages/500.html +1 -1
  142. package/.next/static/chunks/090el2nj92~9k.js +1 -0
  143. package/.next/static/chunks/0bdnkx3fvtw2t.js +4 -0
  144. package/.next/static/chunks/0febdempmtc5e.js +1 -0
  145. package/.next/static/chunks/0jjd-epm-pvht.css +2 -0
  146. package/.next/static/chunks/{0l440-mv.tqcj.js → 0ua3qnri0i81x.js} +1 -1
  147. package/.next/trace +2 -2
  148. package/.next/trace-build +1 -1
  149. package/app/components/TopoGraph.tsx +5378 -176
  150. package/app/globals.css +373 -7
  151. package/package.json +4 -4
  152. package/scripts/topo-active-chrome-hover-text-test.mjs +107 -0
  153. package/scripts/topo-active-links-chip-halo-layers-test.mjs +81 -0
  154. package/scripts/topo-alias-chat-brightness-test.mjs +79 -0
  155. package/scripts/topo-alias-text-halo-layers-test.mjs +98 -0
  156. package/scripts/topo-avatar-chat-gate-test.mjs +77 -0
  157. package/scripts/topo-avatar-drop-shadow-test.mjs +86 -0
  158. package/scripts/topo-avatar-fallback-hover-test.mjs +104 -0
  159. package/scripts/topo-avatar-fallback-rotate-test.mjs +92 -0
  160. package/scripts/topo-avatar-rotate-test.mjs +85 -0
  161. package/scripts/topo-avatar-scale-test.mjs +89 -0
  162. package/scripts/topo-badge-chat-gate-test.mjs +74 -0
  163. package/scripts/topo-brand-drop-shadow-test.mjs +71 -0
  164. package/scripts/topo-brand-logo-breath-test.mjs +102 -0
  165. package/scripts/topo-brand-logo-halo-layers-test.mjs +85 -0
  166. package/scripts/topo-brand-logo-hover-brightness-test.mjs +105 -0
  167. package/scripts/topo-brand-logo-hover-rotate-test.mjs +93 -0
  168. package/scripts/topo-brand-logo-hover-test.mjs +85 -0
  169. package/scripts/topo-card-chat-brightness-test.mjs +86 -0
  170. package/scripts/topo-chat-ring-breath-curve-test.mjs +114 -0
  171. package/scripts/topo-chat-ring-brightness-test.mjs +80 -0
  172. package/scripts/topo-chat-ring-halo-layers-test.mjs +100 -0
  173. package/scripts/topo-chat-ring-r-breath-test.mjs +121 -0
  174. package/scripts/topo-chat-ring-status-halo-test.mjs +106 -0
  175. package/scripts/topo-chat-ring-sw-breath-test.mjs +123 -0
  176. package/scripts/topo-chip-pin-halo-test.mjs +85 -0
  177. package/scripts/topo-chip-row-digit-ls-test.mjs +135 -0
  178. package/scripts/topo-chip-row-member-alias-lit-test.mjs +154 -0
  179. package/scripts/topo-chip-row-tier-glow-brightness-test.mjs +99 -0
  180. package/scripts/topo-chip-row-unit-hover-tracking-test.mjs +124 -0
  181. package/scripts/topo-chrome-control-halo-layers-test.mjs +22 -0
  182. package/scripts/topo-chrome-wrapper-halo-test.mjs +83 -0
  183. package/scripts/topo-click-ripple-glow-test.mjs +86 -0
  184. package/scripts/topo-click-ripple-halo-layers-test.mjs +79 -0
  185. package/scripts/topo-click-ripple-sw-test.mjs +110 -0
  186. package/scripts/topo-cluster-count-attr-test.mjs +80 -0
  187. package/scripts/topo-crescent-breath-test.mjs +104 -0
  188. package/scripts/topo-crescent-envelope-breath-test.mjs +103 -0
  189. package/scripts/topo-crescent-recede-test.mjs +111 -0
  190. package/scripts/topo-dense-alias-chat-halo-test.mjs +73 -0
  191. package/scripts/topo-dense-alias-halo-layers-test.mjs +80 -0
  192. package/scripts/topo-edge-badge-circle-brightness-test.mjs +82 -0
  193. package/scripts/topo-edge-badge-circle-hot-pulse-test.mjs +100 -0
  194. package/scripts/topo-edge-badge-digit-halo-layers-test.mjs +107 -0
  195. package/scripts/topo-edge-badge-endpoint-gate-test.mjs +94 -0
  196. package/scripts/topo-edge-badge-halo-layers-test.mjs +85 -0
  197. package/scripts/topo-edge-badge-hot-pulse-test.mjs +92 -0
  198. package/scripts/topo-edge-badge-hover-glow-test.mjs +90 -0
  199. package/scripts/topo-edge-badge-text-brightness-test.mjs +83 -0
  200. package/scripts/topo-edge-chat-gate-test.mjs +71 -0
  201. package/scripts/topo-edge-flow-rail-halo-layers-test.mjs +89 -0
  202. package/scripts/topo-edge-particle-brightness-test.mjs +82 -0
  203. package/scripts/topo-edge-particle-halo-layers-test.mjs +91 -0
  204. package/scripts/topo-edge-pill-glow-test.mjs +67 -0
  205. package/scripts/topo-edge-pin-halo-test.mjs +99 -0
  206. package/scripts/topo-edge-visible-brightness-test.mjs +84 -0
  207. package/scripts/topo-edge-visible-halo-layers-test.mjs +87 -0
  208. package/scripts/topo-endpoint-ring-brightness-test.mjs +83 -0
  209. package/scripts/topo-endpoint-ring-flow-halo-test.mjs +107 -0
  210. package/scripts/topo-endpoint-ring-halo-layers-test.mjs +100 -0
  211. package/scripts/topo-filter-pill-glow-test.mjs +90 -0
  212. package/scripts/topo-filter-pill-halo-layers-test.mjs +27 -0
  213. package/scripts/topo-flow-arrow-brightness-test.mjs +82 -0
  214. package/scripts/topo-flow-rail-brightness-test.mjs +80 -0
  215. package/scripts/topo-fullscreen-attr-test.mjs +73 -0
  216. package/scripts/topo-fullscreen-brightness-test.mjs +84 -0
  217. package/scripts/topo-fullscreen-icon-rotate-test.mjs +93 -0
  218. package/scripts/topo-grid-content-bottom-attr-test.mjs +72 -0
  219. package/scripts/topo-group-box-brightness-test.mjs +84 -0
  220. package/scripts/topo-group-box-halo-layers-test.mjs +91 -0
  221. package/scripts/topo-group-chat-gate-test.mjs +77 -0
  222. package/scripts/topo-group-label-brightness-test.mjs +84 -0
  223. package/scripts/topo-group-label-halo-layers-test.mjs +78 -0
  224. package/scripts/topo-group-label-hover-glow-test.mjs +86 -0
  225. package/scripts/topo-group-label-member-alias-hover-test.mjs +125 -0
  226. package/scripts/topo-group-pill-glow-test.mjs +76 -0
  227. package/scripts/topo-group-tint-brightness-test.mjs +82 -0
  228. package/scripts/topo-halo-chat-gate-test.mjs +72 -0
  229. package/scripts/topo-hover-detail-halo-test.mjs +76 -0
  230. package/scripts/topo-hub-core-brightness-test.mjs +82 -0
  231. package/scripts/topo-hub-core-halo-layers-test.mjs +81 -0
  232. package/scripts/topo-hub-digit-brightness-test.mjs +79 -0
  233. package/scripts/topo-hub-digit-halo-layers-test.mjs +76 -0
  234. package/scripts/topo-hub-digit-ls-test.mjs +119 -0
  235. package/scripts/topo-hub-halo-brightness-test.mjs +80 -0
  236. package/scripts/topo-hub-halo-glow-test.mjs +96 -0
  237. package/scripts/topo-hub-halo-halo-layers-test.mjs +76 -0
  238. package/scripts/topo-hub-highlight-amplify-test.mjs +139 -0
  239. package/scripts/topo-hub-highlight-brightness-test.mjs +84 -0
  240. package/scripts/topo-hub-highlight-fill-transition-test.mjs +84 -0
  241. package/scripts/topo-hub-highlight-glow-test.mjs +99 -0
  242. package/scripts/topo-hub-highlight-halo-layers-test.mjs +78 -0
  243. package/scripts/topo-hub-highlight-r-test.mjs +112 -0
  244. package/scripts/topo-hub-highlight-recede-test.mjs +5 -1
  245. package/scripts/topo-hub-highlight-theme-fill-test.mjs +83 -0
  246. package/scripts/topo-hub-hover-ring-brightness-test.mjs +79 -0
  247. package/scripts/topo-hub-hover-ring-glow-test.mjs +97 -0
  248. package/scripts/topo-hub-hover-ring-halo-layers-test.mjs +71 -0
  249. package/scripts/topo-hub-idle-breath-test.mjs +6 -7
  250. package/scripts/topo-hub-spoke-brightness-test.mjs +77 -0
  251. package/scripts/topo-hub-spoke-glow-test.mjs +112 -0
  252. package/scripts/topo-hub-spoke-halo-layers-test.mjs +97 -0
  253. package/scripts/topo-hub-spoke-self-filter-test.mjs +119 -0
  254. package/scripts/topo-kicker-breath-test.mjs +100 -0
  255. package/scripts/topo-kicker-halo-layers-test.mjs +82 -0
  256. package/scripts/topo-label-card-brightness-test.mjs +81 -0
  257. package/scripts/topo-layout-hover-fw-test.mjs +98 -0
  258. package/scripts/topo-layout-toggle-brightness-test.mjs +94 -0
  259. package/scripts/topo-layout-toggle-halo-layers-test.mjs +95 -0
  260. package/scripts/topo-legend-count-brightness-test.mjs +80 -0
  261. package/scripts/topo-legend-count-halo-layers-test.mjs +79 -0
  262. package/scripts/topo-legend-count-letter-spacing-test.mjs +108 -0
  263. package/scripts/topo-legend-label-fw-test.mjs +107 -0
  264. package/scripts/topo-legend-panel-title-breath-test.mjs +86 -0
  265. package/scripts/topo-legend-pin-ring-brightness-test.mjs +82 -0
  266. package/scripts/topo-legend-pin-ring-halo-layers-test.mjs +71 -0
  267. package/scripts/topo-legend-row-count-brightness-test.mjs +85 -0
  268. package/scripts/topo-legend-row-label-glow-test.mjs +102 -0
  269. package/scripts/topo-legend-swatch-glow-test.mjs +109 -0
  270. package/scripts/topo-legend-swatch-member-alias-match-test.mjs +139 -0
  271. package/scripts/topo-legend-tint-brightness-test.mjs +83 -0
  272. package/scripts/topo-legend-trio-halo-layers-test.mjs +22 -0
  273. package/scripts/topo-minimap-container-halo-test.mjs +82 -0
  274. package/scripts/topo-minimap-dot-chat-gate-test.mjs +81 -0
  275. package/scripts/topo-minimap-hover-glow-test.mjs +109 -0
  276. package/scripts/topo-minimap-viewport-brightness-test.mjs +84 -0
  277. package/scripts/topo-minimap-viewport-halo-layers-test.mjs +24 -0
  278. package/scripts/topo-more-footer-brightness-test.mjs +94 -0
  279. package/scripts/topo-node-alias-brightness-test.mjs +84 -0
  280. package/scripts/topo-node-avatar-halo-layers-test.mjs +25 -0
  281. package/scripts/topo-node-hover-ring-halo-layers-test.mjs +70 -0
  282. package/scripts/topo-node-label-card-halo-test.mjs +76 -0
  283. package/scripts/topo-node-sub-text-brightness-test.mjs +88 -0
  284. package/scripts/topo-nodesize-brightness-test.mjs +82 -0
  285. package/scripts/topo-nodesize-halo-layers-test.mjs +89 -0
  286. package/scripts/topo-nodesize-hover-fw-test.mjs +99 -0
  287. package/scripts/topo-orphan-label-opacity-test.mjs +98 -0
  288. package/scripts/topo-panel-count-halo-layers-test.mjs +91 -0
  289. package/scripts/topo-panel-count-hover-ls-test.mjs +87 -0
  290. package/scripts/topo-panel-rect-halo-test.mjs +90 -0
  291. package/scripts/topo-panel-row-brightness-test.mjs +116 -0
  292. package/scripts/topo-panel-title-brightness-test.mjs +98 -0
  293. package/scripts/topo-panel-title-glow-test.mjs +111 -0
  294. package/scripts/topo-panel-titles-halo-layers-test.mjs +23 -0
  295. package/scripts/topo-pill-x-rotate-test.mjs +96 -0
  296. package/scripts/topo-pip-brightness-test.mjs +85 -0
  297. package/scripts/topo-pressure-bar-halo-layers-test.mjs +19 -0
  298. package/scripts/topo-pressure-seg-glow-test.mjs +92 -0
  299. package/scripts/topo-pressure-seg-member-alias-match-test.mjs +133 -0
  300. package/scripts/topo-pressure-seg-motion-test.mjs +101 -0
  301. package/scripts/topo-recent-count-brightness-test.mjs +84 -0
  302. package/scripts/topo-recent-more-fw-test.mjs +126 -0
  303. package/scripts/topo-recent-more-halo-layers-test.mjs +90 -0
  304. package/scripts/topo-recent-panel-hot-pulse-test.mjs +105 -0
  305. package/scripts/topo-recent-panel-title-breath-test.mjs +91 -0
  306. package/scripts/topo-recent-pip-halo-layers-test.mjs +82 -0
  307. package/scripts/topo-recent-row-chat-gate-test.mjs +75 -0
  308. package/scripts/topo-recent-row-content-lift-test.mjs +140 -0
  309. package/scripts/topo-recent-row-fw-test.mjs +115 -0
  310. package/scripts/topo-recent-row-text-glow-test.mjs +86 -0
  311. package/scripts/topo-recent-row-text-halo-layers-test.mjs +67 -0
  312. package/scripts/topo-recent-tint-brightness-test.mjs +80 -0
  313. package/scripts/topo-recent-ts-brightness-test.mjs +86 -0
  314. package/scripts/topo-reduced-motion-attr-test.mjs +69 -0
  315. package/scripts/topo-reset-brightness-test.mjs +83 -0
  316. package/scripts/topo-reset-icon-hover-scale-test.mjs +102 -0
  317. package/scripts/topo-runtime-badge-brightness-test.mjs +78 -0
  318. package/scripts/topo-runtime-badge-glow-test.mjs +108 -0
  319. package/scripts/topo-runtime-badge-halo-layers-test.mjs +87 -0
  320. package/scripts/topo-runtime-badge-rotate-test.mjs +85 -0
  321. package/scripts/topo-section-title-breath-test.mjs +83 -0
  322. package/scripts/topo-section-title-halo-layers-test.mjs +88 -0
  323. package/scripts/topo-spoke-chat-gate-test.mjs +72 -0
  324. package/scripts/topo-starfield-hue-test.mjs +109 -0
  325. package/scripts/topo-status-pin-pill-halo-layers-test.mjs +17 -0
  326. package/scripts/topo-status-ring-brightness-test.mjs +84 -0
  327. package/scripts/topo-status-ring-chat-gate-test.mjs +72 -0
  328. package/scripts/topo-status-ring-halo-layers-test.mjs +105 -0
  329. package/scripts/topo-status-ring-status-halo-test.mjs +110 -0
  330. package/scripts/topo-sub-text-chat-brightness-test.mjs +81 -0
  331. package/scripts/topo-title-block-envelope-breath-test.mjs +87 -0
  332. package/scripts/topo-titleblock-h2-hover-fw-test.mjs +109 -0
  333. package/scripts/topo-titleblock-h2-hover-tracking-test.mjs +128 -0
  334. package/scripts/topo-titleblock-kicker-hover-test.mjs +134 -0
  335. package/scripts/topo-vendor-chip-glow-test.mjs +97 -0
  336. package/scripts/topo-vendor-chip-halo-layers-test.mjs +18 -0
  337. package/scripts/topo-vendor-chip-pin-halo-test.mjs +88 -0
  338. package/scripts/topo-vendor-count-suffix-halo-layers-test.mjs +79 -0
  339. package/scripts/topo-vendor-distribution-wrapper-halo-test.mjs +93 -0
  340. package/scripts/topo-vendor-letter-halo-layers-test.mjs +93 -0
  341. package/scripts/topo-vendor-pill-glow-test.mjs +98 -0
  342. package/scripts/topo-watermark-breath-test.mjs +100 -0
  343. package/scripts/topo-watermark-envelope-breath-test.mjs +88 -0
  344. package/scripts/topo-watermark-recede-test.mjs +114 -0
  345. package/scripts/topo-working-online-chip-halo-layers-test.mjs +94 -0
  346. package/scripts/topo-zoom-buttons-brightness-test.mjs +94 -0
  347. package/scripts/topo-zoom-in-out-halo-layers-test.mjs +97 -0
  348. package/scripts/topo-zoom-level-breath-test.mjs +87 -0
  349. package/scripts/topo-zoom-level-brightness-test.mjs +83 -0
  350. package/scripts/topo-zoom-level-color-test.mjs +105 -0
  351. package/scripts/topo-zoom-level-halo-layers-test.mjs +78 -0
  352. package/.next/static/chunks/0g2t4ytep_laz.js +0 -4
  353. package/.next/static/chunks/0m.1mvl~t.avc.css +0 -2
  354. package/.next/static/chunks/0zm6yg97ubkp5.js +0 -1
  355. package/.next/static/chunks/1867gm.v~vka2.js +0 -1
  356. /package/.next/static/{oGQapRVlgbDN-Wxb5B4gq → Q5dzAC2O1le81YYmwsgi2}/_buildManifest.js +0 -0
  357. /package/.next/static/{oGQapRVlgbDN-Wxb5B4gq → Q5dzAC2O1le81YYmwsgi2}/_clientMiddlewareManifest.js +0 -0
  358. /package/.next/static/{oGQapRVlgbDN-Wxb5B4gq → Q5dzAC2O1le81YYmwsgi2}/_ssgManifest.js +0 -0
@@ -0,0 +1,105 @@
1
+ /* Round 643 — status ring filter gains a SECOND drop-shadow layer
2
+ * at 4px blur + 0x20 alpha, mirroring R642's multi-layer halo on
3
+ * the chat-target ring. Per-node identity rings now share the same
4
+ * "near + far" 2-layer halo vocabulary on hover/chat.
5
+ *
6
+ * Test phases:
7
+ * 1. rest: no hover/chat, halo-layers='0'
8
+ * 2. click a·1 → R621 extends isRingHovered to chat-target;
9
+ * that node's status ring gets halo-layers='2'; computed
10
+ * filter has exactly 2 drop-shadow substrings
11
+ * 3. source: light + cyber+online + cyber+offline branches all
12
+ * stack 2 drop-shadows (2px + 4px blur)
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
+ await route.fulfill({ response: r, json: { ...b, sessions: [
40
+ mk('a·1', 'idle'),
41
+ mk('a·2', 'working'),
42
+ ] } });
43
+ });
44
+ await ctx.route('**/api/hub/messages*', (r) => r.fulfill({ json: { messages: [] } }));
45
+ await ctx.route('**/api/hub/tasks*', (r) => r.fulfill({ json: { tasks: [] } }));
46
+ const page = await ctx.newPage();
47
+ await page.goto('http://127.0.0.1:3000/', { waitUntil: 'networkidle' });
48
+ await page.waitForSelector('[data-node-status-ring]', { timeout: 15000, state: 'attached' });
49
+ await page.waitForTimeout(500);
50
+
51
+ const restRings = await page.evaluate(() => {
52
+ return Array.from(document.querySelectorAll('[data-node-status-ring]')).map(el => ({
53
+ layers: el.getAttribute('data-node-status-ring-halo-layers'),
54
+ hovered: el.getAttribute('data-node-status-ring-hovered'),
55
+ }));
56
+ });
57
+
58
+ await page.click('[data-node="a·1"]', { force: true });
59
+ await page.waitForTimeout(400);
60
+
61
+ const chatState = await page.evaluate(() => {
62
+ return Array.from(document.querySelectorAll('[data-node]')).map(g => {
63
+ const ring = g.querySelector('[data-node-status-ring]');
64
+ if (!ring) return null;
65
+ const cs = getComputedStyle(ring);
66
+ return {
67
+ alias: g.getAttribute('data-node'),
68
+ layers: ring.getAttribute('data-node-status-ring-halo-layers'),
69
+ hovered: ring.getAttribute('data-node-status-ring-hovered'),
70
+ filter: cs.filter,
71
+ };
72
+ }).filter(Boolean);
73
+ });
74
+
75
+ await browser.close();
76
+
77
+ const src = readFileSync('/home/vansin/agent-network-dashboard/app/components/TopoGraph.tsx', 'utf8');
78
+ const sourceLight = /`drop-shadow\(0 0 2px \$\{status\.primary\}40\) drop-shadow\(0 0 4px \$\{status\.primary\}20\) brightness\(1\.15\)`/.test(src);
79
+ const sourceCyberOnline = /`drop-shadow\(0 0 2px \$\{status\.primary\}40\) drop-shadow\(0 0 4px \$\{status\.primary\}20\) url\(#topo-glow\) brightness\(1\.15\)`/.test(src);
80
+ const sourceLayersAttr = /data-node-status-ring-halo-layers=\{isRingHovered \? '2' : '0'\}/.test(src);
81
+
82
+ const restAllZeroLayers = restRings.every(r => r.layers === '0');
83
+ const chatActiveRing = chatState.find(c => c.alias === 'a·1');
84
+ const chatIdleRing = chatState.find(c => c.alias === 'a·2');
85
+ const activeDropShadowCount = (chatActiveRing?.filter?.match(/drop-shadow/g) || []).length;
86
+
87
+ const results = {
88
+ rest_rings_present: restRings.length >= 2,
89
+ rest_all_layers_0: restAllZeroLayers,
90
+ chat_a1_present: !!chatActiveRing,
91
+ chat_a1_layers_2: chatActiveRing?.layers === '2',
92
+ chat_a1_hovered: chatActiveRing?.hovered === 'true',
93
+ chat_a1_two_dropshadows: activeDropShadowCount === 2,
94
+ chat_a1_brightness: /brightness/.test(chatActiveRing?.filter || ''),
95
+ chat_a2_layers_0: chatIdleRing?.layers === '0',
96
+ source_light_filter: sourceLight,
97
+ source_cyber_online: sourceCyberOnline,
98
+ source_layers_attr: sourceLayersAttr,
99
+ };
100
+ const ok = Object.values(results).every(Boolean);
101
+ console.log(`${ok ? '✅' : '❌'} R643 status ring multi-layer halo (innermost identity ring 2-layer halo):`,
102
+ JSON.stringify(results, null, 2),
103
+ `\n rest: ${JSON.stringify(restRings)}`,
104
+ `\n chat: ${JSON.stringify(chatState)}`);
105
+ process.exit(ok ? 0 : 1);
@@ -0,0 +1,110 @@
1
+ /* Round 638 — status ring filter gains a status-tinted drop-shadow
2
+ * halo on isRingHovered. Sibling to R637 chat-target ring at the
3
+ * innermost per-node identity surface (r=radius). Halo color
4
+ * matches stroke color (status.primary) across all status tiers.
5
+ *
6
+ * Test phases:
7
+ * 1. mock idle node + working node
8
+ * 2. rest: no hover/chat → status-ring-halo-color='none' for all
9
+ * 3. open chat with idle node a·1 (R621 extends isRingHovered to
10
+ * chat-target) → that ring's halo-color = idle teal hex,
11
+ * filter contains drop-shadow(teal); other node stays 'none'
12
+ * 4. source: filter expression includes status.primary in drop-
13
+ * shadow across all 3 branches (light, cyber+online,
14
+ * cyber+offline)
15
+ */
16
+ import { chromium } from 'playwright';
17
+ import { readFileSync } from 'node:fs';
18
+
19
+ const TOKEN = JSON.parse(readFileSync('/home/vansin/.anet/config.json', 'utf8')).token;
20
+ const fresh = new Date(Date.now() - 60 * 1000).toISOString();
21
+
22
+ const browser = await chromium.launch({ headless: true });
23
+ const ctx = await browser.newContext({ viewport: { width: 1500, height: 1200 } });
24
+ await ctx.addCookies([{ name: 'anet_dashboard_session', value: `v3:${TOKEN}`, domain: '127.0.0.1', path: '/' }]);
25
+ await ctx.addInitScript(() => {
26
+ try {
27
+ localStorage.setItem('anet-theme', 'cyber');
28
+ localStorage.setItem('anet-topo-layout', 'ring');
29
+ sessionStorage.setItem('anet_v3_auth', '1');
30
+ } catch {}
31
+ });
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, status) => ({
37
+ alias, status, 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: [
42
+ mk('a·1', 'idle'),
43
+ mk('a·2', 'working'),
44
+ ] } });
45
+ });
46
+ await ctx.route('**/api/hub/messages*', (r) => r.fulfill({ json: { messages: [] } }));
47
+ await ctx.route('**/api/hub/tasks*', (r) => r.fulfill({ json: { tasks: [] } }));
48
+ const page = await ctx.newPage();
49
+ await page.goto('http://127.0.0.1:3000/', { waitUntil: 'networkidle' });
50
+ await page.waitForSelector('[data-node-status-ring]', { timeout: 15000, state: 'attached' });
51
+ await page.waitForTimeout(500);
52
+
53
+ // rest: collect all status-ring halo colors (should be 'none')
54
+ const restRings = await page.evaluate(() => {
55
+ return Array.from(document.querySelectorAll('[data-node-status-ring]')).map(el => ({
56
+ haloColor: el.getAttribute('data-node-status-ring-halo-color'),
57
+ hovered: el.getAttribute('data-node-status-ring-hovered'),
58
+ }));
59
+ });
60
+
61
+ // open chat with a·1 (idle) — R621 extends isRingHovered to chat-target
62
+ await page.click('[data-node="a·1"]', { force: true });
63
+ await page.waitForTimeout(400);
64
+
65
+ const chatState = await page.evaluate(() => {
66
+ const all = Array.from(document.querySelectorAll('[data-node]')).map(g => {
67
+ const ring = g.querySelector('[data-node-status-ring]');
68
+ if (!ring) return null;
69
+ const cs = getComputedStyle(ring);
70
+ return {
71
+ alias: g.getAttribute('data-node'),
72
+ haloColor: ring.getAttribute('data-node-status-ring-halo-color'),
73
+ hovered: ring.getAttribute('data-node-status-ring-hovered'),
74
+ stroke: cs.stroke,
75
+ filter: cs.filter,
76
+ };
77
+ }).filter(Boolean);
78
+ return all;
79
+ });
80
+
81
+ await browser.close();
82
+
83
+ const src = readFileSync('/home/vansin/agent-network-dashboard/app/components/TopoGraph.tsx', 'utf8');
84
+ const sourceLightFilter = /`drop-shadow\(0 0 2px \$\{status\.primary\}40\) brightness\(1\.15\)`/.test(src);
85
+ const sourceCyberOnline = /`drop-shadow\(0 0 2px \$\{status\.primary\}40\) url\(#topo-glow\) brightness\(1\.15\)`/.test(src);
86
+ const sourceHaloAttr = /data-node-status-ring-halo-color=\{isRingHovered \? status\.primary : 'none'\}/.test(src);
87
+
88
+ const restAllNone = restRings.every(r => r.haloColor === 'none');
89
+ const chatActiveRing = chatState.find(c => c.alias === 'a·1');
90
+ const chatIdleRing = chatState.find(c => c.alias === 'a·2');
91
+
92
+ const results = {
93
+ rest_all_halo_none: restAllNone,
94
+ chat_a1_present: !!chatActiveRing,
95
+ chat_a1_halo_color: /^#[0-9a-f]{6,8}$/i.test(chatActiveRing?.haloColor || ''),
96
+ chat_a1_hovered_true: chatActiveRing?.hovered === 'true',
97
+ chat_a1_filter_dropshadow: /drop-shadow/.test(chatActiveRing?.filter || ''),
98
+ chat_a1_filter_brightness: /brightness/.test(chatActiveRing?.filter || ''),
99
+ chat_a2_present: !!chatIdleRing,
100
+ chat_a2_halo_none: chatIdleRing?.haloColor === 'none',
101
+ source_light_filter: sourceLightFilter,
102
+ source_cyber_online: sourceCyberOnline,
103
+ source_halo_attr: sourceHaloAttr,
104
+ };
105
+ const ok = Object.values(results).every(Boolean);
106
+ console.log(`${ok ? '✅' : '❌'} R638 status ring status-tinted halo (chromatic identity at innermost identity surface):`,
107
+ JSON.stringify(results, null, 2),
108
+ `\n rest: ${JSON.stringify(restRings)}`,
109
+ `\n chat: ${JSON.stringify(chatState)}`);
110
+ 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,87 @@
1
+ /* Round 706 — title-block wrapper envelope breath at 11s. Mirrors the
2
+ * canvas-brand-pair nested-envelope pattern (R704/R705) at the title-
3
+ * block scope. Creates triply-nested respiration: 3 inner trio anchors
4
+ * (brand-logo 5s + kicker 6s + H2 10s) inside outer wrapper (11s).
5
+ *
6
+ * 11s coprime with all 3 inner cadences (5, 6, 10) — no common factor.
7
+ * Tighter alpha (0.92 ↔ 1, ~8%) than canvas-brand envelopes since
8
+ * title-block carries primary text identity.
9
+ */
10
+ import { chromium } from 'playwright';
11
+ import { readFileSync } from 'node:fs';
12
+
13
+ const TOKEN = JSON.parse(readFileSync('/home/vansin/.anet/config.json', 'utf8')).token;
14
+ const fresh = new Date(Date.now() - 60 * 1000).toISOString();
15
+
16
+ const browser = await chromium.launch({ headless: true });
17
+ const ctx = await browser.newContext({ viewport: { width: 1500, height: 1200 } });
18
+ await ctx.addCookies([{ name: 'anet_dashboard_session', value: `v3:${TOKEN}`, domain: '127.0.0.1', path: '/' }]);
19
+ await ctx.addInitScript(() => {
20
+ try {
21
+ localStorage.setItem('anet-theme', 'cyber');
22
+ localStorage.setItem('anet-topo-layout', 'ring');
23
+ sessionStorage.setItem('anet_v3_auth', '1');
24
+ } catch {}
25
+ });
26
+ await ctx.route('**/api/hub/status*', async (route) => {
27
+ const r = await route.fetch();
28
+ const b = await r.json();
29
+ const nid = (b.sessions || [])[0]?.network_id || 'default';
30
+ const mk = (alias) => ({
31
+ alias, status: 'idle', model: 'claude-opus-4', runtime: 'claude-code-cli',
32
+ network_id: nid, project_dir: null,
33
+ created_at: fresh, updated_at: fresh, last_seen_at: fresh,
34
+ });
35
+ await route.fulfill({ response: r, json: { ...b, sessions: [mk('a·1'), mk('a·2')] } });
36
+ });
37
+ await ctx.route('**/api/hub/messages*', (r) => r.fulfill({ json: { messages: [] } }));
38
+ await ctx.route('**/api/hub/tasks*', (r) => r.fulfill({ json: { tasks: [] } }));
39
+ const page = await ctx.newPage();
40
+ await page.goto('http://127.0.0.1:3000/', { waitUntil: 'networkidle' });
41
+ await page.waitForSelector('[data-topo-section-titleblock-group]', { timeout: 15000, state: 'attached' });
42
+ await page.waitForTimeout(300);
43
+
44
+ const runtimeState = await page.evaluate(() => {
45
+ const wrap = document.querySelector('[data-topo-section-titleblock-group]');
46
+ if (!wrap) return null;
47
+ const cs = getComputedStyle(wrap);
48
+ return {
49
+ has_class: wrap.classList.contains('anet-topo-title-block-envelope-breath'),
50
+ breath_attr: wrap.getAttribute('data-topo-section-titleblock-envelope-breath'),
51
+ anim_name: cs.animationName,
52
+ anim_duration: cs.animationDuration,
53
+ anim_iter: cs.animationIterationCount,
54
+ };
55
+ });
56
+
57
+ await browser.close();
58
+
59
+ const cssSrc = readFileSync('/home/vansin/agent-network-dashboard/app/globals.css', 'utf8');
60
+ const tsxSrc = readFileSync('/home/vansin/agent-network-dashboard/app/components/TopoGraph.tsx', 'utf8');
61
+
62
+ const cssKeyframes = /@keyframes anet-topo-title-block-envelope-breath-kf\s*\{[\s\S]*?0%, 100%\s*\{\s*opacity:\s*1;\s*\}[\s\S]*?50%\s*\{\s*opacity:\s*0\.92;/.test(cssSrc);
63
+ const cssRule = /\.anet-topo-title-block-envelope-breath\s*\{[\s\S]*?animation:\s*anet-topo-title-block-envelope-breath-kf\s+11s\s+ease-in-out\s+infinite/.test(cssSrc);
64
+ const cssReducedMotion = /prefers-reduced-motion:\s*reduce\s*\)\s*\{\s*\.anet-topo-title-block-envelope-breath\s*\{\s*animation:\s*none/.test(cssSrc);
65
+ const tsxClass = /anet-topo-title-block-envelope-breath group flex items-center gap-2\.5/.test(tsxSrc);
66
+ const tsxAttr = /data-topo-section-titleblock-envelope-breath="11s"/.test(tsxSrc);
67
+
68
+ const runtimeAnim = runtimeState?.anim_name === 'anet-topo-title-block-envelope-breath-kf' || runtimeState?.anim_name === 'none';
69
+ const runtimeDuration = runtimeState?.anim_duration === '11s' || runtimeState?.anim_name === 'none';
70
+
71
+ const results = {
72
+ wrapper_present: !!runtimeState,
73
+ has_breath_class: runtimeState?.has_class === true,
74
+ breath_attr_11s: runtimeState?.breath_attr === '11s',
75
+ runtime_anim_ok: runtimeAnim,
76
+ runtime_duration_ok: runtimeDuration,
77
+ css_keyframes: cssKeyframes,
78
+ css_rule: cssRule,
79
+ css_reduced_motion: cssReducedMotion,
80
+ tsx_class: tsxClass,
81
+ tsx_breath_attr: tsxAttr,
82
+ };
83
+ const ok = Object.values(results).every(Boolean);
84
+ console.log(`${ok ? '✅' : '❌'} R706 title-block wrapper envelope breath (11s, triply-nested respiration):`,
85
+ JSON.stringify(results, null, 2),
86
+ `\n runtime: ${JSON.stringify(runtimeState)}`);
87
+ process.exit(ok ? 0 : 1);
@@ -0,0 +1,109 @@
1
+ /* Round 556 verification: title-block H2 "Command mesh" gains
2
+ * a 2nd editorial-emphasis axis — group-hover:font-bold paired
3
+ * with R554's group-hover:tracking-tighter.
4
+ *
5
+ * Test phases:
6
+ * 1. rest: fontWeight = 600 (semibold), letter-spacing ≈ -0.45px
7
+ * 2. hover brand logo (sibling, propagates via group-hover):
8
+ * H2 fontWeight = 700 (bold), letter-spacing ≈ -0.9px
9
+ * 3. transition-property contains BOTH letter-spacing AND font-weight
10
+ * 4. source-side regex confirms group-hover:font-bold wired
11
+ */
12
+ import { chromium } from 'playwright';
13
+ import { readFileSync } from 'node:fs';
14
+
15
+ const TOKEN = JSON.parse(readFileSync('/home/vansin/.anet/config.json', 'utf8')).token;
16
+ const fresh = new Date(Date.now() - 60 * 1000).toISOString();
17
+
18
+ const browser = await chromium.launch({ headless: true });
19
+ const ctx = await browser.newContext({ viewport: { width: 1500, height: 1200 } });
20
+ await ctx.addCookies([{ name: 'anet_dashboard_session', value: `v3:${TOKEN}`, domain: '127.0.0.1', path: '/' }]);
21
+ await ctx.addInitScript(() => {
22
+ try {
23
+ localStorage.setItem('anet-theme', 'cyber');
24
+ localStorage.setItem('anet-topo-layout', 'ring');
25
+ sessionStorage.setItem('anet_v3_auth', '1');
26
+ } catch {}
27
+ });
28
+ await ctx.route('**/api/hub/status*', async (route) => {
29
+ const r = await route.fetch();
30
+ const b = await r.json();
31
+ const nid = (b.sessions || [])[0]?.network_id || 'default';
32
+ const mk = (alias) => ({
33
+ alias, status: 'idle', model: 'claude-opus-4', runtime: 'claude-code-cli',
34
+ network_id: nid, project_dir: null,
35
+ created_at: fresh, updated_at: fresh, last_seen_at: fresh,
36
+ });
37
+ await route.fulfill({ response: r, json: { ...b, sessions: [mk('a·1')] } });
38
+ });
39
+ await ctx.route('**/api/hub/messages*', (r) => r.fulfill({ json: { messages: [] } }));
40
+ await ctx.route('**/api/hub/tasks*', (r) => r.fulfill({ json: { tasks: [] } }));
41
+ const page = await ctx.newPage();
42
+ await page.goto('http://127.0.0.1:3000/', { waitUntil: 'networkidle' });
43
+ await page.waitForSelector('[data-topo-section-title]', { timeout: 15000 });
44
+ await page.waitForTimeout(500);
45
+
46
+ const h2Sel = '[data-topo-section-title]';
47
+ const logoSel = '[data-topo-brand-logo]';
48
+
49
+ const parsePx = (s) => parseFloat((s || '').replace(/px$/, ''));
50
+
51
+ // Phase 1: rest
52
+ const rest = await page.evaluate((s) => {
53
+ const el = document.querySelector(s);
54
+ if (!el) return null;
55
+ const cs = getComputedStyle(el);
56
+ return {
57
+ fontWeight: cs.fontWeight,
58
+ letterSpacing: cs.letterSpacing,
59
+ transitionProperty: cs.transitionProperty,
60
+ transitionDuration: cs.transitionDuration,
61
+ hoverFwAttr: el.getAttribute('data-topo-section-title-hover-fw'),
62
+ hoverTrackingAttr: el.getAttribute('data-topo-section-title-hover-tracking'),
63
+ };
64
+ }, h2Sel);
65
+
66
+ // Phase 2: hover brand logo (sibling) → group-hover propagates
67
+ await page.hover(logoSel);
68
+ await page.waitForTimeout(400);
69
+ const hover = await page.evaluate((s) => {
70
+ const el = document.querySelector(s);
71
+ if (!el) return null;
72
+ const cs = getComputedStyle(el);
73
+ return { fontWeight: cs.fontWeight, letterSpacing: cs.letterSpacing };
74
+ }, h2Sel);
75
+
76
+ await browser.close();
77
+
78
+ const src = readFileSync('/home/vansin/agent-network-dashboard/app/components/TopoGraph.tsx', 'utf8');
79
+ const sourceFwWired = /group-hover:font-bold/.test(src);
80
+ const sourceTransition = /transition-\[letter-spacing,font-weight\] duration-200 ease-out/.test(src);
81
+ const sourceFwAttr = /data-topo-section-title-hover-fw="700"/.test(src);
82
+
83
+ const restPx = parsePx(rest?.letterSpacing);
84
+ const hoverPx = parsePx(hover?.letterSpacing);
85
+
86
+ const results = {
87
+ rest_fw_semibold: rest?.fontWeight === '600',
88
+ rest_tracking_tight: Math.abs(restPx - (-0.45)) < 0.05,
89
+ hover_fw_bold: hover?.fontWeight === '700',
90
+ hover_tracking_tighter: Math.abs(hoverPx - (-0.9)) < 0.05,
91
+ // Both axes intensify together — confirm by directionality
92
+ fw_intensifies: parseInt(hover?.fontWeight || '0') > parseInt(rest?.fontWeight || '0'),
93
+ tracking_intensifies: hoverPx < restPx - 0.3, // more negative = tighter
94
+ transition_has_ls: /letter-spacing/.test(rest?.transitionProperty || ''),
95
+ transition_has_fw: /font-weight/.test(rest?.transitionProperty || ''),
96
+ transition_duration: rest?.transitionDuration === '0.2s',
97
+ rest_hover_fw_attr: rest?.hoverFwAttr === '700',
98
+ rest_hover_tracking_attr: rest?.hoverTrackingAttr === 'tracking-tighter',
99
+ source_fw_wired: sourceFwWired,
100
+ source_transition: sourceTransition,
101
+ source_fw_attr: sourceFwAttr,
102
+ };
103
+ const ok = Object.values(results).every(Boolean);
104
+ console.log(`${ok ? '✅' : '❌'} R556 title-block H2 group-hover:font-bold (2-axis editorial emphasis):`,
105
+ JSON.stringify(results, null, 2),
106
+ `\n rest: fw=${rest?.fontWeight}, ls=${rest?.letterSpacing}`,
107
+ `\n hover: fw=${hover?.fontWeight}, ls=${hover?.letterSpacing}`,
108
+ `\n transition: ${rest?.transitionProperty}`);
109
+ process.exit(ok ? 0 : 1);
@@ -0,0 +1,128 @@
1
+ /* Round 554 verification: title-block H2 "Command mesh" gains
2
+ * group-hover:tracking-tighter via the wrapper's `group` flag.
3
+ * Hovering the brand logo OR the title text should tighten the
4
+ * H2's kerning from -0.025em → -0.05em.
5
+ *
6
+ * Tailwind tracking utilities map to letter-spacing CSS:
7
+ * tracking-tight -0.025em
8
+ * tracking-tighter -0.05em
9
+ *
10
+ * At text-lg (18px font-size):
11
+ * tracking-tight = -0.45px
12
+ * tracking-tighter = -0.9px
13
+ *
14
+ * Test phases:
15
+ * 1. rest: H2 letter-spacing ≈ -0.45px (tracking-tight)
16
+ * 2. hover brand logo: H2 letter-spacing ≈ -0.9px (tracking-tighter)
17
+ * Verifies group-hover propagation from sibling element.
18
+ * 3. hover H2 itself: letter-spacing ≈ -0.9px (same)
19
+ * 4. source: wrapper has `group`, H2 has group-hover:tracking-tighter
20
+ */
21
+ import { chromium } from 'playwright';
22
+ import { readFileSync } from 'node:fs';
23
+
24
+ const TOKEN = JSON.parse(readFileSync('/home/vansin/.anet/config.json', 'utf8')).token;
25
+ const fresh = new Date(Date.now() - 60 * 1000).toISOString();
26
+
27
+ const browser = await chromium.launch({ headless: true });
28
+ const ctx = await browser.newContext({ viewport: { width: 1500, height: 1200 } });
29
+ await ctx.addCookies([{ name: 'anet_dashboard_session', value: `v3:${TOKEN}`, domain: '127.0.0.1', path: '/' }]);
30
+ await ctx.addInitScript(() => {
31
+ try {
32
+ localStorage.setItem('anet-theme', 'cyber');
33
+ localStorage.setItem('anet-topo-layout', 'ring');
34
+ sessionStorage.setItem('anet_v3_auth', '1');
35
+ } catch {}
36
+ });
37
+ await ctx.route('**/api/hub/status*', async (route) => {
38
+ const r = await route.fetch();
39
+ const b = await r.json();
40
+ const nid = (b.sessions || [])[0]?.network_id || 'default';
41
+ const mk = (alias) => ({
42
+ alias, status: 'idle', model: 'claude-opus-4', runtime: 'claude-code-cli',
43
+ network_id: nid, project_dir: null,
44
+ created_at: fresh, updated_at: fresh, last_seen_at: fresh,
45
+ });
46
+ await route.fulfill({ response: r, json: { ...b, sessions: [mk('a·1')] } });
47
+ });
48
+ await ctx.route('**/api/hub/messages*', (r) => r.fulfill({ json: { messages: [] } }));
49
+ await ctx.route('**/api/hub/tasks*', (r) => r.fulfill({ json: { tasks: [] } }));
50
+ const page = await ctx.newPage();
51
+ await page.goto('http://127.0.0.1:3000/', { waitUntil: 'networkidle' });
52
+ await page.waitForSelector('[data-topo-section-title]', { timeout: 15000 });
53
+ await page.waitForTimeout(500);
54
+
55
+ const h2Sel = '[data-topo-section-title]';
56
+ const logoSel = '[data-topo-brand-logo]';
57
+
58
+ const parsePx = (s) => parseFloat((s || '').replace(/px$/, ''));
59
+
60
+ // Phase 1: rest
61
+ const rest = await page.evaluate((s) => {
62
+ const el = document.querySelector(s);
63
+ if (!el) return null;
64
+ const cs = getComputedStyle(el);
65
+ return {
66
+ letterSpacing: cs.letterSpacing,
67
+ transitionProperty: cs.transitionProperty,
68
+ transitionDuration: cs.transitionDuration,
69
+ fontSize: cs.fontSize,
70
+ hoverAttr: el.getAttribute('data-topo-section-title-hover-tracking'),
71
+ };
72
+ }, h2Sel);
73
+
74
+ // Phase 2: hover brand logo (different element, but same group → H2 should tighten)
75
+ await page.hover(logoSel);
76
+ await page.waitForTimeout(400);
77
+ const hoverLogo = await page.evaluate((s) => {
78
+ const el = document.querySelector(s);
79
+ if (!el) return null;
80
+ const cs = getComputedStyle(el);
81
+ return { letterSpacing: cs.letterSpacing };
82
+ }, h2Sel);
83
+
84
+ // Phase 3: hover H2 itself (cross-confirm)
85
+ await page.mouse.move(0, 0);
86
+ await page.waitForTimeout(300);
87
+ await page.hover(h2Sel);
88
+ await page.waitForTimeout(400);
89
+ const hoverH2 = await page.evaluate((s) => {
90
+ const el = document.querySelector(s);
91
+ if (!el) return null;
92
+ const cs = getComputedStyle(el);
93
+ return { letterSpacing: cs.letterSpacing };
94
+ }, h2Sel);
95
+
96
+ await browser.close();
97
+
98
+ const src = readFileSync('/home/vansin/agent-network-dashboard/app/components/TopoGraph.tsx', 'utf8');
99
+ const sourceGroupWrapper = /<div className="group flex items-center gap-2\.5" data-topo-section-titleblock-group>/.test(src);
100
+ const sourceH2HoverTracking = /group-hover:tracking-tighter/.test(src);
101
+ const sourceH2HoverAttr = /data-topo-section-title-hover-tracking="tracking-tighter"/.test(src);
102
+
103
+ // Rest ≈ -0.45px (-0.025em × 18px), hover ≈ -0.9px (-0.05em × 18px)
104
+ const restPx = parsePx(rest?.letterSpacing);
105
+ const hoverLogoPx = parsePx(hoverLogo?.letterSpacing);
106
+ const hoverH2Px = parsePx(hoverH2?.letterSpacing);
107
+
108
+ const results = {
109
+ rest_attr_present: rest?.hoverAttr === 'tracking-tighter',
110
+ rest_tracking_tight: Math.abs(restPx - (-0.45)) < 0.05,
111
+ hover_via_logo_tightens: Math.abs(hoverLogoPx - (-0.9)) < 0.05,
112
+ hover_via_h2_tightens: Math.abs(hoverH2Px - (-0.9)) < 0.05,
113
+ hover_tighter_than_rest: hoverLogoPx < restPx - 0.3,
114
+ transition_has_letter_spacing: /letter-spacing/.test(rest?.transitionProperty || ''),
115
+ transition_duration_200ms: rest?.transitionDuration === '0.2s',
116
+ source_group_wrapper: sourceGroupWrapper,
117
+ source_h2_group_hover: sourceH2HoverTracking,
118
+ source_h2_attr: sourceH2HoverAttr,
119
+ };
120
+ const ok = Object.values(results).every(Boolean);
121
+ console.log(`${ok ? '✅' : '❌'} R554 title-block H2 group-hover:tracking-tighter:`,
122
+ JSON.stringify(results, null, 2),
123
+ `\n rest letter-spacing: ${rest?.letterSpacing} (expect ≈ -0.45px)`,
124
+ `\n hover-via-logo: ${hoverLogo?.letterSpacing} (expect ≈ -0.9px)`,
125
+ `\n hover-via-h2: ${hoverH2?.letterSpacing} (expect ≈ -0.9px)`,
126
+ `\n font-size: ${rest?.fontSize}`,
127
+ `\n transition-property: ${rest?.transitionProperty}`);
128
+ process.exit(ok ? 0 : 1);