@sleep2agi/agent-network-dashboard 0.5.3 → 0.5.4

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 (484) hide show
  1. package/.next/BUILD_ID +1 -1
  2. package/.next/app-path-routes-manifest.json +2 -0
  3. package/.next/build-manifest.json +3 -3
  4. package/.next/diagnostics/route-bundle-stats.json +35 -35
  5. package/.next/fallback-build-manifest.json +3 -3
  6. package/.next/prerender-manifest.json +29 -0
  7. package/.next/routes-manifest.json +12 -0
  8. package/.next/server/app/_global-error.html +1 -1
  9. package/.next/server/app/_global-error.rsc +2 -2
  10. package/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  11. package/.next/server/app/_global-error.segments/_full.segment.rsc +2 -2
  12. package/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  13. package/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  14. package/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  15. package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  16. package/.next/server/app/_not-found.html +2 -2
  17. package/.next/server/app/_not-found.rsc +13 -13
  18. package/.next/server/app/_not-found.segments/_full.segment.rsc +13 -13
  19. package/.next/server/app/_not-found.segments/_head.segment.rsc +4 -4
  20. package/.next/server/app/_not-found.segments/_index.segment.rsc +7 -7
  21. package/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +2 -2
  22. package/.next/server/app/_not-found.segments/_not-found.segment.rsc +3 -3
  23. package/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  24. package/.next/server/app/admin/page_client-reference-manifest.js +1 -1
  25. package/.next/server/app/admin.html +2 -2
  26. package/.next/server/app/admin.rsc +15 -15
  27. package/.next/server/app/admin.segments/_full.segment.rsc +15 -15
  28. package/.next/server/app/admin.segments/_head.segment.rsc +4 -4
  29. package/.next/server/app/admin.segments/_index.segment.rsc +7 -7
  30. package/.next/server/app/admin.segments/_tree.segment.rsc +2 -2
  31. package/.next/server/app/admin.segments/admin/__PAGE__.segment.rsc +4 -4
  32. package/.next/server/app/admin.segments/admin.segment.rsc +3 -3
  33. package/.next/server/app/api/hub/upload/route/app-paths-manifest.json +3 -0
  34. package/.next/server/app/api/hub/upload/route/build-manifest.json +9 -0
  35. package/.next/server/app/api/hub/upload/route/server-reference-manifest.json +4 -0
  36. package/.next/server/app/api/hub/upload/route.js +7 -0
  37. package/.next/server/app/api/hub/upload/route.js.map +5 -0
  38. package/.next/server/app/api/hub/upload/route.js.nft.json +1 -0
  39. package/.next/server/app/api/hub/upload/route_client-reference-manifest.js +3 -0
  40. package/.next/server/app/index.html +2 -2
  41. package/.next/server/app/index.rsc +15 -15
  42. package/.next/server/app/index.segments/__PAGE__.segment.rsc +4 -4
  43. package/.next/server/app/index.segments/_full.segment.rsc +15 -15
  44. package/.next/server/app/index.segments/_head.segment.rsc +4 -4
  45. package/.next/server/app/index.segments/_index.segment.rsc +7 -7
  46. package/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  47. package/.next/server/app/login/page_client-reference-manifest.js +1 -1
  48. package/.next/server/app/login.html +2 -2
  49. package/.next/server/app/login.rsc +15 -15
  50. package/.next/server/app/login.segments/_full.segment.rsc +15 -15
  51. package/.next/server/app/login.segments/_head.segment.rsc +4 -4
  52. package/.next/server/app/login.segments/_index.segment.rsc +7 -7
  53. package/.next/server/app/login.segments/_tree.segment.rsc +2 -2
  54. package/.next/server/app/login.segments/login/__PAGE__.segment.rsc +4 -4
  55. package/.next/server/app/login.segments/login.segment.rsc +3 -3
  56. package/.next/server/app/logs/page_client-reference-manifest.js +1 -1
  57. package/.next/server/app/logs.html +2 -2
  58. package/.next/server/app/logs.rsc +15 -15
  59. package/.next/server/app/logs.segments/_full.segment.rsc +15 -15
  60. package/.next/server/app/logs.segments/_head.segment.rsc +4 -4
  61. package/.next/server/app/logs.segments/_index.segment.rsc +7 -7
  62. package/.next/server/app/logs.segments/_tree.segment.rsc +2 -2
  63. package/.next/server/app/logs.segments/logs/__PAGE__.segment.rsc +4 -4
  64. package/.next/server/app/logs.segments/logs.segment.rsc +3 -3
  65. package/.next/server/app/manifest.webmanifest/route/app-paths-manifest.json +3 -0
  66. package/.next/server/app/manifest.webmanifest/route/build-manifest.json +9 -0
  67. package/.next/server/app/manifest.webmanifest/route/server-reference-manifest.json +4 -0
  68. package/.next/server/app/manifest.webmanifest/route.js +8 -0
  69. package/.next/server/app/manifest.webmanifest/route.js.map +5 -0
  70. package/.next/server/app/manifest.webmanifest/route.js.nft.json +1 -0
  71. package/.next/server/app/manifest.webmanifest/route_client-reference-manifest.js +3 -0
  72. package/.next/server/app/manifest.webmanifest.body +1 -0
  73. package/.next/server/app/manifest.webmanifest.meta +1 -0
  74. package/.next/server/app/messages/page_client-reference-manifest.js +1 -1
  75. package/.next/server/app/messages.html +2 -2
  76. package/.next/server/app/messages.rsc +15 -15
  77. package/.next/server/app/messages.segments/_full.segment.rsc +15 -15
  78. package/.next/server/app/messages.segments/_head.segment.rsc +4 -4
  79. package/.next/server/app/messages.segments/_index.segment.rsc +7 -7
  80. package/.next/server/app/messages.segments/_tree.segment.rsc +2 -2
  81. package/.next/server/app/messages.segments/messages/__PAGE__.segment.rsc +4 -4
  82. package/.next/server/app/messages.segments/messages.segment.rsc +3 -3
  83. package/.next/server/app/node/page_client-reference-manifest.js +1 -1
  84. package/.next/server/app/node.html +2 -2
  85. package/.next/server/app/node.rsc +15 -15
  86. package/.next/server/app/node.segments/_full.segment.rsc +15 -15
  87. package/.next/server/app/node.segments/_head.segment.rsc +4 -4
  88. package/.next/server/app/node.segments/_index.segment.rsc +7 -7
  89. package/.next/server/app/node.segments/_tree.segment.rsc +2 -2
  90. package/.next/server/app/node.segments/node/__PAGE__.segment.rsc +4 -4
  91. package/.next/server/app/node.segments/node.segment.rsc +3 -3
  92. package/.next/server/app/nodes/page_client-reference-manifest.js +1 -1
  93. package/.next/server/app/nodes.html +2 -2
  94. package/.next/server/app/nodes.rsc +15 -15
  95. package/.next/server/app/nodes.segments/_full.segment.rsc +15 -15
  96. package/.next/server/app/nodes.segments/_head.segment.rsc +4 -4
  97. package/.next/server/app/nodes.segments/_index.segment.rsc +7 -7
  98. package/.next/server/app/nodes.segments/_tree.segment.rsc +2 -2
  99. package/.next/server/app/nodes.segments/nodes/__PAGE__.segment.rsc +4 -4
  100. package/.next/server/app/nodes.segments/nodes.segment.rsc +3 -3
  101. package/.next/server/app/page_client-reference-manifest.js +1 -1
  102. package/.next/server/app/server-logs/page_client-reference-manifest.js +1 -1
  103. package/.next/server/app/server-logs.html +2 -2
  104. package/.next/server/app/server-logs.rsc +15 -15
  105. package/.next/server/app/server-logs.segments/_full.segment.rsc +15 -15
  106. package/.next/server/app/server-logs.segments/_head.segment.rsc +4 -4
  107. package/.next/server/app/server-logs.segments/_index.segment.rsc +7 -7
  108. package/.next/server/app/server-logs.segments/_tree.segment.rsc +2 -2
  109. package/.next/server/app/server-logs.segments/server-logs/__PAGE__.segment.rsc +4 -4
  110. package/.next/server/app/server-logs.segments/server-logs.segment.rsc +3 -3
  111. package/.next/server/app/settings/networks/page_client-reference-manifest.js +1 -1
  112. package/.next/server/app/settings/networks.html +2 -2
  113. package/.next/server/app/settings/networks.rsc +15 -15
  114. package/.next/server/app/settings/networks.segments/_full.segment.rsc +15 -15
  115. package/.next/server/app/settings/networks.segments/_head.segment.rsc +4 -4
  116. package/.next/server/app/settings/networks.segments/_index.segment.rsc +7 -7
  117. package/.next/server/app/settings/networks.segments/_tree.segment.rsc +2 -2
  118. package/.next/server/app/settings/networks.segments/settings/networks/__PAGE__.segment.rsc +4 -4
  119. package/.next/server/app/settings/networks.segments/settings/networks.segment.rsc +3 -3
  120. package/.next/server/app/settings/networks.segments/settings.segment.rsc +3 -3
  121. package/.next/server/app/settings/page_client-reference-manifest.js +1 -1
  122. package/.next/server/app/settings/tokens/page_client-reference-manifest.js +1 -1
  123. package/.next/server/app/settings/tokens.html +2 -2
  124. package/.next/server/app/settings/tokens.rsc +15 -15
  125. package/.next/server/app/settings/tokens.segments/_full.segment.rsc +15 -15
  126. package/.next/server/app/settings/tokens.segments/_head.segment.rsc +4 -4
  127. package/.next/server/app/settings/tokens.segments/_index.segment.rsc +7 -7
  128. package/.next/server/app/settings/tokens.segments/_tree.segment.rsc +2 -2
  129. package/.next/server/app/settings/tokens.segments/settings/tokens/__PAGE__.segment.rsc +4 -4
  130. package/.next/server/app/settings/tokens.segments/settings/tokens.segment.rsc +3 -3
  131. package/.next/server/app/settings/tokens.segments/settings.segment.rsc +3 -3
  132. package/.next/server/app/settings.html +2 -2
  133. package/.next/server/app/settings.rsc +15 -15
  134. package/.next/server/app/settings.segments/_full.segment.rsc +15 -15
  135. package/.next/server/app/settings.segments/_head.segment.rsc +4 -4
  136. package/.next/server/app/settings.segments/_index.segment.rsc +7 -7
  137. package/.next/server/app/settings.segments/_tree.segment.rsc +2 -2
  138. package/.next/server/app/settings.segments/settings/__PAGE__.segment.rsc +4 -4
  139. package/.next/server/app/settings.segments/settings.segment.rsc +3 -3
  140. package/.next/server/app/tasks/[id]/page_client-reference-manifest.js +1 -1
  141. package/.next/server/app/tasks/page_client-reference-manifest.js +1 -1
  142. package/.next/server/app/tasks.html +2 -2
  143. package/.next/server/app/tasks.rsc +15 -15
  144. package/.next/server/app/tasks.segments/_full.segment.rsc +15 -15
  145. package/.next/server/app/tasks.segments/_head.segment.rsc +4 -4
  146. package/.next/server/app/tasks.segments/_index.segment.rsc +7 -7
  147. package/.next/server/app/tasks.segments/_tree.segment.rsc +2 -2
  148. package/.next/server/app/tasks.segments/tasks/__PAGE__.segment.rsc +4 -4
  149. package/.next/server/app/tasks.segments/tasks.segment.rsc +3 -3
  150. package/.next/server/app-paths-manifest.json +2 -0
  151. package/.next/server/chunks/00jm_next_dist_0ju_ux9._.js +18 -0
  152. package/.next/server/chunks/00jm_next_dist_0ju_ux9._.js.map +1 -0
  153. package/.next/server/chunks/0ykm__next-internal_server_app_api_hub_upload_route_actions_03_eqnf.js +3 -0
  154. package/.next/server/chunks/0ykm__next-internal_server_app_manifest_webmanifest_route_actions_0m16rb8.js +3 -0
  155. package/.next/server/chunks/0ykm__next-internal_server_app_manifest_webmanifest_route_actions_0m16rb8.js.map +1 -0
  156. package/.next/server/chunks/{[externals]__11vad82._.js → [externals]__036g1.i._.js} +2 -2
  157. package/.next/server/chunks/[externals]__036g1.i._.js.map +1 -0
  158. package/.next/server/chunks/[root-of-the-server]__0-8_f0o._.js +3 -0
  159. package/.next/server/chunks/[root-of-the-server]__0-8_f0o._.js.map +1 -0
  160. package/.next/server/chunks/{[root-of-the-server]__08uyvdq._.js → [root-of-the-server]__0jndzts._.js} +2 -2
  161. package/.next/server/chunks/{[root-of-the-server]__08uyvdq._.js.map → [root-of-the-server]__0jndzts._.js.map} +1 -1
  162. package/.next/server/chunks/[root-of-the-server]__0mxw4vb._.js +1 -1
  163. package/.next/server/chunks/[root-of-the-server]__0mxw4vb._.js.map +1 -1
  164. package/.next/server/chunks/[root-of-the-server]__0tx8s8i._.js +1 -1
  165. package/.next/server/chunks/[root-of-the-server]__0tx8s8i._.js.map +1 -1
  166. package/.next/server/chunks/ssr/00jm_next_dist_esm_build_templates_app-page_0..ddwm.js +1 -1
  167. package/.next/server/chunks/ssr/00jm_next_dist_esm_build_templates_app-page_0..ddwm.js.map +1 -1
  168. package/.next/server/chunks/ssr/00jm_next_dist_esm_build_templates_app-page_02bxi6j.js +1 -1
  169. package/.next/server/chunks/ssr/00jm_next_dist_esm_build_templates_app-page_02bxi6j.js.map +1 -1
  170. package/.next/server/chunks/ssr/00jm_next_dist_esm_build_templates_app-page_05oassd.js +1 -1
  171. package/.next/server/chunks/ssr/00jm_next_dist_esm_build_templates_app-page_05oassd.js.map +1 -1
  172. package/.next/server/chunks/ssr/00jm_next_dist_esm_build_templates_app-page_05vxtby.js +1 -1
  173. package/.next/server/chunks/ssr/00jm_next_dist_esm_build_templates_app-page_05vxtby.js.map +1 -1
  174. package/.next/server/chunks/ssr/00jm_next_dist_esm_build_templates_app-page_05~eml4.js +1 -1
  175. package/.next/server/chunks/ssr/00jm_next_dist_esm_build_templates_app-page_05~eml4.js.map +1 -1
  176. package/.next/server/chunks/ssr/00jm_next_dist_esm_build_templates_app-page_0_-g_q2.js +1 -1
  177. package/.next/server/chunks/ssr/00jm_next_dist_esm_build_templates_app-page_0_-g_q2.js.map +1 -1
  178. package/.next/server/chunks/ssr/00jm_next_dist_esm_build_templates_app-page_0_ec0xu.js +1 -1
  179. package/.next/server/chunks/ssr/00jm_next_dist_esm_build_templates_app-page_0_ec0xu.js.map +1 -1
  180. package/.next/server/chunks/ssr/00jm_next_dist_esm_build_templates_app-page_0czb6wz.js +1 -1
  181. package/.next/server/chunks/ssr/00jm_next_dist_esm_build_templates_app-page_0czb6wz.js.map +1 -1
  182. package/.next/server/chunks/ssr/00jm_next_dist_esm_build_templates_app-page_0e-cn.p.js +1 -1
  183. package/.next/server/chunks/ssr/00jm_next_dist_esm_build_templates_app-page_0e-cn.p.js.map +1 -1
  184. package/.next/server/chunks/ssr/00jm_next_dist_esm_build_templates_app-page_0k8_sr8.js +1 -1
  185. package/.next/server/chunks/ssr/00jm_next_dist_esm_build_templates_app-page_0k8_sr8.js.map +1 -1
  186. package/.next/server/chunks/ssr/00jm_next_dist_esm_build_templates_app-page_0lt_3bw.js +1 -1
  187. package/.next/server/chunks/ssr/00jm_next_dist_esm_build_templates_app-page_0lt_3bw.js.map +1 -1
  188. package/.next/server/chunks/ssr/00jm_next_dist_esm_build_templates_app-page_0uyh3yt.js +1 -1
  189. package/.next/server/chunks/ssr/00jm_next_dist_esm_build_templates_app-page_0uyh3yt.js.map +1 -1
  190. package/.next/server/chunks/ssr/00jm_next_dist_esm_build_templates_app-page_0v-a2ps.js +1 -1
  191. package/.next/server/chunks/ssr/00jm_next_dist_esm_build_templates_app-page_0v-a2ps.js.map +1 -1
  192. package/.next/server/chunks/ssr/00jm_next_dist_esm_build_templates_app-page_12.4r9~.js +1 -1
  193. package/.next/server/chunks/ssr/00jm_next_dist_esm_build_templates_app-page_12.4r9~.js.map +1 -1
  194. package/.next/server/chunks/ssr/00jm_next_dist_esm_build_templates_app-page_13mqkay.js +1 -1
  195. package/.next/server/chunks/ssr/00jm_next_dist_esm_build_templates_app-page_13mqkay.js.map +1 -1
  196. package/.next/server/chunks/ssr/[root-of-the-server]__030vg4n._.js +4 -1
  197. package/.next/server/chunks/ssr/[root-of-the-server]__030vg4n._.js.map +1 -1
  198. package/.next/server/chunks/ssr/[root-of-the-server]__0sv~g.o._.js +1 -1
  199. package/.next/server/chunks/ssr/[root-of-the-server]__0sv~g.o._.js.map +1 -1
  200. package/.next/server/chunks/ssr/[root-of-the-server]__0u5aqkk._.js +1 -1
  201. package/.next/server/chunks/ssr/[root-of-the-server]__0u5aqkk._.js.map +1 -1
  202. package/.next/server/chunks/ssr/agent-network-dashboard_09kk21a._.js +4 -4
  203. package/.next/server/chunks/ssr/agent-network-dashboard_09kk21a._.js.map +1 -1
  204. package/.next/server/chunks/ssr/agent-network-dashboard_app_01jhlxz._.js +1 -1
  205. package/.next/server/chunks/ssr/agent-network-dashboard_app_01jhlxz._.js.map +1 -1
  206. package/.next/server/chunks/ssr/agent-network-dashboard_app_09d29my._.js +1 -1
  207. package/.next/server/chunks/ssr/agent-network-dashboard_app_09d29my._.js.map +1 -1
  208. package/.next/server/chunks/ssr/agent-network-dashboard_app_components_0mvyi-4._.js +1 -1
  209. package/.next/server/chunks/ssr/agent-network-dashboard_app_components_0mvyi-4._.js.map +1 -1
  210. package/.next/server/middleware-build-manifest.js +3 -3
  211. package/.next/server/middleware.js +2 -2
  212. package/.next/server/middleware.js.nft.json +1 -1
  213. package/.next/server/pages/404.html +2 -2
  214. package/.next/server/pages/500.html +1 -1
  215. package/.next/static/chunks/{07~8sx3_5uiox.js → 04wjx7vbxusw5.js} +4 -1
  216. package/.next/static/chunks/089t1exs6apb8.js +4 -0
  217. package/.next/static/chunks/{0ph1in3421~o-.js → 09e8kxo30n5cf.js} +1 -1
  218. package/.next/static/chunks/{0v4-5tng.uh.7.js → 0k-c1chkvf78s.js} +2 -2
  219. package/.next/static/chunks/0v2~nlpk-cx6v.css +2 -0
  220. package/.next/static/chunks/0xsye-9kffdi0.js +1 -0
  221. package/.next/static/chunks/0~rx_~akeylmq.js +1 -0
  222. package/.next/trace +2 -2
  223. package/.next/trace-build +1 -1
  224. package/.next/types/routes.d.ts +2 -1
  225. package/.next/types/validator.ts +9 -0
  226. package/app/api/hub/send/route.ts +11 -2
  227. package/app/api/hub/servers/route.ts +3 -29
  228. package/app/api/hub/upload/route.ts +83 -0
  229. package/app/components/AppShell.tsx +3 -1
  230. package/app/components/MobileNav.tsx +45 -0
  231. package/app/components/TaskChatPanel.tsx +130 -6
  232. package/app/components/TopoGraph.tsx +6686 -248
  233. package/app/globals.css +897 -7
  234. package/app/layout.tsx +6 -0
  235. package/app/lib/serverDedupe.ts +122 -0
  236. package/app/lib/vendorIdentity.ts +74 -56
  237. package/app/manifest.ts +23 -0
  238. package/package.json +4 -4
  239. package/public/vendors/claude.svg +7 -8
  240. package/public/vendors/minimax.svg +8 -9
  241. package/public/vendors/openai.svg +8 -10
  242. package/scripts/p157-rc2-dedup-test.mjs +110 -0
  243. package/scripts/topo-a11y-titles-catalog-test.mjs +132 -0
  244. package/scripts/topo-active-chrome-hover-text-test.mjs +107 -0
  245. package/scripts/topo-active-links-chip-halo-layers-test.mjs +81 -0
  246. package/scripts/topo-alias-chat-brightness-test.mjs +79 -0
  247. package/scripts/topo-alias-text-halo-layers-test.mjs +98 -0
  248. package/scripts/topo-animation-temporal-modes-catalog-test.mjs +144 -0
  249. package/scripts/topo-avatar-chat-gate-test.mjs +77 -0
  250. package/scripts/topo-avatar-drop-shadow-test.mjs +86 -0
  251. package/scripts/topo-avatar-fallback-hover-test.mjs +104 -0
  252. package/scripts/topo-avatar-fallback-rotate-test.mjs +92 -0
  253. package/scripts/topo-avatar-rotate-test.mjs +85 -0
  254. package/scripts/topo-avatar-scale-test.mjs +89 -0
  255. package/scripts/topo-badge-chat-gate-test.mjs +74 -0
  256. package/scripts/topo-brand-drop-shadow-test.mjs +71 -0
  257. package/scripts/topo-brand-logo-breath-test.mjs +102 -0
  258. package/scripts/topo-brand-logo-halo-layers-test.mjs +85 -0
  259. package/scripts/topo-brand-logo-hover-brightness-test.mjs +105 -0
  260. package/scripts/topo-brand-logo-hover-rotate-test.mjs +93 -0
  261. package/scripts/topo-brand-logo-hover-test.mjs +85 -0
  262. package/scripts/topo-canvas-desc-a11y-test.mjs +87 -0
  263. package/scripts/topo-canvas-entrance-animation-test.mjs +117 -0
  264. package/scripts/topo-canvas-scan-beam-diagonal-test.mjs +148 -0
  265. package/scripts/topo-canvas-scan-beam-test.mjs +109 -0
  266. package/scripts/topo-canvas-scan-beam-vertical-test.mjs +123 -0
  267. package/scripts/topo-card-chat-brightness-test.mjs +86 -0
  268. package/scripts/topo-chat-ring-breath-curve-test.mjs +114 -0
  269. package/scripts/topo-chat-ring-brightness-test.mjs +80 -0
  270. package/scripts/topo-chat-ring-halo-layers-test.mjs +100 -0
  271. package/scripts/topo-chat-ring-r-breath-test.mjs +121 -0
  272. package/scripts/topo-chat-ring-status-halo-test.mjs +106 -0
  273. package/scripts/topo-chat-ring-sw-breath-test.mjs +123 -0
  274. package/scripts/topo-chip-pin-halo-test.mjs +85 -0
  275. package/scripts/topo-chip-row-digit-ls-test.mjs +135 -0
  276. package/scripts/topo-chip-row-member-alias-lit-test.mjs +154 -0
  277. package/scripts/topo-chip-row-tier-glow-brightness-test.mjs +99 -0
  278. package/scripts/topo-chip-row-unit-hover-tracking-test.mjs +124 -0
  279. package/scripts/topo-chrome-control-halo-layers-test.mjs +22 -0
  280. package/scripts/topo-chrome-fullscreen-breath-test.mjs +121 -0
  281. package/scripts/topo-chrome-layout-trailer-breath-test.mjs +86 -0
  282. package/scripts/topo-chrome-nodesize-trailer-breath-test.mjs +86 -0
  283. package/scripts/topo-chrome-reset-breath-test.mjs +115 -0
  284. package/scripts/topo-chrome-strip-entrance-animation-test.mjs +115 -0
  285. package/scripts/topo-chrome-wrapper-halo-test.mjs +83 -0
  286. package/scripts/topo-chrome-zoom-wrapper-breath-test.mjs +85 -0
  287. package/scripts/topo-click-ripple-glow-test.mjs +86 -0
  288. package/scripts/topo-click-ripple-halo-layers-test.mjs +79 -0
  289. package/scripts/topo-click-ripple-sw-test.mjs +110 -0
  290. package/scripts/topo-cluster-count-attr-test.mjs +80 -0
  291. package/scripts/topo-crescent-breath-test.mjs +104 -0
  292. package/scripts/topo-crescent-envelope-breath-test.mjs +103 -0
  293. package/scripts/topo-crescent-recede-test.mjs +111 -0
  294. package/scripts/topo-dense-alias-chat-halo-test.mjs +73 -0
  295. package/scripts/topo-dense-alias-halo-layers-test.mjs +80 -0
  296. package/scripts/topo-dual-axis-surfaces-catalog-test.mjs +94 -0
  297. package/scripts/topo-edge-badge-circle-brightness-test.mjs +82 -0
  298. package/scripts/topo-edge-badge-circle-hot-pulse-test.mjs +100 -0
  299. package/scripts/topo-edge-badge-digit-halo-layers-test.mjs +107 -0
  300. package/scripts/topo-edge-badge-endpoint-gate-test.mjs +94 -0
  301. package/scripts/topo-edge-badge-halo-layers-test.mjs +85 -0
  302. package/scripts/topo-edge-badge-hot-pulse-test.mjs +92 -0
  303. package/scripts/topo-edge-badge-hover-glow-test.mjs +90 -0
  304. package/scripts/topo-edge-badge-text-brightness-test.mjs +83 -0
  305. package/scripts/topo-edge-chat-gate-test.mjs +71 -0
  306. package/scripts/topo-edge-flow-rail-halo-layers-test.mjs +89 -0
  307. package/scripts/topo-edge-particle-brightness-test.mjs +82 -0
  308. package/scripts/topo-edge-particle-halo-layers-test.mjs +91 -0
  309. package/scripts/topo-edge-pill-glow-test.mjs +67 -0
  310. package/scripts/topo-edge-pin-halo-test.mjs +99 -0
  311. package/scripts/topo-edge-visible-brightness-test.mjs +84 -0
  312. package/scripts/topo-edge-visible-halo-layers-test.mjs +87 -0
  313. package/scripts/topo-endpoint-ring-brightness-test.mjs +83 -0
  314. package/scripts/topo-endpoint-ring-flow-halo-test.mjs +107 -0
  315. package/scripts/topo-endpoint-ring-halo-layers-test.mjs +100 -0
  316. package/scripts/topo-filter-pill-glow-test.mjs +90 -0
  317. package/scripts/topo-filter-pill-halo-layers-test.mjs +27 -0
  318. package/scripts/topo-flow-arrow-brightness-test.mjs +82 -0
  319. package/scripts/topo-flow-rail-brightness-test.mjs +80 -0
  320. package/scripts/topo-fullscreen-attr-test.mjs +73 -0
  321. package/scripts/topo-fullscreen-brightness-test.mjs +84 -0
  322. package/scripts/topo-fullscreen-icon-rotate-test.mjs +93 -0
  323. package/scripts/topo-grid-content-bottom-attr-test.mjs +72 -0
  324. package/scripts/topo-group-box-brightness-test.mjs +84 -0
  325. package/scripts/topo-group-box-halo-layers-test.mjs +91 -0
  326. package/scripts/topo-group-chat-gate-test.mjs +77 -0
  327. package/scripts/topo-group-label-brightness-test.mjs +84 -0
  328. package/scripts/topo-group-label-halo-layers-test.mjs +78 -0
  329. package/scripts/topo-group-label-hover-glow-test.mjs +86 -0
  330. package/scripts/topo-group-label-member-alias-hover-test.mjs +125 -0
  331. package/scripts/topo-group-pill-glow-test.mjs +76 -0
  332. package/scripts/topo-group-tint-brightness-test.mjs +82 -0
  333. package/scripts/topo-h2-dual-axis-breath-test.mjs +92 -0
  334. package/scripts/topo-h2-triple-axis-breath-test.mjs +142 -0
  335. package/scripts/topo-halo-chat-gate-test.mjs +72 -0
  336. package/scripts/topo-hover-detail-halo-test.mjs +76 -0
  337. package/scripts/topo-hub-a11y-title-test.mjs +95 -0
  338. package/scripts/topo-hub-core-brightness-test.mjs +82 -0
  339. package/scripts/topo-hub-core-halo-layers-test.mjs +81 -0
  340. package/scripts/topo-hub-digit-brightness-test.mjs +79 -0
  341. package/scripts/topo-hub-digit-halo-layers-test.mjs +76 -0
  342. package/scripts/topo-hub-digit-ls-test.mjs +119 -0
  343. package/scripts/topo-hub-halo-brightness-test.mjs +80 -0
  344. package/scripts/topo-hub-halo-glow-test.mjs +96 -0
  345. package/scripts/topo-hub-halo-halo-layers-test.mjs +76 -0
  346. package/scripts/topo-hub-highlight-brightness-test.mjs +84 -0
  347. package/scripts/topo-hub-highlight-glow-test.mjs +99 -0
  348. package/scripts/topo-hub-highlight-halo-layers-test.mjs +78 -0
  349. package/scripts/topo-hub-highlight-r-test.mjs +112 -0
  350. package/scripts/topo-hub-hover-ring-brightness-test.mjs +79 -0
  351. package/scripts/topo-hub-hover-ring-glow-test.mjs +97 -0
  352. package/scripts/topo-hub-hover-ring-halo-layers-test.mjs +71 -0
  353. package/scripts/topo-hub-spoke-brightness-test.mjs +77 -0
  354. package/scripts/topo-hub-spoke-glow-test.mjs +112 -0
  355. package/scripts/topo-hub-spoke-halo-layers-test.mjs +97 -0
  356. package/scripts/topo-hub-spoke-self-filter-test.mjs +119 -0
  357. package/scripts/topo-kicker-breath-test.mjs +100 -0
  358. package/scripts/topo-kicker-dual-axis-breath-test.mjs +81 -0
  359. package/scripts/topo-kicker-halo-layers-test.mjs +82 -0
  360. package/scripts/topo-kicker-triple-axis-breath-test.mjs +124 -0
  361. package/scripts/topo-label-card-brightness-test.mjs +81 -0
  362. package/scripts/topo-layout-hover-fw-test.mjs +98 -0
  363. package/scripts/topo-layout-toggle-brightness-test.mjs +94 -0
  364. package/scripts/topo-layout-toggle-halo-layers-test.mjs +95 -0
  365. package/scripts/topo-legend-count-brightness-test.mjs +80 -0
  366. package/scripts/topo-legend-count-halo-layers-test.mjs +79 -0
  367. package/scripts/topo-legend-count-letter-spacing-test.mjs +108 -0
  368. package/scripts/topo-legend-label-fw-test.mjs +107 -0
  369. package/scripts/topo-legend-panel-title-breath-test.mjs +86 -0
  370. package/scripts/topo-legend-pin-ring-brightness-test.mjs +82 -0
  371. package/scripts/topo-legend-pin-ring-halo-layers-test.mjs +71 -0
  372. package/scripts/topo-legend-row-count-brightness-test.mjs +85 -0
  373. package/scripts/topo-legend-row-label-glow-test.mjs +102 -0
  374. package/scripts/topo-legend-swatch-glow-test.mjs +109 -0
  375. package/scripts/topo-legend-swatch-member-alias-match-test.mjs +139 -0
  376. package/scripts/topo-legend-tint-brightness-test.mjs +83 -0
  377. package/scripts/topo-legend-trio-halo-layers-test.mjs +22 -0
  378. package/scripts/topo-live-lanes.mjs +48 -0
  379. package/scripts/topo-minimap-container-halo-test.mjs +82 -0
  380. package/scripts/topo-minimap-dot-chat-gate-test.mjs +81 -0
  381. package/scripts/topo-minimap-hover-glow-test.mjs +109 -0
  382. package/scripts/topo-minimap-viewport-brightness-test.mjs +84 -0
  383. package/scripts/topo-minimap-viewport-halo-layers-test.mjs +24 -0
  384. package/scripts/topo-more-footer-brightness-test.mjs +94 -0
  385. package/scripts/topo-node-alias-brightness-test.mjs +84 -0
  386. package/scripts/topo-node-avatar-halo-layers-test.mjs +25 -0
  387. package/scripts/topo-node-hover-ring-halo-layers-test.mjs +70 -0
  388. package/scripts/topo-node-label-card-halo-test.mjs +76 -0
  389. package/scripts/topo-node-sub-text-brightness-test.mjs +88 -0
  390. package/scripts/topo-nodesize-brightness-test.mjs +82 -0
  391. package/scripts/topo-nodesize-halo-layers-test.mjs +89 -0
  392. package/scripts/topo-nodesize-hover-fw-test.mjs +99 -0
  393. package/scripts/topo-orphan-label-opacity-test.mjs +98 -0
  394. package/scripts/topo-overlap-test.mjs +22 -8
  395. package/scripts/topo-panel-count-halo-layers-test.mjs +91 -0
  396. package/scripts/topo-panel-count-hover-ls-test.mjs +87 -0
  397. package/scripts/topo-panel-rect-halo-test.mjs +90 -0
  398. package/scripts/topo-panel-row-brightness-test.mjs +116 -0
  399. package/scripts/topo-panel-title-brightness-test.mjs +98 -0
  400. package/scripts/topo-panel-title-glow-test.mjs +111 -0
  401. package/scripts/topo-panel-titles-dual-axis-breath-test.mjs +94 -0
  402. package/scripts/topo-panel-titles-halo-layers-test.mjs +23 -0
  403. package/scripts/topo-panel-titles-triple-axis-breath-test.mjs +161 -0
  404. package/scripts/topo-pill-x-rotate-test.mjs +96 -0
  405. package/scripts/topo-pip-brightness-test.mjs +85 -0
  406. package/scripts/topo-pressure-bar-halo-layers-test.mjs +19 -0
  407. package/scripts/topo-pressure-seg-glow-test.mjs +92 -0
  408. package/scripts/topo-pressure-seg-member-alias-match-test.mjs +133 -0
  409. package/scripts/topo-pressure-seg-motion-test.mjs +101 -0
  410. package/scripts/topo-r717-scan-beam-pair-pattern-test.mjs +100 -0
  411. package/scripts/topo-r717-triple-axis-pair-pattern-test.mjs +113 -0
  412. package/scripts/topo-r717-triple-axis-tier-pattern-test.mjs +117 -0
  413. package/scripts/topo-recent-count-brightness-test.mjs +84 -0
  414. package/scripts/topo-recent-more-fw-test.mjs +126 -0
  415. package/scripts/topo-recent-more-halo-layers-test.mjs +90 -0
  416. package/scripts/topo-recent-panel-hot-pulse-test.mjs +105 -0
  417. package/scripts/topo-recent-panel-title-breath-test.mjs +91 -0
  418. package/scripts/topo-recent-pip-halo-layers-test.mjs +82 -0
  419. package/scripts/topo-recent-row-chat-gate-test.mjs +75 -0
  420. package/scripts/topo-recent-row-content-lift-test.mjs +140 -0
  421. package/scripts/topo-recent-row-fw-test.mjs +115 -0
  422. package/scripts/topo-recent-row-text-glow-test.mjs +86 -0
  423. package/scripts/topo-recent-row-text-halo-layers-test.mjs +67 -0
  424. package/scripts/topo-recent-tint-brightness-test.mjs +80 -0
  425. package/scripts/topo-recent-ts-brightness-test.mjs +86 -0
  426. package/scripts/topo-reduced-motion-attr-test.mjs +69 -0
  427. package/scripts/topo-reset-brightness-test.mjs +83 -0
  428. package/scripts/topo-reset-icon-hover-scale-test.mjs +102 -0
  429. package/scripts/topo-respiratory-axis-count-stats-test.mjs +154 -0
  430. package/scripts/topo-respiratory-patterns-catalog-test.mjs +112 -0
  431. package/scripts/topo-respiratory-rolodex-test.mjs +83 -0
  432. package/scripts/topo-respiratory-tiers-catalog-test.mjs +119 -0
  433. package/scripts/topo-respiratory-triple-axis-surfaces-catalog-test.mjs +127 -0
  434. package/scripts/topo-runtime-badge-brightness-test.mjs +78 -0
  435. package/scripts/topo-runtime-badge-glow-test.mjs +108 -0
  436. package/scripts/topo-runtime-badge-halo-layers-test.mjs +87 -0
  437. package/scripts/topo-runtime-badge-rotate-test.mjs +85 -0
  438. package/scripts/topo-section-title-breath-test.mjs +83 -0
  439. package/scripts/topo-section-title-halo-layers-test.mjs +88 -0
  440. package/scripts/topo-spoke-chat-gate-test.mjs +72 -0
  441. package/scripts/topo-starfield-hue-test.mjs +109 -0
  442. package/scripts/topo-status-pin-pill-halo-layers-test.mjs +17 -0
  443. package/scripts/topo-status-ring-brightness-test.mjs +84 -0
  444. package/scripts/topo-status-ring-chat-gate-test.mjs +72 -0
  445. package/scripts/topo-status-ring-halo-layers-test.mjs +105 -0
  446. package/scripts/topo-status-ring-status-halo-test.mjs +110 -0
  447. package/scripts/topo-sub-text-chat-brightness-test.mjs +81 -0
  448. package/scripts/topo-svg-title-a11y-r731-test.mjs +93 -0
  449. package/scripts/topo-svg-title-a11y-test.mjs +88 -0
  450. package/scripts/topo-title-block-entrance-animation-test.mjs +127 -0
  451. package/scripts/topo-title-block-envelope-breath-test.mjs +87 -0
  452. package/scripts/topo-titleblock-h2-hover-fw-test.mjs +109 -0
  453. package/scripts/topo-titleblock-h2-hover-tracking-test.mjs +128 -0
  454. package/scripts/topo-titleblock-kicker-hover-test.mjs +134 -0
  455. package/scripts/topo-tree-diag.mjs +95 -0
  456. package/scripts/topo-vendor-chip-glow-test.mjs +97 -0
  457. package/scripts/topo-vendor-chip-halo-layers-test.mjs +18 -0
  458. package/scripts/topo-vendor-chip-pin-halo-test.mjs +88 -0
  459. package/scripts/topo-vendor-count-suffix-halo-layers-test.mjs +79 -0
  460. package/scripts/topo-vendor-distribution-wrapper-halo-test.mjs +93 -0
  461. package/scripts/topo-vendor-letter-halo-layers-test.mjs +93 -0
  462. package/scripts/topo-vendor-pill-glow-test.mjs +98 -0
  463. package/scripts/topo-watermark-breath-test.mjs +100 -0
  464. package/scripts/topo-watermark-dual-axis-breath-test.mjs +88 -0
  465. package/scripts/topo-watermark-envelope-breath-test.mjs +88 -0
  466. package/scripts/topo-watermark-recede-test.mjs +114 -0
  467. package/scripts/topo-watermark-triple-axis-breath-test.mjs +129 -0
  468. package/scripts/topo-working-online-chip-halo-layers-test.mjs +94 -0
  469. package/scripts/topo-zoom-buttons-brightness-test.mjs +94 -0
  470. package/scripts/topo-zoom-in-out-halo-layers-test.mjs +97 -0
  471. package/scripts/topo-zoom-level-breath-test.mjs +87 -0
  472. package/scripts/topo-zoom-level-brightness-test.mjs +83 -0
  473. package/scripts/topo-zoom-level-color-test.mjs +105 -0
  474. package/scripts/topo-zoom-level-dual-axis-breath-test.mjs +83 -0
  475. package/scripts/topo-zoom-level-halo-layers-test.mjs +78 -0
  476. package/scripts/topo-zoom-level-triple-axis-breath-test.mjs +148 -0
  477. package/.next/static/chunks/0fuba20p57-zo.js +0 -1
  478. package/.next/static/chunks/0m.1mvl~t.avc.css +0 -2
  479. package/.next/static/chunks/10cj-86disers.js +0 -1
  480. package/.next/static/chunks/158h2g7f-nxbt.js +0 -4
  481. /package/.next/server/chunks/{[externals]__11vad82._.js.map → 0ykm__next-internal_server_app_api_hub_upload_route_actions_03_eqnf.js.map} +0 -0
  482. /package/.next/static/{tQ1EtcEiS7ikgAoAyZWm7 → xq88BMF7fMUHWh10yaKTn}/_buildManifest.js +0 -0
  483. /package/.next/static/{tQ1EtcEiS7ikgAoAyZWm7 → xq88BMF7fMUHWh10yaKTn}/_clientMiddlewareManifest.js +0 -0
  484. /package/.next/static/{tQ1EtcEiS7ikgAoAyZWm7 → xq88BMF7fMUHWh10yaKTn}/_ssgManifest.js +0 -0
@@ -0,0 +1,94 @@
1
+ /* Round 629 — extend edge-badge brightness gate (CIRCLE + TEXT)
2
+ * to include isEndpointHoveredEdge. Closes the badge↔edge
3
+ * brightness parity left open after R624 brightened the visible
4
+ * path on endpoint-hover (incl. chat-target via R624's chatAlias
5
+ * extension). 14th anchor in chat-target-gated brightness family
6
+ * (indirect, via isEndpointHoveredEdge), and also a hover-gated
7
+ * polish — two gate axes added in one expression.
8
+ *
9
+ * Test phases:
10
+ * 1. mock 2 nodes + 3 messages → edge with count=3 visible
11
+ * (visible threshold), badge mounts
12
+ * 2. rest (no hover, no chat): brightness '1', endpoint-active 'false'
13
+ * on both circle and text
14
+ * 3. source: filter expression on circle + text includes
15
+ * isEndpointHoveredEdge in the OR-chain
16
+ */
17
+ import { chromium } from 'playwright';
18
+ import { readFileSync } from 'node:fs';
19
+
20
+ const TOKEN = JSON.parse(readFileSync('/home/vansin/.anet/config.json', 'utf8')).token;
21
+ const fresh = new Date(Date.now() - 60 * 1000).toISOString();
22
+
23
+ const browser = await chromium.launch({ headless: true });
24
+ const ctx = await browser.newContext({ viewport: { width: 1500, height: 1200 } });
25
+ await ctx.addCookies([{ name: 'anet_dashboard_session', value: `v3:${TOKEN}`, domain: '127.0.0.1', path: '/' }]);
26
+ await ctx.addInitScript(() => {
27
+ try {
28
+ localStorage.setItem('anet-theme', 'cyber');
29
+ localStorage.setItem('anet-topo-layout', 'ring');
30
+ sessionStorage.setItem('anet_v3_auth', '1');
31
+ } catch {}
32
+ });
33
+ await ctx.route('**/api/hub/status*', async (route) => {
34
+ const r = await route.fetch();
35
+ const b = await r.json();
36
+ const nid = (b.sessions || [])[0]?.network_id || 'default';
37
+ const mk = (alias) => ({
38
+ alias, status: 'idle', model: 'claude-opus-4', runtime: 'claude-code-cli',
39
+ network_id: nid, project_dir: null,
40
+ created_at: fresh, updated_at: fresh, last_seen_at: fresh,
41
+ });
42
+ await route.fulfill({ response: r, json: { ...b, sessions: [mk('a·1'), mk('a·2')] } });
43
+ });
44
+ await ctx.route('**/api/hub/messages*', (r) => r.fulfill({ json: { messages: [
45
+ { from_alias: 'a·1', to_alias: 'a·2', content: 'one', created_at: fresh },
46
+ { from_alias: 'a·1', to_alias: 'a·2', content: 'two', created_at: fresh },
47
+ { from_alias: 'a·1', to_alias: 'a·2', content: 'three', created_at: fresh },
48
+ ] } }));
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-edge-badge-brightness]', { timeout: 15000, state: 'attached' });
53
+ await page.waitForTimeout(500);
54
+
55
+ const rest = await page.evaluate(() => {
56
+ const c = document.querySelector('[data-edge-badge-brightness]');
57
+ const t = document.querySelector('[data-edge-badge-text-brightness]');
58
+ return {
59
+ circleBrightness: c?.getAttribute('data-edge-badge-brightness'),
60
+ circleEndpoint: c?.getAttribute('data-edge-badge-endpoint-active'),
61
+ circleGlow: c?.getAttribute('data-edge-badge-glow'),
62
+ textBrightness: t?.getAttribute('data-edge-badge-text-brightness'),
63
+ textEndpoint: t?.getAttribute('data-edge-badge-text-endpoint-active'),
64
+ };
65
+ });
66
+
67
+ await browser.close();
68
+
69
+ const src = readFileSync('/home/vansin/agent-network-dashboard/app/components/TopoGraph.tsx', 'utf8');
70
+ const sourceCircleFilter = /filter: \(isHoveredEdge \|\| isPinned \|\| isEndpointHoveredEdge\)\s*\n\s*\? `drop-shadow\(0 0 3px \$\{pal\.legendAccent\}99\) brightness\(1\.15\)`/.test(src);
71
+ const sourceTextFilter = /filter: \(isHoveredEdge \|\| isPinned \|\| isHot \|\| isEndpointHoveredEdge\)\s*\n\s*\? 'brightness\(1\.15\)'/.test(src);
72
+ const sourceCircleAttr = /data-edge-badge-brightness=\{\(isHoveredEdge \|\| isPinned \|\| isHot \|\| isEndpointHoveredEdge\) \? '1\.15' : '1'\}/.test(src);
73
+ const sourceCircleEpAttr = /data-edge-badge-endpoint-active=\{isEndpointHoveredEdge \? 'true' : 'false'\}/.test(src);
74
+ const sourceTextAttr = /data-edge-badge-text-brightness=\{\(isHoveredEdge \|\| isPinned \|\| isHot \|\| isEndpointHoveredEdge\) \? '1\.15' : '1'\}/.test(src);
75
+
76
+ const results = {
77
+ circle_present: rest.circleBrightness != null,
78
+ rest_circle_brightness: rest.circleBrightness === '1',
79
+ rest_circle_endpoint: rest.circleEndpoint === 'false',
80
+ rest_circle_glow_false: rest.circleGlow === 'false',
81
+ text_present: rest.textBrightness != null,
82
+ rest_text_brightness: rest.textBrightness === '1',
83
+ rest_text_endpoint: rest.textEndpoint === 'false',
84
+ source_circle_filter: sourceCircleFilter,
85
+ source_text_filter: sourceTextFilter,
86
+ source_circle_attr: sourceCircleAttr,
87
+ source_circle_ep_attr: sourceCircleEpAttr,
88
+ source_text_attr: sourceTextAttr,
89
+ };
90
+ const ok = Object.values(results).every(Boolean);
91
+ console.log(`${ok ? '✅' : '❌'} R629 edge-badge endpoint-active gate (chat-gated family 14th anchor, indirect):`,
92
+ JSON.stringify(results, null, 2),
93
+ `\n rest: ${JSON.stringify(rest)}`);
94
+ process.exit(ok ? 0 : 1);
@@ -0,0 +1,85 @@
1
+ /* Round 646 — edge-badge CIRCLE filter gains a SECOND drop-shadow
2
+ * layer at 6px blur with halved alpha. Extends multi-layer halo
3
+ * family from rings + text to the first per-edge surface.
4
+ *
5
+ * Test phases:
6
+ * 1. mock hot edge (12 messages → isHot=true) → badge visible
7
+ * 2. rest (no hover/pin): hot branch fires → halo-layers='2',
8
+ * computed filter has 2 drop-shadow substrings with amber tint
9
+ * 3. source: both hover/pin/endpoint AND hot branches stack
10
+ * 2 drop-shadows
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
+ // 12 messages → isHot=true (count ≥ 10 threshold) → hot branch of filter fires
40
+ await ctx.route('**/api/hub/messages*', (r) => r.fulfill({ json: { messages:
41
+ Array.from({ length: 12 }, (_, i) => ({
42
+ from_alias: 'a·1', to_alias: 'a·2', content: `msg-${i}`, created_at: fresh,
43
+ }))
44
+ } }));
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-edge-badge-halo-layers]', { timeout: 15000, state: 'attached' });
49
+ await page.waitForTimeout(500);
50
+
51
+ const hot = await page.evaluate(() => {
52
+ const el = document.querySelector('[data-edge-badge-halo-layers="2"]');
53
+ if (!el) return null;
54
+ const cs = getComputedStyle(el);
55
+ return {
56
+ layers: el.getAttribute('data-edge-badge-halo-layers'),
57
+ glow: el.getAttribute('data-edge-badge-glow'),
58
+ filter: cs.filter,
59
+ };
60
+ });
61
+
62
+ await browser.close();
63
+
64
+ const src = readFileSync('/home/vansin/agent-network-dashboard/app/components/TopoGraph.tsx', 'utf8');
65
+ const sourceHoverPin = /`drop-shadow\(0 0 3px \$\{pal\.legendAccent\}99\) drop-shadow\(0 0 6px \$\{pal\.legendAccent\}50\) brightness\(1\.15\)`/.test(src);
66
+ const sourceHot = /`drop-shadow\(0 0 3px \$\{hotStroke\}80\) drop-shadow\(0 0 6px \$\{hotStroke\}40\) brightness\(1\.15\)`/.test(src);
67
+ const sourceLayers = /data-edge-badge-halo-layers=\{\(\(isHoveredEdge \|\| isPinned \|\| isEndpointHoveredEdge\) \|\| isHot\) \? '2' : '0'\}/.test(src);
68
+
69
+ const hotDropShadowCount = (hot?.filter?.match(/drop-shadow/g) || []).length;
70
+
71
+ const results = {
72
+ hot_present: !!hot,
73
+ hot_layers_2: hot?.layers === '2',
74
+ hot_glow_hot: hot?.glow === 'hot',
75
+ hot_two_dropshadows: hotDropShadowCount === 2,
76
+ hot_filter_brightness: /brightness/.test(hot?.filter || ''),
77
+ source_hover_pin: sourceHoverPin,
78
+ source_hot: sourceHot,
79
+ source_layers_attr: sourceLayers,
80
+ };
81
+ const ok = Object.values(results).every(Boolean);
82
+ console.log(`${ok ? '✅' : '❌'} R646 edge-badge multi-layer halo (per-edge chromatic identity):`,
83
+ JSON.stringify(results, null, 2),
84
+ `\n hot: ${JSON.stringify(hot)}`);
85
+ process.exit(ok ? 0 : 1);
@@ -0,0 +1,92 @@
1
+ /* Round 632 — canvas-side edge-badge digit picks up R498's
2
+ * `anet-recent-hot-pulse` className when isHot && !reducedMotion.
3
+ * Pulse extends from panel-row count digit (R498) to canvas-edge
4
+ * badge digit so a hot lane breathes together across both
5
+ * surfaces. 2nd anchor in hot-pulse family.
6
+ *
7
+ * Test phases:
8
+ * 1. mock 2 nodes + 12 messages on one edge → isHot=true
9
+ * (count ≥ 10 threshold)
10
+ * 2. badge text present, className contains
11
+ * 'anet-recent-hot-pulse', hot-pulse attr 'true'
12
+ * 3. computed animation-name resolves to
13
+ * 'anet-recent-hot-pulse-kf' (CSS keyframes hook firing)
14
+ * 4. source: className gate matches `isHot && !reducedMotion`
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) => ({
37
+ alias, status: 'idle', model: 'claude-opus-4', runtime: 'claude-code-cli',
38
+ network_id: nid, project_dir: null,
39
+ created_at: fresh, updated_at: fresh, last_seen_at: fresh,
40
+ });
41
+ await route.fulfill({ response: r, json: { ...b, sessions: [mk('a·1'), mk('a·2')] } });
42
+ });
43
+ // 12 messages on a·1 → a·2 (count ≥ 10 = isHot threshold)
44
+ await ctx.route('**/api/hub/messages*', (r) => r.fulfill({ json: { messages:
45
+ Array.from({ length: 12 }, (_, i) => ({
46
+ from_alias: 'a·1', to_alias: 'a·2', content: `msg-${i}`, created_at: fresh,
47
+ }))
48
+ } }));
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-edge-badge-text-hot-pulse]', { timeout: 15000, state: 'attached' });
53
+ await page.waitForTimeout(500);
54
+
55
+ const hot = await page.evaluate(() => {
56
+ const el = document.querySelector('[data-edge-badge-text-hot-pulse="true"]');
57
+ if (!el) return null;
58
+ const cs = getComputedStyle(el);
59
+ return {
60
+ cls: el.getAttribute('class') || '',
61
+ pulseAttr: el.getAttribute('data-edge-badge-text-hot-pulse'),
62
+ brightnessAttr:el.getAttribute('data-edge-badge-text-brightness'),
63
+ animName: cs.animationName,
64
+ animDuration: cs.animationDuration,
65
+ animIter: cs.animationIterationCount,
66
+ animTiming: cs.animationTimingFunction,
67
+ textContent: el.textContent,
68
+ };
69
+ });
70
+
71
+ await browser.close();
72
+
73
+ const src = readFileSync('/home/vansin/agent-network-dashboard/app/components/TopoGraph.tsx', 'utf8');
74
+ const sourceClassName = /className=\{isHot && !reducedMotion \? 'anet-recent-hot-pulse' : undefined\}\s*\n\s*data-edge-badge-text-hot-pulse=\{isHot && !reducedMotion \? 'true' : 'false'\}/.test(src);
75
+
76
+ const results = {
77
+ hot_text_present: !!hot,
78
+ has_pulse_class: /anet-recent-hot-pulse/.test(hot?.cls || ''),
79
+ pulse_attr_true: hot?.pulseAttr === 'true',
80
+ brightness_hot: hot?.brightnessAttr === '1.15',
81
+ anim_name_kf: /anet-recent-hot-pulse-kf/.test(hot?.animName || ''),
82
+ anim_duration_3s: /^3s\b/.test(hot?.animDuration || ''),
83
+ anim_iter_infinite: hot?.animIter === 'infinite',
84
+ anim_timing_ease_in_out: /ease-in-out/.test(hot?.animTiming || ''),
85
+ text_is_count_12: hot?.textContent === '12',
86
+ source_className_gate: sourceClassName,
87
+ };
88
+ const ok = Object.values(results).every(Boolean);
89
+ console.log(`${ok ? '✅' : '❌'} R632 edge-badge digit hot-pulse (2nd anchor in hot-pulse family):`,
90
+ JSON.stringify(results, null, 2),
91
+ `\n hot: ${JSON.stringify(hot)}`);
92
+ process.exit(ok ? 0 : 1);
@@ -0,0 +1,90 @@
1
+ /* Round 534 verification: edge midpoint badge gains drop-shadow glow on
2
+ * hover/pin (cyan accent), with hover precedence over isHot (amber R480).
3
+ *
4
+ * Test strategy: source-side wiring is canonical because edge hover via
5
+ * Playwright is impractical (topo-panel rect intercepts at SVG root;
6
+ * R48 hitbox is the React handler target but isn't directly hoverable
7
+ * through the panel). Rest-state DOM probe + source regex covers the
8
+ * 4-axis hover-lift parity wiring.
9
+ *
10
+ * Test phases:
11
+ * 1. rest cold: glow attr='false', filter='none', lifted attr='false'
12
+ * (regression check — pre-R534 behavior unchanged at rest)
13
+ * 2. source-side regex confirms:
14
+ * - filter ternary precedence: (hovered||pinned) > isHot > undefined
15
+ * - cyan accent hue (pal.legendAccent) at 99 hex alpha
16
+ * - data-edge-badge-glow 3-value attr ('hover' | 'hot' | 'false')
17
+ * - transition list includes filter
18
+ */
19
+ import { chromium } from 'playwright';
20
+ import { readFileSync } from 'node:fs';
21
+
22
+ const TOKEN = JSON.parse(readFileSync('/home/vansin/.anet/config.json', 'utf8')).token;
23
+ const fresh = new Date(Date.now() - 60 * 1000).toISOString();
24
+
25
+ const browser = await chromium.launch({ headless: true });
26
+ const ctx = await browser.newContext({ viewport: { width: 1500, height: 1200 } });
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: 'working', 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: [mk('a·1'), mk('a·2')] } });
45
+ });
46
+ await ctx.route('**/api/hub/messages*', (r) => r.fulfill({ json: {
47
+ messages: [{ id: 'm1', from_alias: 'a·1', to_alias: 'a·2', content: 'test', created_at: fresh }]
48
+ } }));
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-edge-badge-glow]', { timeout: 15000 });
53
+ await page.waitForTimeout(800);
54
+
55
+ const rest = await page.evaluate(() => {
56
+ const el = document.querySelector('[data-edge-badge-glow]');
57
+ if (!el) return null;
58
+ const cs = getComputedStyle(el);
59
+ return {
60
+ glowAttr: el.getAttribute('data-edge-badge-glow'),
61
+ liftedAttr: el.getAttribute('data-edge-badge-lifted'),
62
+ filter: cs.filter,
63
+ transition: cs.transition,
64
+ };
65
+ });
66
+
67
+ await browser.close();
68
+
69
+ const src = readFileSync('/home/vansin/agent-network-dashboard/app/components/TopoGraph.tsx', 'utf8');
70
+ const sourceFilterTernary =
71
+ /filter: \(isHoveredEdge \|\| isPinned\)\s+\? `drop-shadow\(0 0 3px \$\{pal\.legendAccent\}99\)`\s+: isHot\s+\? `drop-shadow\(0 0 3px \$\{hotStroke\}80\)`\s+: undefined,/.test(src);
72
+ const sourceAttrTernary =
73
+ /data-edge-badge-glow=\{\(isHoveredEdge \|\| isPinned\) \? 'hover' : isHot \? 'hot' : 'false'\}/.test(src);
74
+ const sourceTransitionFilter =
75
+ /transition: 'r 180ms ease-out, stroke 300ms ease-out, stroke-width 300ms ease-out, fill 200ms ease-out, opacity 200ms ease-out, filter 200ms ease-out'/.test(src);
76
+
77
+ const results = {
78
+ rest_glow_false: rest?.glowAttr === 'false',
79
+ rest_lifted_false: rest?.liftedAttr === 'false',
80
+ rest_filter_none: rest?.filter === 'none' || rest?.filter === '',
81
+ rest_transition_has_filter: /\bfilter\b/.test(rest?.transition || ''),
82
+ source_filter_ternary: sourceFilterTernary,
83
+ source_attr_ternary: sourceAttrTernary,
84
+ source_transition_filter: sourceTransitionFilter,
85
+ };
86
+ const ok = Object.values(results).every(Boolean);
87
+ console.log(`${ok ? '✅' : '❌'} R534 edge-badge hover-glow (source-canonical):`,
88
+ JSON.stringify(results, null, 2),
89
+ '\n rest:', JSON.stringify(rest));
90
+ process.exit(ok ? 0 : 1);
@@ -0,0 +1,83 @@
1
+ /* Round 570 verification: edge-badge digit gains filter brightness
2
+ * (1.15) on (isHoveredEdge || isPinned || isHot). Joins per-element
3
+ * brightness family at 7th anchor.
4
+ *
5
+ * Test phases:
6
+ * 1. mock 1 message → 1 flowLink with edge-badge rendered
7
+ * 2. rest: filter='none', brightness-attr='1'
8
+ * 3. transition-property contains 'filter'
9
+ * 4. source-side regex confirms wiring
10
+ *
11
+ * Live hover/pin on SVG edge-badge is unreliable for Playwright
12
+ * (R525 banked); use source-canonical for gate + rest data-attrs.
13
+ */
14
+ import { chromium } from 'playwright';
15
+ import { readFileSync } from 'node:fs';
16
+
17
+ const TOKEN = JSON.parse(readFileSync('/home/vansin/.anet/config.json', 'utf8')).token;
18
+ const fresh = new Date(Date.now() - 60 * 1000).toISOString();
19
+
20
+ const browser = await chromium.launch({ headless: true });
21
+ const ctx = await browser.newContext({ viewport: { width: 1500, height: 1200 } });
22
+ await ctx.addCookies([{ name: 'anet_dashboard_session', value: `v3:${TOKEN}`, domain: '127.0.0.1', path: '/' }]);
23
+ await ctx.addInitScript(() => {
24
+ try {
25
+ localStorage.setItem('anet-theme', 'cyber');
26
+ localStorage.setItem('anet-topo-layout', 'ring');
27
+ sessionStorage.setItem('anet_v3_auth', '1');
28
+ } catch {}
29
+ });
30
+ await ctx.route('**/api/hub/status*', async (route) => {
31
+ const r = await route.fetch();
32
+ const b = await r.json();
33
+ const nid = (b.sessions || [])[0]?.network_id || 'default';
34
+ const mk = (alias) => ({
35
+ alias, status: 'idle', model: 'claude-opus-4', runtime: 'claude-code-cli',
36
+ network_id: nid, project_dir: null,
37
+ created_at: fresh, updated_at: fresh, last_seen_at: fresh,
38
+ });
39
+ await route.fulfill({ response: r, json: { ...b, sessions: [mk('a·1'), mk('a·2')] } });
40
+ });
41
+ // 1 message so flowLinks > 0 → edge-badge renders
42
+ await ctx.route('**/api/hub/messages*', (r) => r.fulfill({ json: { messages: [
43
+ { from_alias: 'a·1', to_alias: 'a·2', content: 'hi', created_at: fresh },
44
+ ] } }));
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-edge-badge-text]', { timeout: 15000 });
49
+ await page.waitForTimeout(500);
50
+
51
+ const rest = await page.evaluate(() => {
52
+ const el = document.querySelector('[data-edge-badge-text]');
53
+ if (!el) return null;
54
+ const cs = getComputedStyle(el);
55
+ return {
56
+ filter: cs.filter,
57
+ transitionProperty: cs.transitionProperty,
58
+ brightnessAttr: el.getAttribute('data-edge-badge-text-brightness'),
59
+ pinAttr: el.getAttribute('data-edge-badge-text-pin'),
60
+ };
61
+ });
62
+
63
+ await browser.close();
64
+
65
+ const src = readFileSync('/home/vansin/agent-network-dashboard/app/components/TopoGraph.tsx', 'utf8');
66
+ const sourceFilter = /filter: \(isHoveredEdge \|\| isPinned \|\| isHot\)\s*\?\s*'brightness\(1\.15\)'\s*:\s*undefined/.test(src);
67
+ const sourceAttr = /data-edge-badge-text-brightness=\{\(isHoveredEdge \|\| isPinned \|\| isHot\) \? '1\.15' : '1'\}/.test(src);
68
+ const sourceTransition = /transition: 'letter-spacing 300ms ease-out, font-weight 300ms ease-out, filter 300ms ease-out'/.test(src);
69
+
70
+ const results = {
71
+ rest_filter_none: rest?.filter === 'none',
72
+ rest_brightness_1: rest?.brightnessAttr === '1',
73
+ rest_pin_false: rest?.pinAttr === 'false',
74
+ transition_has_filter: /filter/.test(rest?.transitionProperty || ''),
75
+ source_filter: sourceFilter,
76
+ source_attr: sourceAttr,
77
+ source_transition: sourceTransition,
78
+ };
79
+ const ok = Object.values(results).every(Boolean);
80
+ console.log(`${ok ? '✅' : '❌'} R570 edge-badge text brightness(1.15) (per-element family 7th anchor):`,
81
+ JSON.stringify(results, null, 2),
82
+ `\n rest: ${JSON.stringify(rest)}`);
83
+ process.exit(ok ? 0 : 1);
@@ -0,0 +1,71 @@
1
+ /* Round 624 — extend isEndpointHoveredEdge gate to include
2
+ * chatAlias. All edges incident on the chat partner now light
3
+ * up. 10th anchor in chat-target-gated brightness family.
4
+ *
5
+ * Test phases:
6
+ * 1. mock 2 nodes + 1 flow message → 1 flowLink/edge renders
7
+ * 2. rest (no hover, no chat): edge at idle stroke-width
8
+ * 3. source: isEndpointHoveredEdge declaration uses gate union
9
+ * `(hover || chat)` joined by ||
10
+ */
11
+ import { chromium } from 'playwright';
12
+ import { readFileSync } from 'node:fs';
13
+
14
+ const TOKEN = JSON.parse(readFileSync('/home/vansin/.anet/config.json', 'utf8')).token;
15
+ const fresh = new Date(Date.now() - 60 * 1000).toISOString();
16
+
17
+ const browser = await chromium.launch({ headless: true });
18
+ const ctx = await browser.newContext({ viewport: { width: 1500, height: 1200 } });
19
+ await ctx.addCookies([{ name: 'anet_dashboard_session', value: `v3:${TOKEN}`, domain: '127.0.0.1', path: '/' }]);
20
+ await ctx.addInitScript(() => {
21
+ try {
22
+ localStorage.setItem('anet-theme', 'cyber');
23
+ localStorage.setItem('anet-topo-layout', 'ring');
24
+ sessionStorage.setItem('anet_v3_auth', '1');
25
+ } catch {}
26
+ });
27
+ await ctx.route('**/api/hub/status*', async (route) => {
28
+ const r = await route.fetch();
29
+ const b = await r.json();
30
+ const nid = (b.sessions || [])[0]?.network_id || 'default';
31
+ const mk = (alias) => ({
32
+ alias, status: 'idle', model: 'claude-opus-4', runtime: 'claude-code-cli',
33
+ network_id: nid, project_dir: null,
34
+ created_at: fresh, updated_at: fresh, last_seen_at: fresh,
35
+ });
36
+ await route.fulfill({ response: r, json: { ...b, sessions: [mk('a·1'), mk('a·2')] } });
37
+ });
38
+ await ctx.route('**/api/hub/messages*', (r) => r.fulfill({ json: { messages: [
39
+ { from_alias: 'a·1', to_alias: 'a·2', content: 'hi', created_at: fresh },
40
+ ] } }));
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('[data-edge-visible]', { timeout: 15000, state: 'attached' });
45
+ await page.waitForTimeout(500);
46
+
47
+ const rest = await page.evaluate(() => {
48
+ const el = document.querySelector('[data-edge-visible]');
49
+ if (!el) return null;
50
+ return {
51
+ endpointAttr: el.getAttribute('data-edge-visible-endpoint-hovered'),
52
+ brightnessAttr: el.getAttribute('data-edge-visible-brightness'),
53
+ };
54
+ });
55
+
56
+ await browser.close();
57
+
58
+ const src = readFileSync('/home/vansin/agent-network-dashboard/app/components/TopoGraph.tsx', 'utf8');
59
+ const sourceGate = /const isEndpointHoveredEdge = \(!!hoveredAlias && \(link\.from === hoveredAlias \|\| link\.to === hoveredAlias\)\)\s*\|\|\s*\(!!chatAlias\s*&& \(link\.from === chatAlias\s*\|\| link\.to === chatAlias\)\)/.test(src);
60
+
61
+ const results = {
62
+ edge_present: !!rest,
63
+ rest_endpoint_false: rest?.endpointAttr === 'false',
64
+ rest_brightness_1: rest?.brightnessAttr === '1',
65
+ source_gate_or: sourceGate,
66
+ };
67
+ const ok = Object.values(results).every(Boolean);
68
+ console.log(`${ok ? '✅' : '❌'} R624 incident-edge chat-target gate (chat-gated family 10th anchor):`,
69
+ JSON.stringify(results, null, 2),
70
+ `\n rest: ${JSON.stringify(rest)}`);
71
+ process.exit(ok ? 0 : 1);
@@ -0,0 +1,89 @@
1
+ /* Round 678 — edge flow-rail (dashed underline) extends single-axis
2
+ * brightness hover to 2-layer drop-shadow at pal.flowPath tint with
3
+ * 2+4 stride, alpha 80/40. Sibling to R677 visible-path's pal.flowEdge
4
+ * halo. Completes the edge stroke pair (visible + rail) at full halo
5
+ * coverage. Per-edge ALL 4 surfaces now multi-layer (badge circle,
6
+ * badge digit, visible path, flow-rail). 37th anchor in family.
7
+ *
8
+ * The rail is dashed (strokeDasharray="2 12") so each dash halos
9
+ * individually — glow-stones-along-path effect.
10
+ *
11
+ * Source assertions:
12
+ * - filter uses pal.flowPath at 0x80 + 0x40 with 2+4 stride
13
+ * - data-edge-flow-rail-halo-layers attr toggles '2' ↔ '0'
14
+ *
15
+ * Runtime assertions:
16
+ * - rails present in DOM
17
+ * - rest: halo-layers='0' on all
18
+ * - gate consistency: brightness ↔ layers
19
+ */
20
+ import { chromium } from 'playwright';
21
+ import { readFileSync } from 'node:fs';
22
+
23
+ const TOKEN = JSON.parse(readFileSync('/home/vansin/.anet/config.json', 'utf8')).token;
24
+ const fresh = new Date(Date.now() - 60 * 1000).toISOString();
25
+
26
+ const browser = await chromium.launch({ headless: true });
27
+ const ctx = await browser.newContext({ viewport: { width: 1500, height: 1200 } });
28
+ await ctx.addCookies([{ name: 'anet_dashboard_session', value: `v3:${TOKEN}`, domain: '127.0.0.1', path: '/' }]);
29
+ await ctx.addInitScript(() => {
30
+ try {
31
+ localStorage.setItem('anet-theme', 'cyber');
32
+ localStorage.setItem('anet-topo-layout', 'ring');
33
+ sessionStorage.setItem('anet_v3_auth', '1');
34
+ } catch {}
35
+ });
36
+ await ctx.route('**/api/hub/status*', async (route) => {
37
+ const r = await route.fetch();
38
+ const b = await r.json();
39
+ const nid = (b.sessions || [])[0]?.network_id || 'default';
40
+ const mk = (alias) => ({
41
+ alias, status: 'idle', model: 'claude-opus-4', runtime: 'claude-code-cli',
42
+ network_id: nid, project_dir: null,
43
+ created_at: fresh, updated_at: fresh, last_seen_at: fresh,
44
+ });
45
+ await route.fulfill({ response: r, json: { ...b, sessions: [
46
+ mk('a·1'), mk('a·2'), mk('a·3'),
47
+ ] } });
48
+ });
49
+ await ctx.route('**/api/hub/messages*', (r) => r.fulfill({ json: { messages: [
50
+ { id: 'm1', from_alias: 'a·1', to_alias: 'a·2', kind: 'message', content: 'p', network_id: 'default', created_at: fresh },
51
+ { id: 'm2', from_alias: 'a·2', to_alias: 'a·3', kind: 'task', content: 'p2', network_id: 'default', created_at: fresh },
52
+ ] } }));
53
+ await ctx.route('**/api/hub/tasks*', (r) => r.fulfill({ json: { tasks: [] } }));
54
+ const page = await ctx.newPage();
55
+ await page.goto('http://127.0.0.1:3000/', { waitUntil: 'networkidle' });
56
+ await page.waitForSelector('[data-edge-flow-rail-halo-layers]', { timeout: 15000, state: 'attached' });
57
+ await page.waitForTimeout(500);
58
+
59
+ const restState = await page.evaluate(() => {
60
+ return Array.from(document.querySelectorAll('[data-edge-flow-rail]')).map(el => ({
61
+ rail: el.getAttribute('data-edge-flow-rail'),
62
+ layers: el.getAttribute('data-edge-flow-rail-halo-layers'),
63
+ brightness: el.getAttribute('data-edge-flow-rail-brightness'),
64
+ }));
65
+ });
66
+
67
+ await browser.close();
68
+
69
+ const src = readFileSync('/home/vansin/agent-network-dashboard/app/components/TopoGraph.tsx', 'utf8');
70
+ const sourceFilter = /\? `drop-shadow\(0 0 2px \$\{pal\.flowPath\}80\) drop-shadow\(0 0 4px \$\{pal\.flowPath\}40\) brightness\(1\.15\)`/.test(src);
71
+ const sourceAttr = /data-edge-flow-rail-halo-layers=\{\(isHoveredEdge \|\| isEndpointHoveredEdge\) \? '2' : '0'\}/.test(src);
72
+
73
+ const allConsistent = restState.every(e =>
74
+ (e.brightness === '1' && e.layers === '0') ||
75
+ (e.brightness === '1.15' && e.layers === '2')
76
+ );
77
+
78
+ const results = {
79
+ rails_present: restState.length >= 2,
80
+ rest_all_layers_zero: restState.every(e => e.layers === '0'),
81
+ rest_gate_consistent: allConsistent,
82
+ source_filter: sourceFilter,
83
+ source_layers_attr: sourceAttr,
84
+ };
85
+ const ok = Object.values(results).every(Boolean);
86
+ console.log(`${ok ? '✅' : '❌'} R678 edge flow-rail multi-layer halo (completes edge stroke pair 2/2):`,
87
+ JSON.stringify(results, null, 2),
88
+ `\n rest: ${JSON.stringify(restState)}`);
89
+ process.exit(ok ? 0 : 1);