@sleep2agi/agent-network-dashboard 0.5.3-preview.21 → 0.5.3-preview.210

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 (348) 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/{17-8bizggk6cz.js → 051~.vno73m41.js} +1 -1
  143. package/.next/static/chunks/0_5bx.ra9kap9.js +4 -0
  144. package/.next/static/chunks/0e20d3m55ia2k.js +1 -0
  145. package/.next/static/chunks/0kawbcl2g5q6s.js +1 -0
  146. package/.next/static/chunks/17if82x7mcn4j.css +2 -0
  147. package/.next/trace +2 -2
  148. package/.next/trace-build +1 -1
  149. package/app/components/TopoGraph.tsx +5127 -184
  150. package/app/globals.css +144 -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-click-ripple-glow-test.mjs +86 -0
  183. package/scripts/topo-click-ripple-halo-layers-test.mjs +79 -0
  184. package/scripts/topo-click-ripple-sw-test.mjs +110 -0
  185. package/scripts/topo-cluster-count-attr-test.mjs +80 -0
  186. package/scripts/topo-crescent-breath-test.mjs +104 -0
  187. package/scripts/topo-crescent-recede-test.mjs +111 -0
  188. package/scripts/topo-dense-alias-chat-halo-test.mjs +73 -0
  189. package/scripts/topo-dense-alias-halo-layers-test.mjs +80 -0
  190. package/scripts/topo-edge-badge-circle-brightness-test.mjs +82 -0
  191. package/scripts/topo-edge-badge-circle-hot-pulse-test.mjs +100 -0
  192. package/scripts/topo-edge-badge-digit-halo-layers-test.mjs +107 -0
  193. package/scripts/topo-edge-badge-endpoint-gate-test.mjs +94 -0
  194. package/scripts/topo-edge-badge-halo-layers-test.mjs +85 -0
  195. package/scripts/topo-edge-badge-hot-pulse-test.mjs +92 -0
  196. package/scripts/topo-edge-badge-hover-glow-test.mjs +90 -0
  197. package/scripts/topo-edge-badge-text-brightness-test.mjs +83 -0
  198. package/scripts/topo-edge-chat-gate-test.mjs +71 -0
  199. package/scripts/topo-edge-flow-rail-halo-layers-test.mjs +89 -0
  200. package/scripts/topo-edge-particle-brightness-test.mjs +82 -0
  201. package/scripts/topo-edge-particle-halo-layers-test.mjs +91 -0
  202. package/scripts/topo-edge-pill-glow-test.mjs +67 -0
  203. package/scripts/topo-edge-pin-halo-test.mjs +99 -0
  204. package/scripts/topo-edge-visible-brightness-test.mjs +84 -0
  205. package/scripts/topo-edge-visible-halo-layers-test.mjs +87 -0
  206. package/scripts/topo-endpoint-ring-brightness-test.mjs +83 -0
  207. package/scripts/topo-endpoint-ring-flow-halo-test.mjs +107 -0
  208. package/scripts/topo-endpoint-ring-halo-layers-test.mjs +100 -0
  209. package/scripts/topo-filter-pill-glow-test.mjs +90 -0
  210. package/scripts/topo-filter-pill-halo-layers-test.mjs +27 -0
  211. package/scripts/topo-flow-arrow-brightness-test.mjs +82 -0
  212. package/scripts/topo-flow-rail-brightness-test.mjs +80 -0
  213. package/scripts/topo-fullscreen-attr-test.mjs +73 -0
  214. package/scripts/topo-fullscreen-brightness-test.mjs +84 -0
  215. package/scripts/topo-fullscreen-icon-rotate-test.mjs +93 -0
  216. package/scripts/topo-grid-content-bottom-attr-test.mjs +72 -0
  217. package/scripts/topo-group-box-brightness-test.mjs +84 -0
  218. package/scripts/topo-group-box-halo-layers-test.mjs +91 -0
  219. package/scripts/topo-group-chat-gate-test.mjs +77 -0
  220. package/scripts/topo-group-label-brightness-test.mjs +84 -0
  221. package/scripts/topo-group-label-halo-layers-test.mjs +78 -0
  222. package/scripts/topo-group-label-hover-glow-test.mjs +86 -0
  223. package/scripts/topo-group-label-member-alias-hover-test.mjs +125 -0
  224. package/scripts/topo-group-pill-glow-test.mjs +76 -0
  225. package/scripts/topo-group-tint-brightness-test.mjs +82 -0
  226. package/scripts/topo-halo-chat-gate-test.mjs +72 -0
  227. package/scripts/topo-hover-detail-halo-test.mjs +76 -0
  228. package/scripts/topo-hub-core-brightness-test.mjs +82 -0
  229. package/scripts/topo-hub-core-halo-layers-test.mjs +81 -0
  230. package/scripts/topo-hub-digit-brightness-test.mjs +79 -0
  231. package/scripts/topo-hub-digit-halo-layers-test.mjs +76 -0
  232. package/scripts/topo-hub-digit-ls-test.mjs +119 -0
  233. package/scripts/topo-hub-halo-brightness-test.mjs +80 -0
  234. package/scripts/topo-hub-halo-glow-test.mjs +96 -0
  235. package/scripts/topo-hub-halo-halo-layers-test.mjs +76 -0
  236. package/scripts/topo-hub-highlight-amplify-test.mjs +139 -0
  237. package/scripts/topo-hub-highlight-brightness-test.mjs +84 -0
  238. package/scripts/topo-hub-highlight-fill-transition-test.mjs +84 -0
  239. package/scripts/topo-hub-highlight-glow-test.mjs +99 -0
  240. package/scripts/topo-hub-highlight-halo-layers-test.mjs +78 -0
  241. package/scripts/topo-hub-highlight-r-test.mjs +112 -0
  242. package/scripts/topo-hub-highlight-recede-test.mjs +144 -0
  243. package/scripts/topo-hub-highlight-theme-fill-test.mjs +83 -0
  244. package/scripts/topo-hub-hover-ring-brightness-test.mjs +79 -0
  245. package/scripts/topo-hub-hover-ring-glow-test.mjs +97 -0
  246. package/scripts/topo-hub-hover-ring-halo-layers-test.mjs +71 -0
  247. package/scripts/topo-hub-idle-breath-test.mjs +7 -2
  248. package/scripts/topo-hub-spoke-brightness-test.mjs +77 -0
  249. package/scripts/topo-hub-spoke-glow-test.mjs +112 -0
  250. package/scripts/topo-hub-spoke-halo-layers-test.mjs +97 -0
  251. package/scripts/topo-hub-spoke-self-filter-test.mjs +119 -0
  252. package/scripts/topo-kicker-halo-layers-test.mjs +82 -0
  253. package/scripts/topo-label-card-brightness-test.mjs +81 -0
  254. package/scripts/topo-layout-hover-fw-test.mjs +98 -0
  255. package/scripts/topo-layout-toggle-brightness-test.mjs +94 -0
  256. package/scripts/topo-layout-toggle-halo-layers-test.mjs +95 -0
  257. package/scripts/topo-legend-count-brightness-test.mjs +80 -0
  258. package/scripts/topo-legend-count-halo-layers-test.mjs +79 -0
  259. package/scripts/topo-legend-count-letter-spacing-test.mjs +108 -0
  260. package/scripts/topo-legend-label-fw-test.mjs +107 -0
  261. package/scripts/topo-legend-pin-ring-brightness-test.mjs +82 -0
  262. package/scripts/topo-legend-pin-ring-halo-layers-test.mjs +71 -0
  263. package/scripts/topo-legend-row-count-brightness-test.mjs +85 -0
  264. package/scripts/topo-legend-row-label-glow-test.mjs +102 -0
  265. package/scripts/topo-legend-swatch-glow-test.mjs +109 -0
  266. package/scripts/topo-legend-swatch-member-alias-match-test.mjs +139 -0
  267. package/scripts/topo-legend-tint-brightness-test.mjs +83 -0
  268. package/scripts/topo-legend-trio-halo-layers-test.mjs +22 -0
  269. package/scripts/topo-minimap-container-halo-test.mjs +82 -0
  270. package/scripts/topo-minimap-dot-chat-gate-test.mjs +81 -0
  271. package/scripts/topo-minimap-hover-glow-test.mjs +109 -0
  272. package/scripts/topo-minimap-viewport-brightness-test.mjs +84 -0
  273. package/scripts/topo-minimap-viewport-halo-layers-test.mjs +24 -0
  274. package/scripts/topo-more-footer-brightness-test.mjs +94 -0
  275. package/scripts/topo-node-alias-brightness-test.mjs +84 -0
  276. package/scripts/topo-node-avatar-halo-layers-test.mjs +25 -0
  277. package/scripts/topo-node-hover-ring-halo-layers-test.mjs +70 -0
  278. package/scripts/topo-node-label-card-halo-test.mjs +76 -0
  279. package/scripts/topo-node-sub-text-brightness-test.mjs +88 -0
  280. package/scripts/topo-nodesize-brightness-test.mjs +82 -0
  281. package/scripts/topo-nodesize-halo-layers-test.mjs +89 -0
  282. package/scripts/topo-nodesize-hover-fw-test.mjs +99 -0
  283. package/scripts/topo-orphan-label-opacity-test.mjs +98 -0
  284. package/scripts/topo-panel-count-halo-layers-test.mjs +91 -0
  285. package/scripts/topo-panel-count-hover-ls-test.mjs +87 -0
  286. package/scripts/topo-panel-rect-halo-test.mjs +90 -0
  287. package/scripts/topo-panel-row-brightness-test.mjs +116 -0
  288. package/scripts/topo-panel-title-brightness-test.mjs +98 -0
  289. package/scripts/topo-panel-title-glow-test.mjs +111 -0
  290. package/scripts/topo-panel-titles-halo-layers-test.mjs +23 -0
  291. package/scripts/topo-pill-x-rotate-test.mjs +96 -0
  292. package/scripts/topo-pip-brightness-test.mjs +85 -0
  293. package/scripts/topo-pressure-bar-halo-layers-test.mjs +19 -0
  294. package/scripts/topo-pressure-seg-glow-test.mjs +92 -0
  295. package/scripts/topo-pressure-seg-member-alias-match-test.mjs +133 -0
  296. package/scripts/topo-pressure-seg-motion-test.mjs +101 -0
  297. package/scripts/topo-recent-count-brightness-test.mjs +84 -0
  298. package/scripts/topo-recent-more-fw-test.mjs +126 -0
  299. package/scripts/topo-recent-more-halo-layers-test.mjs +90 -0
  300. package/scripts/topo-recent-panel-hot-pulse-test.mjs +105 -0
  301. package/scripts/topo-recent-pip-halo-layers-test.mjs +82 -0
  302. package/scripts/topo-recent-row-chat-gate-test.mjs +75 -0
  303. package/scripts/topo-recent-row-content-lift-test.mjs +140 -0
  304. package/scripts/topo-recent-row-fw-test.mjs +115 -0
  305. package/scripts/topo-recent-row-text-glow-test.mjs +86 -0
  306. package/scripts/topo-recent-row-text-halo-layers-test.mjs +67 -0
  307. package/scripts/topo-recent-tint-brightness-test.mjs +80 -0
  308. package/scripts/topo-recent-ts-brightness-test.mjs +86 -0
  309. package/scripts/topo-reduced-motion-attr-test.mjs +69 -0
  310. package/scripts/topo-reset-brightness-test.mjs +83 -0
  311. package/scripts/topo-reset-icon-hover-scale-test.mjs +102 -0
  312. package/scripts/topo-runtime-badge-brightness-test.mjs +78 -0
  313. package/scripts/topo-runtime-badge-glow-test.mjs +108 -0
  314. package/scripts/topo-runtime-badge-halo-layers-test.mjs +87 -0
  315. package/scripts/topo-runtime-badge-rotate-test.mjs +85 -0
  316. package/scripts/topo-section-title-halo-layers-test.mjs +88 -0
  317. package/scripts/topo-spoke-chat-gate-test.mjs +72 -0
  318. package/scripts/topo-starfield-hue-test.mjs +109 -0
  319. package/scripts/topo-status-pin-pill-halo-layers-test.mjs +17 -0
  320. package/scripts/topo-status-ring-brightness-test.mjs +84 -0
  321. package/scripts/topo-status-ring-chat-gate-test.mjs +72 -0
  322. package/scripts/topo-status-ring-halo-layers-test.mjs +105 -0
  323. package/scripts/topo-status-ring-status-halo-test.mjs +110 -0
  324. package/scripts/topo-sub-text-chat-brightness-test.mjs +81 -0
  325. package/scripts/topo-titleblock-h2-hover-fw-test.mjs +109 -0
  326. package/scripts/topo-titleblock-h2-hover-tracking-test.mjs +128 -0
  327. package/scripts/topo-titleblock-kicker-hover-test.mjs +134 -0
  328. package/scripts/topo-vendor-chip-glow-test.mjs +97 -0
  329. package/scripts/topo-vendor-chip-halo-layers-test.mjs +18 -0
  330. package/scripts/topo-vendor-chip-pin-halo-test.mjs +88 -0
  331. package/scripts/topo-vendor-count-suffix-halo-layers-test.mjs +79 -0
  332. package/scripts/topo-vendor-letter-halo-layers-test.mjs +93 -0
  333. package/scripts/topo-vendor-pill-glow-test.mjs +98 -0
  334. package/scripts/topo-watermark-breath-test.mjs +100 -0
  335. package/scripts/topo-watermark-recede-test.mjs +114 -0
  336. package/scripts/topo-working-online-chip-halo-layers-test.mjs +94 -0
  337. package/scripts/topo-zoom-buttons-brightness-test.mjs +94 -0
  338. package/scripts/topo-zoom-in-out-halo-layers-test.mjs +97 -0
  339. package/scripts/topo-zoom-level-brightness-test.mjs +83 -0
  340. package/scripts/topo-zoom-level-color-test.mjs +105 -0
  341. package/scripts/topo-zoom-level-halo-layers-test.mjs +78 -0
  342. package/.next/static/chunks/01uyqm4r9qnpt.js +0 -1
  343. package/.next/static/chunks/04m~pbcsq2ej6.js +0 -4
  344. package/.next/static/chunks/0m.1mvl~t.avc.css +0 -2
  345. package/.next/static/chunks/112g_zni~x6_j.js +0 -1
  346. /package/.next/static/{9EnLX9vOfh-hoRKs1_aTC → 3D5_n49X1pW-2zn5wZP3e}/_buildManifest.js +0 -0
  347. /package/.next/static/{9EnLX9vOfh-hoRKs1_aTC → 3D5_n49X1pW-2zn5wZP3e}/_clientMiddlewareManifest.js +0 -0
  348. /package/.next/static/{9EnLX9vOfh-hoRKs1_aTC → 3D5_n49X1pW-2zn5wZP3e}/_ssgManifest.js +0 -0
@@ -0,0 +1,79 @@
1
+ /* Round 657 — click-ripple drop-shadow gains a SECOND outer layer
2
+ * at 8px + 0x4c alpha (half R608 inner 0x99). 16th anchor in
3
+ * multi-layer halo family (1st click-feedback anchor).
4
+ */
5
+ import { chromium } from 'playwright';
6
+ import { readFileSync } from 'node:fs';
7
+
8
+ const TOKEN = JSON.parse(readFileSync('/home/vansin/.anet/config.json', 'utf8')).token;
9
+ const fresh = new Date(Date.now() - 60 * 1000).toISOString();
10
+
11
+ const browser = await chromium.launch({ headless: true });
12
+ const ctx = await browser.newContext({ viewport: { width: 1500, height: 1200 } });
13
+ await ctx.addCookies([{ name: 'anet_dashboard_session', value: `v3:${TOKEN}`, domain: '127.0.0.1', path: '/' }]);
14
+ await ctx.addInitScript(() => {
15
+ try {
16
+ localStorage.setItem('anet-theme', 'cyber');
17
+ localStorage.setItem('anet-topo-layout', 'ring');
18
+ sessionStorage.setItem('anet_v3_auth', '1');
19
+ } catch {}
20
+ });
21
+ await ctx.route('**/api/hub/status*', async (route) => {
22
+ const r = await route.fetch();
23
+ const b = await r.json();
24
+ const nid = (b.sessions || [])[0]?.network_id || 'default';
25
+ const mk = (alias) => ({
26
+ alias, status: 'idle', model: 'claude-opus-4', runtime: 'claude-code-cli',
27
+ network_id: nid, project_dir: null,
28
+ created_at: fresh, updated_at: fresh, last_seen_at: fresh,
29
+ });
30
+ await route.fulfill({ response: r, json: { ...b, sessions: [mk('a·1'), mk('a·2')] } });
31
+ });
32
+ await ctx.route('**/api/hub/messages*', (r) => r.fulfill({ json: { messages: [] } }));
33
+ await ctx.route('**/api/hub/tasks*', (r) => r.fulfill({ json: { tasks: [] } }));
34
+ const page = await ctx.newPage();
35
+ await page.goto('http://127.0.0.1:3000/', { waitUntil: 'networkidle' });
36
+ await page.waitForSelector('[data-node="a·1"]', { timeout: 15000 });
37
+ await page.waitForTimeout(500);
38
+
39
+ // rest: no ripple
40
+ const restRipple = await page.evaluate(() => !!document.querySelector('[data-click-ripple]'));
41
+
42
+ // click node → ripple mounts; poll to catch it before it self-cleans
43
+ await page.click('[data-node="a·1"]', { force: true });
44
+ let activeState = null;
45
+ for (let i = 0; i < 12; i++) {
46
+ await page.waitForTimeout(40);
47
+ const s = await page.evaluate(() => {
48
+ const el = document.querySelector('[data-click-ripple]');
49
+ if (!el) return null;
50
+ const cs = getComputedStyle(el);
51
+ return {
52
+ layers: el.getAttribute('data-click-ripple-halo-layers'),
53
+ filter: cs.filter,
54
+ };
55
+ });
56
+ if (s) { activeState = s; break; }
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: `drop-shadow\(0 0 4px \$\{clickRipple\.color\}99\) drop-shadow\(0 0 8px \$\{clickRipple\.color\}4c\)`/.test(src);
63
+ const sourceLayersAttr = /data-click-ripple-halo-layers="2"/.test(src);
64
+
65
+ const dropShadowCount = (activeState?.filter?.match(/drop-shadow/g) || []).length;
66
+
67
+ const results = {
68
+ rest_no_ripple: restRipple === false,
69
+ active_present: !!activeState,
70
+ active_layers_2: activeState?.layers === '2',
71
+ active_two_dropshadows: dropShadowCount === 2,
72
+ source_filter: sourceFilter,
73
+ source_layers_attr: sourceLayersAttr,
74
+ };
75
+ const ok = Object.values(results).every(Boolean);
76
+ console.log(`${ok ? '✅' : '❌'} R657 click-ripple multi-layer halo (1st click-feedback anchor):`,
77
+ JSON.stringify(results, null, 2),
78
+ `\n active: ${JSON.stringify(activeState)}`);
79
+ process.exit(ok ? 0 : 1);
@@ -0,0 +1,110 @@
1
+ /* Round 631 — click-ripple gains a THIRD animate axis:
2
+ * stroke-width 2 → 0.5 over 500ms with the same R227 ease-out
3
+ * keySplines as r + opacity. Reads as a real-water-ripple thinning
4
+ * wavefront instead of a constant-thickness expanding line.
5
+ *
6
+ * Test phases:
7
+ * 1. mock 2 nodes → no ripple at rest, no [data-click-ripple]
8
+ * 2. click a node → ripple mounts with 3 <animate> children:
9
+ * - r (R14/R227)
10
+ * - opacity (R227/R403)
11
+ * - stroke-width (R631 — this round)
12
+ * all dur=0.5s, calcMode=spline, keySplines='0.25 0.1 0.25 1',
13
+ * fill=freeze
14
+ * 3. ripple disappears after ~600ms (setClickRipple→null timeout)
15
+ * 4. source: stroke-width animate sits as a sibling of the opacity
16
+ * animate inside the [data-click-ripple] <circle>
17
+ */
18
+ import { chromium } from 'playwright';
19
+ import { readFileSync } from 'node:fs';
20
+
21
+ const TOKEN = JSON.parse(readFileSync('/home/vansin/.anet/config.json', 'utf8')).token;
22
+ const fresh = new Date(Date.now() - 60 * 1000).toISOString();
23
+
24
+ const browser = await chromium.launch({ headless: true });
25
+ const ctx = await browser.newContext({ viewport: { width: 1500, height: 1200 } });
26
+ await ctx.addCookies([{ name: 'anet_dashboard_session', value: `v3:${TOKEN}`, domain: '127.0.0.1', path: '/' }]);
27
+ await ctx.addInitScript(() => {
28
+ try {
29
+ localStorage.setItem('anet-theme', 'cyber');
30
+ localStorage.setItem('anet-topo-layout', 'ring');
31
+ sessionStorage.setItem('anet_v3_auth', '1');
32
+ } catch {}
33
+ });
34
+ await ctx.route('**/api/hub/status*', async (route) => {
35
+ const r = await route.fetch();
36
+ const b = await r.json();
37
+ const nid = (b.sessions || [])[0]?.network_id || 'default';
38
+ const mk = (alias) => ({
39
+ alias, status: 'idle', model: 'claude-opus-4', runtime: 'claude-code-cli',
40
+ network_id: nid, project_dir: null,
41
+ created_at: fresh, updated_at: fresh, last_seen_at: fresh,
42
+ });
43
+ await route.fulfill({ response: r, json: { ...b, sessions: [mk('a·1'), mk('a·2')] } });
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-node="a·1"]', { timeout: 15000 });
50
+ await page.waitForTimeout(500);
51
+
52
+ // 1. rest: no ripple
53
+ const restRipple = await page.evaluate(() => !!document.querySelector('[data-click-ripple]'));
54
+
55
+ // 2. click node — ripple mounts
56
+ await page.click('[data-node="a·1"]', { force: true });
57
+ // poll quickly to catch the ripple before it self-cleans
58
+ let activeState = null;
59
+ for (let i = 0; i < 12; i++) {
60
+ await page.waitForTimeout(40);
61
+ const s = await page.evaluate(() => {
62
+ const el = document.querySelector('[data-click-ripple]');
63
+ if (!el) return null;
64
+ const animates = Array.from(el.querySelectorAll('animate'));
65
+ return {
66
+ strokeWidth: el.getAttribute('stroke-width'),
67
+ animateCount: animates.length,
68
+ animateAttrs: animates.map(a => ({
69
+ attr: a.getAttribute('attributeName'),
70
+ dur: a.getAttribute('dur'),
71
+ vals: a.getAttribute('values'),
72
+ calc: a.getAttribute('calcMode'),
73
+ spl: a.getAttribute('keySplines'),
74
+ fill: a.getAttribute('fill'),
75
+ })),
76
+ };
77
+ });
78
+ if (s) { activeState = s; break; }
79
+ }
80
+
81
+ await browser.close();
82
+
83
+ const src = readFileSync('/home/vansin/agent-network-dashboard/app/components/TopoGraph.tsx', 'utf8');
84
+ const sourceSwAnimate = /<animate\s+attributeName="stroke-width"\s+values="2;0\.5"\s+dur="0\.5s"\s+calcMode="spline"\s+keyTimes="0;1"\s+keySplines="0\.25 0\.1 0\.25 1"\s+fill="freeze"/.test(src);
85
+ const sourceSwAttrs = /data-click-ripple-stroke-width-start="2"\s+data-click-ripple-stroke-width-end="0\.5"/.test(src);
86
+
87
+ const swAnimate = activeState?.animateAttrs?.find(a => a.attr === 'stroke-width');
88
+ const rAnimate = activeState?.animateAttrs?.find(a => a.attr === 'r');
89
+ const opAnimate = activeState?.animateAttrs?.find(a => a.attr === 'opacity');
90
+
91
+ const results = {
92
+ rest_no_ripple: restRipple === false,
93
+ active_ripple_present: activeState != null,
94
+ active_3_animates: activeState?.animateCount === 3,
95
+ active_has_r: rAnimate != null,
96
+ active_has_opacity: opAnimate != null,
97
+ active_has_sw: swAnimate != null,
98
+ active_sw_values: swAnimate?.vals === '2;0.5',
99
+ active_sw_dur: swAnimate?.dur === '0.5s',
100
+ active_sw_spline_easeout: swAnimate?.spl === '0.25 0.1 0.25 1',
101
+ active_sw_calc_spline: swAnimate?.calc === 'spline',
102
+ active_sw_fill_freeze: swAnimate?.fill === 'freeze',
103
+ source_sw_animate: sourceSwAnimate,
104
+ source_sw_attrs: sourceSwAttrs,
105
+ };
106
+ const ok = Object.values(results).every(Boolean);
107
+ console.log(`${ok ? '✅' : '❌'} R631 click-ripple stroke-width thinning (3-axis ripple):`,
108
+ JSON.stringify(results, null, 2),
109
+ `\n active: ${JSON.stringify(activeState)}`);
110
+ process.exit(ok ? 0 : 1);
@@ -0,0 +1,80 @@
1
+ /* Round 512 verification: root svg surfaces `data-topo-cluster-count`
2
+ * (14th attr in canvas state surface set). Paired with R469 fleet
3
+ * numerics + R502 categorical density.
4
+ *
5
+ * Contract:
6
+ * - grid layout: data-topo-cluster-count = groupBoxes.length (≥ 1)
7
+ * - ring layout: data-topo-cluster-count = '0' (groupBoxes is empty)
8
+ * - orphan-band fixture: cluster count includes the orphan band
9
+ *
10
+ * Tests across 2 fixtures × 2 layouts.
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
+ async function probe({ layout, sessions, label }) {
19
+ const browser = await chromium.launch({ headless: true });
20
+ const ctx = await browser.newContext({ viewport: { width: 1500, height: 1200 } });
21
+ await ctx.addCookies([{ name: 'anet_dashboard_session', value: `v3:${TOKEN}`, domain: '127.0.0.1', path: '/' }]);
22
+ await ctx.addInitScript((l) => {
23
+ try {
24
+ localStorage.setItem('anet-theme', 'cyber');
25
+ localStorage.setItem('anet-topo-layout', l);
26
+ sessionStorage.setItem('anet_v3_auth', '1');
27
+ } catch {}
28
+ }, layout);
29
+ await ctx.route('**/api/hub/status*', async (route) => {
30
+ const r = await route.fetch();
31
+ const b = await r.json();
32
+ const nid = (b.sessions || [])[0]?.network_id || 'default';
33
+ const mk = (alias, status) => ({
34
+ alias, status, model: 'claude-opus-4', runtime: 'claude-code-cli',
35
+ network_id: nid, project_dir: null,
36
+ created_at: fresh, updated_at: fresh, last_seen_at: fresh,
37
+ });
38
+ await route.fulfill({ response: r, json: { ...b, sessions: sessions.map(s => mk(s.alias, s.status)) } });
39
+ });
40
+ await ctx.route('**/api/hub/messages*', (r) => r.fulfill({ json: { messages: [] } }));
41
+ await ctx.route('**/api/hub/tasks*', (r) => r.fulfill({ json: { tasks: [] } }));
42
+ const page = await ctx.newPage();
43
+ await page.goto('http://127.0.0.1:3000/', { waitUntil: 'networkidle' });
44
+ await page.waitForSelector('svg[data-topo-cluster-count]', { timeout: 15000 });
45
+ await page.waitForTimeout(1500);
46
+ const count = await page.evaluate(() =>
47
+ document.querySelector('svg[viewBox="0 0 1000 680"]')?.getAttribute('data-topo-cluster-count')
48
+ );
49
+ await browser.close();
50
+ return { label, count };
51
+ }
52
+
53
+ // Fixture A: 2 prefix groups (alpha×3 + beta×2) + 3 orphans
54
+ const fixtureA = [
55
+ { alias: 'alpha·1', status: 'working' },
56
+ { alias: 'alpha·2', status: 'idle' },
57
+ { alias: 'alpha·3', status: 'idle' },
58
+ { alias: 'beta·1', status: 'working' },
59
+ { alias: 'beta·2', status: 'idle' },
60
+ { alias: 'zeta', status: 'idle' },
61
+ { alias: 'omega', status: 'idle' },
62
+ { alias: 'lonely', status: 'idle' },
63
+ ];
64
+
65
+ const aGrid = await probe({ layout: 'grid', sessions: fixtureA, label: 'grid+2prefix+3orph' });
66
+ const aRing = await probe({ layout: 'ring', sessions: fixtureA, label: 'ring+same fixture' });
67
+
68
+ const src = readFileSync('/home/vansin/agent-network-dashboard/app/components/TopoGraph.tsx', 'utf8');
69
+ const sourceWired = /data-topo-cluster-count=\{groupBoxes\.length\}/.test(src);
70
+
71
+ const results = {
72
+ grid_returns_3: aGrid.count === '3', // 2 prefix groups + 1 orphan band
73
+ ring_returns_0: aRing.count === '0', // no group boxes in ring layout
74
+ source_wired: sourceWired,
75
+ };
76
+ const ok = Object.values(results).every(Boolean);
77
+ console.log(`${ok ? '✅' : '❌'} R512 cluster-count attr:`, JSON.stringify(results),
78
+ '\n grid:', JSON.stringify(aGrid),
79
+ '\n ring:', JSON.stringify(aRing));
80
+ process.exit(ok ? 0 : 1);
@@ -0,0 +1,104 @@
1
+ /* Round 528 verification: brand crescent gains ambient SMIL breath
2
+ * (0.8↔1.0 fill-opacity, 7s, repeat indefinite). 呼吸感 family 4th
3
+ * anchor — symmetric to R519 watermark breath but at 7s vs 6s cadence
4
+ * so the two ambient anchors don't beat together visibly.
5
+ *
6
+ * Test phases:
7
+ * 1. motion enabled: data-topo-brand-canvas-mark-breath='true'
8
+ * + <animate> child mounted on inner <rect>
9
+ * + values='0.8;1;0.8', dur='7s', repeatCount='indefinite'
10
+ * + attributeName='fill-opacity' (NOT 'opacity')
11
+ * 2. reduced-motion: breath attr='false', NO <animate> child
12
+ * 3. wrapper recede + visibility still works (regression check)
13
+ * 4. source-side regex confirms wiring
14
+ */
15
+ import { chromium } from 'playwright';
16
+ import { readFileSync } from 'node:fs';
17
+
18
+ const TOKEN = JSON.parse(readFileSync('/home/vansin/.anet/config.json', 'utf8')).token;
19
+ const fresh = new Date(Date.now() - 60 * 1000).toISOString();
20
+
21
+ async function probe(reducedMotion) {
22
+ const browser = await chromium.launch({ headless: true });
23
+ const ctx = await browser.newContext({
24
+ viewport: { width: 1500, height: 1200 },
25
+ reducedMotion: reducedMotion ? 'reduce' : 'no-preference',
26
+ });
27
+ await ctx.addCookies([{ name: 'anet_dashboard_session', value: `v3:${TOKEN}`, domain: '127.0.0.1', path: '/' }]);
28
+ await ctx.addInitScript(() => {
29
+ try {
30
+ localStorage.setItem('anet-theme', 'cyber');
31
+ localStorage.setItem('anet-topo-layout', 'ring');
32
+ sessionStorage.setItem('anet_v3_auth', '1');
33
+ } catch {}
34
+ });
35
+ await ctx.route('**/api/hub/status*', async (route) => {
36
+ const r = await route.fetch();
37
+ const b = await r.json();
38
+ const nid = (b.sessions || [])[0]?.network_id || 'default';
39
+ const mk = (alias) => ({
40
+ alias, status: 'idle', model: 'claude-opus-4', runtime: 'claude-code-cli',
41
+ network_id: nid, project_dir: null,
42
+ created_at: fresh, updated_at: fresh, last_seen_at: fresh,
43
+ });
44
+ await route.fulfill({ response: r, json: { ...b, sessions: [
45
+ mk('alpha·1'), mk('alpha·2'),
46
+ ] } });
47
+ });
48
+ // NO messages → flowLinks=0 → crescent visible
49
+ await ctx.route('**/api/hub/messages*', (r) => r.fulfill({ json: { messages: [] } }));
50
+ await ctx.route('**/api/hub/tasks*', (r) => r.fulfill({ json: { tasks: [] } }));
51
+ const page = await ctx.newPage();
52
+ await page.goto('http://127.0.0.1:3000/', { waitUntil: 'networkidle' });
53
+ await page.waitForSelector('[data-topo-brand-canvas-mark]', { timeout: 15000 });
54
+ await page.waitForTimeout(800);
55
+ const data = await page.evaluate(() => {
56
+ const wrap = document.querySelector('[data-topo-brand-canvas-mark]');
57
+ const rect = wrap?.querySelector('rect[mask*="canvas-corner-mask"]');
58
+ const animate = rect?.querySelector('animate');
59
+ return {
60
+ breathAttr: wrap?.getAttribute('data-topo-brand-canvas-mark-breath'),
61
+ visibleAttr: wrap?.getAttribute('data-topo-brand-canvas-mark-visible'),
62
+ hasAnimate: !!animate,
63
+ attrName: animate?.getAttribute('attributeName') || null,
64
+ values: animate?.getAttribute('values') || null,
65
+ dur: animate?.getAttribute('dur') || null,
66
+ repeatCount: animate?.getAttribute('repeatCount') || null,
67
+ };
68
+ });
69
+ await browser.close();
70
+ return data;
71
+ }
72
+
73
+ const normal = await probe(false);
74
+ const reduced = await probe(true);
75
+
76
+ const src = readFileSync('/home/vansin/agent-network-dashboard/app/components/TopoGraph.tsx', 'utf8');
77
+ const sourceAnimateGated =
78
+ /\{!reducedMotion && \(\s*<animate attributeName="fill-opacity" values="0\.8;1;0\.8" dur="7s" repeatCount="indefinite" \/>\s*\)\}/.test(src);
79
+ const sourceAttrWired =
80
+ /data-topo-brand-canvas-mark-breath=\{reducedMotion \? 'false' : 'true'\}/.test(src);
81
+
82
+ const results = {
83
+ // motion enabled
84
+ normal_breath_true: normal?.breathAttr === 'true',
85
+ normal_visible_true: normal?.visibleAttr === 'true',
86
+ normal_has_animate: normal?.hasAnimate === true,
87
+ normal_attr_fill_op: normal?.attrName === 'fill-opacity',
88
+ normal_values_correct: normal?.values === '0.8;1;0.8',
89
+ normal_dur_7s: normal?.dur === '7s',
90
+ normal_repeat_indef: normal?.repeatCount === 'indefinite',
91
+ // prefers-reduced-motion
92
+ reduced_breath_false: reduced?.breathAttr === 'false',
93
+ reduced_no_animate: reduced?.hasAnimate === false,
94
+ reduced_visible_true: reduced?.visibleAttr === 'true', // crescent still visible, just no breath
95
+ // source
96
+ source_animate_gated: sourceAnimateGated,
97
+ source_attr_wired: sourceAttrWired,
98
+ };
99
+ const ok = Object.values(results).every(Boolean);
100
+ console.log(`${ok ? '✅' : '❌'} R528 crescent ambient breath:`,
101
+ JSON.stringify(results, null, 2),
102
+ '\n normal:', JSON.stringify(normal),
103
+ '\n reduced:', JSON.stringify(reduced));
104
+ process.exit(ok ? 0 : 1);
@@ -0,0 +1,111 @@
1
+ /* Round 526 verification: brand crescent at canvas top-left gains
2
+ * focal-recede (4th anchor in family). Multiplies visible opacity by
3
+ * 0.7 when non-hub canvas surface is hovered.
4
+ *
5
+ * Test phases (flowLinks=0 state — crescent visible):
6
+ * 1. rest: opacity=0.35, recede attr='false', visible='true'
7
+ * 2. hover legend `idle` row: opacity=0.245 (0.35 × 0.7),
8
+ * recede attr='true'
9
+ * 3. mouseleave: opacity returns to 0.35, recede='false'
10
+ * 4. source-side regex confirms multiplicative opacity + attr 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: [
38
+ mk('alpha·1'), mk('alpha·2'), mk('alpha·3'),
39
+ ] } });
40
+ });
41
+ // NO messages → flowLinks.length === 0 → crescent visible at opacity 0.35
42
+ await ctx.route('**/api/hub/messages*', (r) => r.fulfill({ json: { messages: [] } }));
43
+ await ctx.route('**/api/hub/tasks*', (r) => r.fulfill({ json: { tasks: [] } }));
44
+ const page = await ctx.newPage();
45
+ await page.goto('http://127.0.0.1:3000/', { waitUntil: 'networkidle' });
46
+ await page.waitForSelector('[data-topo-brand-canvas-mark]', { timeout: 15000 });
47
+ await page.waitForTimeout(800);
48
+
49
+ // Phase 1: rest
50
+ const rest = await page.evaluate(() => {
51
+ const m = document.querySelector('[data-topo-brand-canvas-mark]');
52
+ return {
53
+ opacity: parseFloat(m?.getAttribute('opacity') || '0'),
54
+ visible: m?.getAttribute('data-topo-brand-canvas-mark-visible'),
55
+ recede: m?.getAttribute('data-topo-brand-canvas-mark-recede'),
56
+ };
57
+ });
58
+
59
+ // Phase 2: hover legend `idle` row (sets hoveredStatus → recede)
60
+ await page.hover('[data-legend-row-label="idle"]');
61
+ await page.waitForTimeout(400);
62
+ const hover = await page.evaluate(() => {
63
+ const m = document.querySelector('[data-topo-brand-canvas-mark]');
64
+ return {
65
+ opacity: parseFloat(m?.getAttribute('opacity') || '0'),
66
+ visible: m?.getAttribute('data-topo-brand-canvas-mark-visible'),
67
+ recede: m?.getAttribute('data-topo-brand-canvas-mark-recede'),
68
+ };
69
+ });
70
+
71
+ // Phase 3: mouseleave
72
+ await page.mouse.move(900, 50);
73
+ await page.waitForTimeout(400);
74
+ const leave = await page.evaluate(() => {
75
+ const m = document.querySelector('[data-topo-brand-canvas-mark]');
76
+ return {
77
+ opacity: parseFloat(m?.getAttribute('opacity') || '0'),
78
+ recede: m?.getAttribute('data-topo-brand-canvas-mark-recede'),
79
+ };
80
+ });
81
+
82
+ await browser.close();
83
+
84
+ // Source regex
85
+ const src = readFileSync('/home/vansin/agent-network-dashboard/app/components/TopoGraph.tsx', 'utf8');
86
+ const sourceOpacityWired =
87
+ /opacity=\{\(flowLinks\.length === 0 \? 0\.35 : 0\) \* \(\s*\(hoveredAlias \|\| hoveredEdgeKey \|\| hoveredGroupLabel \|\|\s*hoveredStatus \|\| hoveredVendor\) && !hoveredHub \? 0\.7 : 1\s*\)\}/.test(src);
88
+ const sourceAttrWired =
89
+ /data-topo-brand-canvas-mark-recede=\{\s*\(hoveredAlias \|\| hoveredEdgeKey \|\| hoveredGroupLabel \|\|\s*hoveredStatus \|\| hoveredVendor\) && !hoveredHub \? 'true' : 'false'\s*\}/.test(src);
90
+
91
+ const approxEq = (a, b, tol = 0.001) => Math.abs(a - b) < tol;
92
+
93
+ const results = {
94
+ rest_opacity_035: approxEq(rest?.opacity, 0.35),
95
+ rest_visible_true: rest?.visible === 'true',
96
+ rest_recede_false: rest?.recede === 'false',
97
+ hover_opacity_0245: approxEq(hover?.opacity, 0.245),
98
+ hover_recede_true: hover?.recede === 'true',
99
+ hover_visible_still: hover?.visible === 'true', // crescent should still be visible
100
+ leave_opacity_035: approxEq(leave?.opacity, 0.35),
101
+ leave_recede_false: leave?.recede === 'false',
102
+ source_opacity_wired: sourceOpacityWired,
103
+ source_attr_wired: sourceAttrWired,
104
+ };
105
+ const ok = Object.values(results).every(Boolean);
106
+ console.log(`${ok ? '✅' : '❌'} R526 crescent focal-recede:`,
107
+ JSON.stringify(results, null, 2),
108
+ '\n rest:', JSON.stringify(rest),
109
+ '\n hover:', JSON.stringify(hover),
110
+ '\n leave:', JSON.stringify(leave));
111
+ process.exit(ok ? 0 : 1);
@@ -0,0 +1,73 @@
1
+ /* Round 691 — dense plain-text alias halo gate extends from hover-only
2
+ * (R680) to (hover || chat-target). Closes dense-mode + chat-target
3
+ * signaling parity at the per-node label scope — joins R616/R617/R645
4
+ * chat-target-gated brightness family.
5
+ *
6
+ * Source assertions:
7
+ * - dense alias halo-layers attr: (hoveredAlias || chatAlias) gate
8
+ * - dense alias filter: same OR-gate at status.primary tint 2+4
9
+ *
10
+ * Runtime assertions:
11
+ * - dense fleet renders (≥17 nodes → triggers dense fallback)
12
+ * - rest halo-layers='0' on all (no hover, no chat)
13
+ */
14
+ import { chromium } from 'playwright';
15
+ import { readFileSync } from 'node:fs';
16
+
17
+ const TOKEN = JSON.parse(readFileSync('/home/vansin/.anet/config.json', 'utf8')).token;
18
+ const fresh = new Date(Date.now() - 60 * 1000).toISOString();
19
+
20
+ const browser = await chromium.launch({ headless: true });
21
+ const ctx = await browser.newContext({ viewport: { width: 1500, height: 1200 } });
22
+ await ctx.addCookies([{ name: 'anet_dashboard_session', value: `v3:${TOKEN}`, domain: '127.0.0.1', path: '/' }]);
23
+ await ctx.addInitScript(() => {
24
+ try {
25
+ localStorage.setItem('anet-theme', 'cyber');
26
+ localStorage.setItem('anet-topo-layout', 'ring');
27
+ sessionStorage.setItem('anet_v3_auth', '1');
28
+ } catch {}
29
+ });
30
+ await ctx.route('**/api/hub/status*', async (route) => {
31
+ const r = await route.fetch();
32
+ const b = await r.json();
33
+ const nid = (b.sessions || [])[0]?.network_id || 'default';
34
+ const mk = (alias) => ({
35
+ alias, status: 'idle', model: 'claude-opus-4', runtime: 'claude-code-cli',
36
+ network_id: nid, project_dir: null,
37
+ created_at: fresh, updated_at: fresh, last_seen_at: fresh,
38
+ });
39
+ // 18 nodes → dense fallback (>16)
40
+ await route.fulfill({ response: r, json: { ...b, sessions: Array.from({ length: 18 }, (_, i) => mk(`a·${i + 1}`)) } });
41
+ });
42
+ await ctx.route('**/api/hub/messages*', (r) => r.fulfill({ json: { messages: [] } }));
43
+ await ctx.route('**/api/hub/tasks*', (r) => r.fulfill({ json: { tasks: [] } }));
44
+ const page = await ctx.newPage();
45
+ await page.goto('http://127.0.0.1:3000/', { waitUntil: 'networkidle' });
46
+ await page.waitForSelector('[data-node-dense-alias-text]', { timeout: 15000, state: 'attached' });
47
+ await page.waitForTimeout(300);
48
+
49
+ const runtimeState = await page.evaluate(() => {
50
+ const labels = Array.from(document.querySelectorAll('[data-node-dense-alias-text]'));
51
+ return {
52
+ count: labels.length,
53
+ all_layers_zero: labels.every(el => el.getAttribute('data-node-dense-alias-text-halo-layers') === '0'),
54
+ };
55
+ });
56
+
57
+ await browser.close();
58
+
59
+ const src = readFileSync('/home/vansin/agent-network-dashboard/app/components/TopoGraph.tsx', 'utf8');
60
+ const sourceAttrGate = /data-node-dense-alias-text-halo-layers=\{\(hoveredAlias === session\.alias \|\| chatAlias === session\.alias\) \? '2' : '0'\}/.test(src);
61
+ const sourceFilterGate = /filter: \(hoveredAlias === session\.alias \|\| chatAlias === session\.alias\)\s*\?\s*`drop-shadow\(0 0 2px \$\{status\.primary\}80\) drop-shadow\(0 0 4px \$\{status\.primary\}40\)`/.test(src);
62
+
63
+ const results = {
64
+ dense_labels_present: runtimeState.count >= 10,
65
+ rest_all_layers_zero: runtimeState.all_layers_zero,
66
+ source_attr_gate: sourceAttrGate,
67
+ source_filter_gate: sourceFilterGate,
68
+ };
69
+ const ok = Object.values(results).every(Boolean);
70
+ console.log(`${ok ? '✅' : '❌'} R691 dense alias chat-target-gated halo (closes dense-mode chat signaling):`,
71
+ JSON.stringify(results, null, 2),
72
+ `\n runtime: ${runtimeState.count} dense labels rendered`);
73
+ process.exit(ok ? 0 : 1);
@@ -0,0 +1,80 @@
1
+ /* Round 680 — dense plain-text alias (the >16-node fallback label)
2
+ * extends from group-hover:-translate-y geometry-only to 2-layer
3
+ * drop-shadow at status.primary tint with 2+4 stride, alpha 80/40.
4
+ * Closes the dense-mode alias hover signature parity with normal-
5
+ * mode card label (R645). 39th anchor in family — first dense-mode
6
+ * anchor.
7
+ *
8
+ * Source assertions:
9
+ * - filter uses status.primary at 0x80 + 0x40 with 2+4 stride,
10
+ * gated on hoveredAlias === session.alias
11
+ * - data-node-dense-alias-text-halo-layers attr toggles '2' ↔ '0'
12
+ * - transition extends with 'filter 200ms ease-out'
13
+ *
14
+ * Runtime assertions:
15
+ * - dense alias labels present (>16 nodes)
16
+ * - all rest: halo-layers='0'
17
+ */
18
+ import { chromium } from 'playwright';
19
+ import { readFileSync } from 'node:fs';
20
+
21
+ const TOKEN = JSON.parse(readFileSync('/home/vansin/.anet/config.json', 'utf8')).token;
22
+ const fresh = new Date(Date.now() - 60 * 1000).toISOString();
23
+
24
+ const browser = await chromium.launch({ headless: true });
25
+ const ctx = await browser.newContext({ viewport: { width: 1500, height: 1200 } });
26
+ await ctx.addCookies([{ name: 'anet_dashboard_session', value: `v3:${TOKEN}`, domain: '127.0.0.1', path: '/' }]);
27
+ await ctx.addInitScript(() => {
28
+ try {
29
+ localStorage.setItem('anet-theme', 'cyber');
30
+ localStorage.setItem('anet-topo-layout', 'ring');
31
+ sessionStorage.setItem('anet_v3_auth', '1');
32
+ } catch {}
33
+ });
34
+ await ctx.route('**/api/hub/status*', async (route) => {
35
+ const r = await route.fetch();
36
+ const b = await r.json();
37
+ const nid = (b.sessions || [])[0]?.network_id || 'default';
38
+ const mk = (alias) => ({
39
+ alias, status: 'idle', model: 'claude-opus-4', runtime: 'claude-code-cli',
40
+ network_id: nid, project_dir: null,
41
+ created_at: fresh, updated_at: fresh, last_seen_at: fresh,
42
+ });
43
+ // 18 nodes triggers dense fallback (>16 nodes)
44
+ await route.fulfill({ response: r, json: { ...b, sessions: Array.from({ length: 18 }, (_, i) => mk(`a·${i + 1}`)) } });
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-dense-alias-text-halo-layers]', { timeout: 15000, state: 'attached' });
51
+ await page.waitForTimeout(500);
52
+
53
+ const restState = await page.evaluate(() => {
54
+ return Array.from(document.querySelectorAll('[data-node-dense-alias-text]')).map(el => ({
55
+ alias: el.getAttribute('data-node-dense-alias-text'),
56
+ layers: el.getAttribute('data-node-dense-alias-text-halo-layers'),
57
+ }));
58
+ });
59
+
60
+ await browser.close();
61
+
62
+ const src = readFileSync('/home/vansin/agent-network-dashboard/app/components/TopoGraph.tsx', 'utf8');
63
+ const sourceFilter = /filter: hoveredAlias === session\.alias\s*\?\s*`drop-shadow\(0 0 2px \$\{status\.primary\}80\) drop-shadow\(0 0 4px \$\{status\.primary\}40\)`/.test(src);
64
+ const sourceLayersAttr = /data-node-dense-alias-text-halo-layers=\{hoveredAlias === session\.alias \? '2' : '0'\}/.test(src);
65
+ const sourceTransition = /transition: 'transform 200ms ease-out, fill 300ms ease-out, filter 200ms ease-out'/.test(src);
66
+
67
+ const restAllZero = restState.every(e => e.layers === '0');
68
+
69
+ const results = {
70
+ dense_aliases_present: restState.length >= 10, // 18 nodes should yield ~18 dense labels
71
+ rest_all_layers_zero: restAllZero,
72
+ source_filter: sourceFilter,
73
+ source_layers_attr: sourceLayersAttr,
74
+ source_transition: sourceTransition,
75
+ };
76
+ const ok = Object.values(results).every(Boolean);
77
+ console.log(`${ok ? '✅' : '❌'} R680 dense plain-text alias multi-layer halo (first dense-mode anchor):`,
78
+ JSON.stringify(results, null, 2),
79
+ `\n count: ${restState.length}, sample: ${JSON.stringify(restState.slice(0, 3))}`);
80
+ process.exit(ok ? 0 : 1);