@sleep2agi/agent-network-dashboard 0.4.6-preview.31 → 0.4.6-preview.310

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 (477) 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 +41 -41
  4. package/.next/fallback-build-manifest.json +3 -3
  5. package/.next/prerender-manifest.json +3 -3
  6. package/.next/server/app/_global-error.html +1 -1
  7. package/.next/server/app/_global-error.rsc +1 -1
  8. package/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  9. package/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  10. package/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  11. package/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  12. package/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  13. package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  14. package/.next/server/app/_not-found.html +2 -2
  15. package/.next/server/app/_not-found.rsc +12 -12
  16. package/.next/server/app/_not-found.segments/_full.segment.rsc +12 -12
  17. package/.next/server/app/_not-found.segments/_head.segment.rsc +4 -4
  18. package/.next/server/app/_not-found.segments/_index.segment.rsc +7 -7
  19. package/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +2 -2
  20. package/.next/server/app/_not-found.segments/_not-found.segment.rsc +3 -3
  21. package/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  22. package/.next/server/app/admin/page_client-reference-manifest.js +1 -1
  23. package/.next/server/app/admin.html +2 -2
  24. package/.next/server/app/admin.rsc +14 -14
  25. package/.next/server/app/admin.segments/_full.segment.rsc +14 -14
  26. package/.next/server/app/admin.segments/_head.segment.rsc +4 -4
  27. package/.next/server/app/admin.segments/_index.segment.rsc +7 -7
  28. package/.next/server/app/admin.segments/_tree.segment.rsc +2 -2
  29. package/.next/server/app/admin.segments/admin/__PAGE__.segment.rsc +4 -4
  30. package/.next/server/app/admin.segments/admin.segment.rsc +3 -3
  31. package/.next/server/app/index.html +2 -2
  32. package/.next/server/app/index.rsc +14 -14
  33. package/.next/server/app/index.segments/__PAGE__.segment.rsc +4 -4
  34. package/.next/server/app/index.segments/_full.segment.rsc +14 -14
  35. package/.next/server/app/index.segments/_head.segment.rsc +4 -4
  36. package/.next/server/app/index.segments/_index.segment.rsc +7 -7
  37. package/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  38. package/.next/server/app/login/page_client-reference-manifest.js +1 -1
  39. package/.next/server/app/login.html +2 -2
  40. package/.next/server/app/login.rsc +14 -14
  41. package/.next/server/app/login.segments/_full.segment.rsc +14 -14
  42. package/.next/server/app/login.segments/_head.segment.rsc +4 -4
  43. package/.next/server/app/login.segments/_index.segment.rsc +7 -7
  44. package/.next/server/app/login.segments/_tree.segment.rsc +2 -2
  45. package/.next/server/app/login.segments/login/__PAGE__.segment.rsc +4 -4
  46. package/.next/server/app/login.segments/login.segment.rsc +3 -3
  47. package/.next/server/app/logs/page_client-reference-manifest.js +1 -1
  48. package/.next/server/app/logs.html +2 -2
  49. package/.next/server/app/logs.rsc +14 -14
  50. package/.next/server/app/logs.segments/_full.segment.rsc +14 -14
  51. package/.next/server/app/logs.segments/_head.segment.rsc +4 -4
  52. package/.next/server/app/logs.segments/_index.segment.rsc +7 -7
  53. package/.next/server/app/logs.segments/_tree.segment.rsc +2 -2
  54. package/.next/server/app/logs.segments/logs/__PAGE__.segment.rsc +4 -4
  55. package/.next/server/app/logs.segments/logs.segment.rsc +3 -3
  56. package/.next/server/app/messages/page_client-reference-manifest.js +1 -1
  57. package/.next/server/app/messages.html +2 -2
  58. package/.next/server/app/messages.rsc +14 -14
  59. package/.next/server/app/messages.segments/_full.segment.rsc +14 -14
  60. package/.next/server/app/messages.segments/_head.segment.rsc +4 -4
  61. package/.next/server/app/messages.segments/_index.segment.rsc +7 -7
  62. package/.next/server/app/messages.segments/_tree.segment.rsc +2 -2
  63. package/.next/server/app/messages.segments/messages/__PAGE__.segment.rsc +4 -4
  64. package/.next/server/app/messages.segments/messages.segment.rsc +3 -3
  65. package/.next/server/app/node/page_client-reference-manifest.js +1 -1
  66. package/.next/server/app/node.html +2 -2
  67. package/.next/server/app/node.rsc +14 -14
  68. package/.next/server/app/node.segments/_full.segment.rsc +14 -14
  69. package/.next/server/app/node.segments/_head.segment.rsc +4 -4
  70. package/.next/server/app/node.segments/_index.segment.rsc +7 -7
  71. package/.next/server/app/node.segments/_tree.segment.rsc +2 -2
  72. package/.next/server/app/node.segments/node/__PAGE__.segment.rsc +4 -4
  73. package/.next/server/app/node.segments/node.segment.rsc +3 -3
  74. package/.next/server/app/nodes/page_client-reference-manifest.js +1 -1
  75. package/.next/server/app/nodes.html +2 -2
  76. package/.next/server/app/nodes.rsc +14 -14
  77. package/.next/server/app/nodes.segments/_full.segment.rsc +14 -14
  78. package/.next/server/app/nodes.segments/_head.segment.rsc +4 -4
  79. package/.next/server/app/nodes.segments/_index.segment.rsc +7 -7
  80. package/.next/server/app/nodes.segments/_tree.segment.rsc +2 -2
  81. package/.next/server/app/nodes.segments/nodes/__PAGE__.segment.rsc +4 -4
  82. package/.next/server/app/nodes.segments/nodes.segment.rsc +3 -3
  83. package/.next/server/app/page_client-reference-manifest.js +1 -1
  84. package/.next/server/app/server-logs/page_client-reference-manifest.js +1 -1
  85. package/.next/server/app/server-logs.html +2 -2
  86. package/.next/server/app/server-logs.rsc +14 -14
  87. package/.next/server/app/server-logs.segments/_full.segment.rsc +14 -14
  88. package/.next/server/app/server-logs.segments/_head.segment.rsc +4 -4
  89. package/.next/server/app/server-logs.segments/_index.segment.rsc +7 -7
  90. package/.next/server/app/server-logs.segments/_tree.segment.rsc +2 -2
  91. package/.next/server/app/server-logs.segments/server-logs/__PAGE__.segment.rsc +4 -4
  92. package/.next/server/app/server-logs.segments/server-logs.segment.rsc +3 -3
  93. package/.next/server/app/settings/networks/page_client-reference-manifest.js +1 -1
  94. package/.next/server/app/settings/networks.html +2 -2
  95. package/.next/server/app/settings/networks.rsc +14 -14
  96. package/.next/server/app/settings/networks.segments/_full.segment.rsc +14 -14
  97. package/.next/server/app/settings/networks.segments/_head.segment.rsc +4 -4
  98. package/.next/server/app/settings/networks.segments/_index.segment.rsc +7 -7
  99. package/.next/server/app/settings/networks.segments/_tree.segment.rsc +2 -2
  100. package/.next/server/app/settings/networks.segments/settings/networks/__PAGE__.segment.rsc +4 -4
  101. package/.next/server/app/settings/networks.segments/settings/networks.segment.rsc +3 -3
  102. package/.next/server/app/settings/networks.segments/settings.segment.rsc +3 -3
  103. package/.next/server/app/settings/page_client-reference-manifest.js +1 -1
  104. package/.next/server/app/settings/tokens/page_client-reference-manifest.js +1 -1
  105. package/.next/server/app/settings/tokens.html +2 -2
  106. package/.next/server/app/settings/tokens.rsc +14 -14
  107. package/.next/server/app/settings/tokens.segments/_full.segment.rsc +14 -14
  108. package/.next/server/app/settings/tokens.segments/_head.segment.rsc +4 -4
  109. package/.next/server/app/settings/tokens.segments/_index.segment.rsc +7 -7
  110. package/.next/server/app/settings/tokens.segments/_tree.segment.rsc +2 -2
  111. package/.next/server/app/settings/tokens.segments/settings/tokens/__PAGE__.segment.rsc +4 -4
  112. package/.next/server/app/settings/tokens.segments/settings/tokens.segment.rsc +3 -3
  113. package/.next/server/app/settings/tokens.segments/settings.segment.rsc +3 -3
  114. package/.next/server/app/settings.html +2 -2
  115. package/.next/server/app/settings.rsc +14 -14
  116. package/.next/server/app/settings.segments/_full.segment.rsc +14 -14
  117. package/.next/server/app/settings.segments/_head.segment.rsc +4 -4
  118. package/.next/server/app/settings.segments/_index.segment.rsc +7 -7
  119. package/.next/server/app/settings.segments/_tree.segment.rsc +2 -2
  120. package/.next/server/app/settings.segments/settings/__PAGE__.segment.rsc +4 -4
  121. package/.next/server/app/settings.segments/settings.segment.rsc +3 -3
  122. package/.next/server/app/tasks/[id]/page_client-reference-manifest.js +1 -1
  123. package/.next/server/app/tasks/page_client-reference-manifest.js +1 -1
  124. package/.next/server/app/tasks.html +2 -2
  125. package/.next/server/app/tasks.rsc +14 -14
  126. package/.next/server/app/tasks.segments/_full.segment.rsc +14 -14
  127. package/.next/server/app/tasks.segments/_head.segment.rsc +4 -4
  128. package/.next/server/app/tasks.segments/_index.segment.rsc +7 -7
  129. package/.next/server/app/tasks.segments/_tree.segment.rsc +2 -2
  130. package/.next/server/app/tasks.segments/tasks/__PAGE__.segment.rsc +4 -4
  131. package/.next/server/app/tasks.segments/tasks.segment.rsc +3 -3
  132. package/.next/server/chunks/ssr/[root-of-the-server]__03b.f76._.js +1 -1
  133. package/.next/server/chunks/ssr/[root-of-the-server]__03b.f76._.js.map +1 -1
  134. package/.next/server/chunks/ssr/[root-of-the-server]__0fhoq8i._.js +1 -1
  135. package/.next/server/chunks/ssr/[root-of-the-server]__0fhoq8i._.js.map +1 -1
  136. package/.next/server/chunks/ssr/[root-of-the-server]__0nw~zhp._.js +1 -1
  137. package/.next/server/chunks/ssr/[root-of-the-server]__0nw~zhp._.js.map +1 -1
  138. package/.next/server/chunks/ssr/agent-network-dashboard_09kk21a._.js +4 -1
  139. package/.next/server/chunks/ssr/agent-network-dashboard_09kk21a._.js.map +1 -1
  140. package/.next/server/chunks/ssr/agent-network-dashboard_app_01jhlxz._.js +1 -1
  141. package/.next/server/chunks/ssr/agent-network-dashboard_app_01jhlxz._.js.map +1 -1
  142. package/.next/server/chunks/ssr/agent-network-dashboard_app_057q.ne._.js +1 -1
  143. package/.next/server/chunks/ssr/agent-network-dashboard_app_057q.ne._.js.map +1 -1
  144. package/.next/server/chunks/ssr/agent-network-dashboard_app_09d29my._.js +1 -1
  145. package/.next/server/chunks/ssr/agent-network-dashboard_app_09d29my._.js.map +1 -1
  146. package/.next/server/chunks/ssr/agent-network-dashboard_app_0_d45-d._.js +1 -1
  147. package/.next/server/chunks/ssr/agent-network-dashboard_app_0_d45-d._.js.map +1 -1
  148. package/.next/server/chunks/ssr/agent-network-dashboard_app_0i3759l._.js +1 -1
  149. package/.next/server/chunks/ssr/agent-network-dashboard_app_0i3759l._.js.map +1 -1
  150. package/.next/server/chunks/ssr/agent-network-dashboard_app_0xgney8._.js +1 -1
  151. package/.next/server/chunks/ssr/agent-network-dashboard_app_0xgney8._.js.map +1 -1
  152. package/.next/server/chunks/ssr/agent-network-dashboard_app_10hjgv4._.js +1 -1
  153. package/.next/server/chunks/ssr/agent-network-dashboard_app_10hjgv4._.js.map +1 -1
  154. package/.next/server/chunks/ssr/agent-network-dashboard_app_1153xeb._.js +1 -1
  155. package/.next/server/chunks/ssr/agent-network-dashboard_app_1153xeb._.js.map +1 -1
  156. package/.next/server/chunks/ssr/agent-network-dashboard_app_12l4oto._.js +1 -1
  157. package/.next/server/chunks/ssr/agent-network-dashboard_app_12l4oto._.js.map +1 -1
  158. package/.next/server/chunks/ssr/agent-network-dashboard_app_components_0mvyi-4._.js +1 -1
  159. package/.next/server/chunks/ssr/agent-network-dashboard_app_components_0mvyi-4._.js.map +1 -1
  160. package/.next/server/middleware-build-manifest.js +3 -3
  161. package/.next/server/pages/404.html +2 -2
  162. package/.next/server/pages/500.html +1 -1
  163. package/.next/server/server-reference-manifest.js +1 -1
  164. package/.next/server/server-reference-manifest.json +1 -1
  165. package/.next/static/chunks/0-mpa_947ipeq.js +1 -0
  166. package/.next/static/chunks/01lmbsd37fybu.js +1 -0
  167. package/.next/static/chunks/03o.h6kvmw4l_.js +1 -0
  168. package/.next/static/chunks/03~~oirxz7~vc.js +1 -0
  169. package/.next/static/chunks/05uk96gc~9mni.js +1 -0
  170. package/.next/static/chunks/08kf-.bgs10ze.js +1 -0
  171. package/.next/static/chunks/0ggj5ummw2a84.js +7 -0
  172. package/.next/static/chunks/0glmrdj9112tc.js +7 -0
  173. package/.next/static/chunks/0o40uf-rn28q6.js +1 -0
  174. package/.next/static/chunks/0q3hr1~viwzkt.js +4 -0
  175. package/.next/static/chunks/0rxrez_cjn.eh.js +1 -0
  176. package/.next/static/chunks/0x8x.29hkju5a.js +1 -0
  177. package/.next/static/chunks/0~ks9b48lw8hx.css +2 -0
  178. package/.next/static/chunks/13lvf-h-j8bmc.js +1 -0
  179. package/.next/static/chunks/174re5ar~kxne.js +1 -0
  180. package/.next/trace +2 -2
  181. package/.next/trace-build +1 -1
  182. package/app/components/ChatPopover.tsx +38 -2
  183. package/app/components/CommandPalette.tsx +107 -0
  184. package/app/components/HelpOverlay.tsx +126 -0
  185. package/app/components/TopoGraph.tsx +5927 -258
  186. package/app/components/utils.ts +8 -7
  187. package/app/globals.css +110 -5
  188. package/app/lib/time.ts +36 -0
  189. package/app/lib/vendorIdentity.ts +14 -3
  190. package/package.json +2 -2
  191. package/public/sleep2agi-logo.svg +11 -0
  192. package/public/vendors/claude.svg +11 -0
  193. package/public/vendors/minimax.svg +11 -0
  194. package/public/vendors/openai.svg +12 -0
  195. package/screenshots/r293-p0/after-full.png +0 -0
  196. package/screenshots/r293-p0/after-topo.png +0 -0
  197. package/screenshots/r293-p0/baseline-full.png +0 -0
  198. package/screenshots/r293-p0/baseline-topo.png +0 -0
  199. package/screenshots/r293-p0/logo-integrated-full.png +0 -0
  200. package/screenshots/r293-p0/logo-integrated-topo.png +0 -0
  201. package/scripts/help-overlay-topo-test.mjs +44 -0
  202. package/scripts/p0-topo-screenshot.mjs +82 -0
  203. package/scripts/topo-active-filter-pill-test.mjs +101 -0
  204. package/scripts/topo-active-links-chip-hover-test.mjs +103 -0
  205. package/scripts/topo-active-links-chip-nav-test.mjs +117 -0
  206. package/scripts/topo-active-links-chip-self-hover-test.mjs +171 -0
  207. package/scripts/topo-active-links-chip-test.mjs +73 -0
  208. package/scripts/topo-active-links-empty-recede-test.mjs +125 -0
  209. package/scripts/topo-active-links-freshness-test.mjs +113 -0
  210. package/scripts/topo-active-links-tooltip-test.mjs +79 -0
  211. package/scripts/topo-active-pulse-ease-test.mjs +120 -0
  212. package/scripts/topo-auto-fit-test.mjs +73 -0
  213. package/scripts/topo-brand-watermark-test.mjs +97 -0
  214. package/scripts/topo-canvas-aria-test.mjs +108 -0
  215. package/scripts/topo-chat-target-breath-test.mjs +84 -0
  216. package/scripts/topo-chat-target-ring-ease-test.mjs +82 -0
  217. package/scripts/topo-chat-target-ring-fade-test.mjs +124 -0
  218. package/scripts/topo-chip-empty-recede-test.mjs +116 -0
  219. package/scripts/topo-chip-focus-test.mjs +95 -0
  220. package/scripts/topo-chip-pin-mirror-test.mjs +113 -0
  221. package/scripts/topo-chip-row-semantic-gap-test.mjs +97 -0
  222. package/scripts/topo-chip-row-tabular-test.mjs +111 -0
  223. package/scripts/topo-chrome-a11y-test.mjs +107 -0
  224. package/scripts/topo-chrome-icon-stroke-test.mjs +95 -0
  225. package/scripts/topo-chrome-pop-extension-test.mjs +98 -0
  226. package/scripts/topo-chrome-pop-nodesize-test.mjs +88 -0
  227. package/scripts/topo-chrome-press-state-test.mjs +135 -0
  228. package/scripts/topo-chrome-strip-semantic-gap-test.mjs +99 -0
  229. package/scripts/topo-chrome-strip-theme-ease-test.mjs +99 -0
  230. package/scripts/topo-chrome-zoom-level-pop-test.mjs +122 -0
  231. package/scripts/topo-chrome-zoom-pop-test.mjs +130 -0
  232. package/scripts/topo-click-ripple-ease-test.mjs +94 -0
  233. package/scripts/topo-cmdk-edge-clear-test.mjs +109 -0
  234. package/scripts/topo-cmdk-layout-view-test.mjs +108 -0
  235. package/scripts/topo-cmdk-pin-test.mjs +123 -0
  236. package/scripts/topo-cmdk-vendor-clear-test.mjs +133 -0
  237. package/scripts/topo-cmdk-vendor-pin-test.mjs +103 -0
  238. package/scripts/topo-corner-radius-unify-test.mjs +103 -0
  239. package/scripts/topo-cwd-tooltip-test.mjs +64 -0
  240. package/scripts/topo-dblclick-reset-test.mjs +74 -0
  241. package/scripts/topo-dense-alias-fill-transition-test.mjs +133 -0
  242. package/scripts/topo-discrete-zoom-smooth-test.mjs +125 -0
  243. package/scripts/topo-edge-badge-click-pin-test.mjs +94 -0
  244. package/scripts/topo-edge-badge-crossfade-test.mjs +138 -0
  245. package/scripts/topo-edge-badge-hot-test.mjs +115 -0
  246. package/scripts/topo-edge-badge-hover-test.mjs +85 -0
  247. package/scripts/topo-edge-badge-lift-test.mjs +150 -0
  248. package/scripts/topo-edge-badge-ripple-test.mjs +111 -0
  249. package/scripts/topo-edge-badge-stroke-transition-test.mjs +118 -0
  250. package/scripts/topo-edge-badge-text-pin-test.mjs +121 -0
  251. package/scripts/topo-edge-badge-theme-ease-test.mjs +89 -0
  252. package/scripts/topo-edge-count-badge-test.mjs +86 -0
  253. package/scripts/topo-edge-endpoint-highlight-test.mjs +111 -0
  254. package/scripts/topo-edge-fadein-test.mjs +106 -0
  255. package/scripts/topo-edge-focus-test.mjs +113 -0
  256. package/scripts/topo-edge-hover-test.mjs +93 -0
  257. package/scripts/topo-edge-pill-hot-test.mjs +129 -0
  258. package/scripts/topo-edge-pill-test.mjs +105 -0
  259. package/scripts/topo-edge-ping-pulse-retired-test.mjs +119 -0
  260. package/scripts/topo-edge-stroke-ease-test.mjs +100 -0
  261. package/scripts/topo-edge-stroke-transition-test.mjs +132 -0
  262. package/scripts/topo-edge-tooltip-test.mjs +70 -0
  263. package/scripts/topo-empty-state-breath-test.mjs +150 -0
  264. package/scripts/topo-empty-state-crossfade-test.mjs +130 -0
  265. package/scripts/topo-empty-state-recenter-test.mjs +107 -0
  266. package/scripts/topo-endpoint-ring-fade-test.mjs +132 -0
  267. package/scripts/topo-endpoint-ring-test.mjs +93 -0
  268. package/scripts/topo-endpoint-ring-thicken-test.mjs +112 -0
  269. package/scripts/topo-esc-clears-pin-test.mjs +98 -0
  270. package/scripts/topo-filter-pill-aliases-test.mjs +121 -0
  271. package/scripts/topo-filter-pill-body-click-test.mjs +112 -0
  272. package/scripts/topo-filter-pill-count-test.mjs +110 -0
  273. package/scripts/topo-filter-pill-mobile-test.mjs +90 -0
  274. package/scripts/topo-fit-key-test.mjs +106 -0
  275. package/scripts/topo-freshness-chip-test.mjs +74 -0
  276. package/scripts/topo-freshness-chip-transition-test.mjs +80 -0
  277. package/scripts/topo-freshness-conditional-render-test.mjs +92 -0
  278. package/scripts/topo-fullscreen-active-test.mjs +115 -0
  279. package/scripts/topo-group-box-pinned-state-test.mjs +95 -0
  280. package/scripts/topo-group-count-test.mjs +6 -1
  281. package/scripts/topo-group-label-a11y-test.mjs +113 -0
  282. package/scripts/topo-group-label-count-inherit-test.mjs +99 -0
  283. package/scripts/topo-group-label-hover-test.mjs +119 -0
  284. package/scripts/topo-group-label-pin-spacing-test.mjs +136 -0
  285. package/scripts/topo-group-label-tint-test.mjs +99 -0
  286. package/scripts/topo-group-label-title-test.mjs +83 -0
  287. package/scripts/topo-group-pin-test.mjs +119 -0
  288. package/scripts/topo-group-pip-fadein-test.mjs +100 -0
  289. package/scripts/topo-group-pip-tabular-test.mjs +95 -0
  290. package/scripts/topo-group-status-pips-test.mjs +103 -0
  291. package/scripts/topo-groupbox-fadein-test.mjs +95 -0
  292. package/scripts/topo-groupbox-hover-lift-test.mjs +127 -0
  293. package/scripts/topo-groupbox-hubcore-ease-test.mjs +106 -0
  294. package/scripts/topo-groupbox-live-test.mjs +100 -0
  295. package/scripts/topo-groupbox-march-busyness-test.mjs +155 -0
  296. package/scripts/topo-groupbox-test.mjs +4 -2
  297. package/scripts/topo-help-overlay-r109-test.mjs +67 -0
  298. package/scripts/topo-help-overlay-r118-test.mjs +69 -0
  299. package/scripts/topo-help-overlay-r123-test.mjs +69 -0
  300. package/scripts/topo-help-overlay-r134-test.mjs +74 -0
  301. package/scripts/topo-help-overlay-r137-test.mjs +81 -0
  302. package/scripts/topo-help-overlay-r141-test.mjs +86 -0
  303. package/scripts/topo-help-overlay-r153-test.mjs +85 -0
  304. package/scripts/topo-help-overlay-r59-test.mjs +67 -0
  305. package/scripts/topo-help-overlay-r65-test.mjs +64 -0
  306. package/scripts/topo-help-overlay-r70-test.mjs +63 -0
  307. package/scripts/topo-help-overlay-r78-test.mjs +59 -0
  308. package/scripts/topo-help-overlay-r81-test.mjs +58 -0
  309. package/scripts/topo-help-overlay-r87-test.mjs +64 -0
  310. package/scripts/topo-help-overlay-r91-test.mjs +65 -0
  311. package/scripts/topo-hot-tail-crossfade-test.mjs +117 -0
  312. package/scripts/topo-html-overlay-padding-unify-test.mjs +120 -0
  313. package/scripts/topo-hub-a11y-test.mjs +112 -0
  314. package/scripts/topo-hub-busyness-test.mjs +100 -0
  315. package/scripts/topo-hub-center-crossfade-test.mjs +124 -0
  316. package/scripts/topo-hub-click-fit-test.mjs +137 -0
  317. package/scripts/topo-hub-digit-scale-test.mjs +129 -0
  318. package/scripts/topo-hub-fadein-test.mjs +88 -0
  319. package/scripts/topo-hub-hover-lift-test.mjs +101 -0
  320. package/scripts/topo-hub-hover-ring-test.mjs +82 -0
  321. package/scripts/topo-hub-pip-theme-ease-test.mjs +116 -0
  322. package/scripts/topo-hub-spoke-ease-test.mjs +120 -0
  323. package/scripts/topo-hub-title-test.mjs +93 -0
  324. package/scripts/topo-hub-working-count-test.mjs +99 -0
  325. package/scripts/topo-ingroup-edge-test.mjs +103 -0
  326. package/scripts/topo-inner-radar-ring-retired-test.mjs +89 -0
  327. package/scripts/topo-kicker-color-test.mjs +93 -0
  328. package/scripts/topo-kicker-tracking-test.mjs +101 -0
  329. package/scripts/topo-label-card-theme-ease-test.mjs +85 -0
  330. package/scripts/topo-label-lift-test.mjs +119 -0
  331. package/scripts/topo-lastseen-tooltip-test.mjs +59 -0
  332. package/scripts/topo-layout-hover-text-preview-test.mjs +101 -0
  333. package/scripts/topo-layout-key-test.mjs +91 -0
  334. package/scripts/topo-layout-switch-crossfade-test.mjs +126 -0
  335. package/scripts/topo-layout-toggle-border-unify-test.mjs +104 -0
  336. package/scripts/topo-layout-toggle-test.mjs +131 -0
  337. package/scripts/topo-legend-compress-test.mjs +107 -0
  338. package/scripts/topo-legend-count-empty-test.mjs +126 -0
  339. package/scripts/topo-legend-count-tabular-parity-test.mjs +90 -0
  340. package/scripts/topo-legend-count-tabular-test.mjs +87 -0
  341. package/scripts/topo-legend-count-test.mjs +88 -0
  342. package/scripts/topo-legend-count-tier-fill-test.mjs +121 -0
  343. package/scripts/topo-legend-header-symmetric-inset-test.mjs +112 -0
  344. package/scripts/topo-legend-hitbox-swatch-center-test.mjs +93 -0
  345. package/scripts/topo-legend-hover-test.mjs +113 -0
  346. package/scripts/topo-legend-offline-delimiter-test.mjs +84 -0
  347. package/scripts/topo-legend-panel-header-test.mjs +83 -0
  348. package/scripts/topo-legend-pin-ring-fade-test.mjs +112 -0
  349. package/scripts/topo-legend-pin-test.mjs +128 -0
  350. package/scripts/topo-legend-row-hover-lift-test.mjs +109 -0
  351. package/scripts/topo-legend-row-pin-spacing-test.mjs +124 -0
  352. package/scripts/topo-legend-row-tint-test.mjs +95 -0
  353. package/scripts/topo-legend-row-title-test.mjs +102 -0
  354. package/scripts/topo-legend-swatch-grow-test.mjs +116 -0
  355. package/scripts/topo-legend-swatch-radius-test.mjs +78 -0
  356. package/scripts/topo-minimap-a11y-test.mjs +101 -0
  357. package/scripts/topo-minimap-dot-transition-test.mjs +113 -0
  358. package/scripts/topo-minimap-rect-stroke-test.mjs +94 -0
  359. package/scripts/topo-minimap-test.mjs +68 -0
  360. package/scripts/topo-minimap-viewport-smooth-test.mjs +124 -0
  361. package/scripts/topo-mobile-chips-test.mjs +103 -0
  362. package/scripts/topo-monogram-font-test.mjs +112 -0
  363. package/scripts/topo-monogram-stroke-test.mjs +101 -0
  364. package/scripts/topo-node-a11y-test.mjs +107 -0
  365. package/scripts/topo-node-hover-lift-test.mjs +85 -0
  366. package/scripts/topo-node-label-card-elevation-test.mjs +157 -0
  367. package/scripts/topo-node-label-card-stroke-test.mjs +135 -0
  368. package/scripts/topo-node-stroke-transition-test.mjs +103 -0
  369. package/scripts/topo-node-text-fill-transition-test.mjs +119 -0
  370. package/scripts/topo-node-title-peers-test.mjs +107 -0
  371. package/scripts/topo-node-title-test.mjs +101 -0
  372. package/scripts/topo-nodesize-active-hover-test.mjs +109 -0
  373. package/scripts/topo-nodesize-crossfade-test.mjs +141 -0
  374. package/scripts/topo-online-chip-nav-test.mjs +143 -0
  375. package/scripts/topo-orbit-particles-retired-test.mjs +91 -0
  376. package/scripts/topo-overlap-test.mjs +32 -5
  377. package/scripts/topo-panel-elevation-test.mjs +76 -0
  378. package/scripts/topo-panel-fadein-test.mjs +102 -0
  379. package/scripts/topo-panel-hot-tail-fade-test.mjs +132 -0
  380. package/scripts/topo-panel-hover-elevation-test.mjs +118 -0
  381. package/scripts/topo-panel-theme-ease-test.mjs +85 -0
  382. package/scripts/topo-panel-title-fill-ease-test.mjs +91 -0
  383. package/scripts/topo-particle-stagger-test.mjs +82 -0
  384. package/scripts/topo-pin-intersection-color-ease-test.mjs +111 -0
  385. package/scripts/topo-pin-intersection-empty-test.mjs +129 -0
  386. package/scripts/topo-pin-intersection-tabular-test.mjs +96 -0
  387. package/scripts/topo-pin-intersection-test.mjs +121 -0
  388. package/scripts/topo-pin-intersection-warning-crossfade-test.mjs +107 -0
  389. package/scripts/topo-pin-mirror-transition-test.mjs +101 -0
  390. package/scripts/topo-pin-persistence-test.mjs +105 -0
  391. package/scripts/topo-popover-meta-test.mjs +78 -0
  392. package/scripts/topo-prepublish-guard-test.mjs +95 -0
  393. package/scripts/topo-pressure-bar-test.mjs +69 -0
  394. package/scripts/topo-pressure-hover-test.mjs +123 -0
  395. package/scripts/topo-pressure-pin-test.mjs +119 -0
  396. package/scripts/topo-pressure-seg-self-hover-test.mjs +126 -0
  397. package/scripts/topo-pressure-seg-tooltip-test.mjs +98 -0
  398. package/scripts/topo-pressure-seg-transition-test.mjs +107 -0
  399. package/scripts/topo-pulse-dot-crossfade-test.mjs +122 -0
  400. package/scripts/topo-pulse-dot-retired-test.mjs +86 -0
  401. package/scripts/topo-pulse-rate-test.mjs +71 -0
  402. package/scripts/topo-recent-panel-count-freshness-test.mjs +109 -0
  403. package/scripts/topo-recent-panel-count-test.mjs +72 -0
  404. package/scripts/topo-recent-panel-footer-breath-test.mjs +142 -0
  405. package/scripts/topo-recent-panel-hot-header-test.mjs +132 -0
  406. package/scripts/topo-recent-panel-more-crossfade-test.mjs +124 -0
  407. package/scripts/topo-recent-panel-more-cyan-hover-test.mjs +151 -0
  408. package/scripts/topo-recent-panel-more-nav-test.mjs +127 -0
  409. package/scripts/topo-recent-panel-more-test.mjs +106 -0
  410. package/scripts/topo-recent-panel-readability-bump-test.mjs +151 -0
  411. package/scripts/topo-recent-row-count-fill-test.mjs +129 -0
  412. package/scripts/topo-recent-row-fadein-test.mjs +107 -0
  413. package/scripts/topo-recent-row-freshness-test.mjs +102 -0
  414. package/scripts/topo-recent-row-hot-test.mjs +110 -0
  415. package/scripts/topo-recent-row-hover-lift-test.mjs +128 -0
  416. package/scripts/topo-recent-row-hover-test.mjs +122 -0
  417. package/scripts/topo-recent-row-pin-spacing-test.mjs +137 -0
  418. package/scripts/topo-recent-row-pin-test.mjs +126 -0
  419. package/scripts/topo-recent-row-tint-test.mjs +91 -0
  420. package/scripts/topo-recent-row-title-test.mjs +112 -0
  421. package/scripts/topo-recent-row-ts-alpha-test.mjs +100 -0
  422. package/scripts/topo-recent-row-ts-test.mjs +95 -0
  423. package/scripts/topo-recent-row-typography-test.mjs +119 -0
  424. package/scripts/topo-recent-signal-empty-hint-test.mjs +73 -0
  425. package/scripts/topo-recent-signal-empty-test.mjs +63 -0
  426. package/scripts/topo-reduced-motion-test.mjs +77 -0
  427. package/scripts/topo-reset-spin-test.mjs +120 -0
  428. package/scripts/topo-runtime-badge-grow-test.mjs +114 -0
  429. package/scripts/topo-spokes-retired-test.mjs +93 -0
  430. package/scripts/topo-starfield-density-test.mjs +89 -0
  431. package/scripts/topo-status-chip-hover-test.mjs +101 -0
  432. package/scripts/topo-status-chip-tooltip-test.mjs +95 -0
  433. package/scripts/topo-statusbar-chips-self-hover-test.mjs +177 -0
  434. package/scripts/topo-svg-focus-test.mjs +112 -0
  435. package/scripts/topo-sweep-busyness-test.mjs +94 -0
  436. package/scripts/topo-tabular-nums-sweep-test.mjs +93 -0
  437. package/scripts/topo-tier-ring-fadein-test.mjs +107 -0
  438. package/scripts/topo-tier-ring-occupancy-test.mjs +87 -0
  439. package/scripts/topo-tier-ring-test.mjs +69 -0
  440. package/scripts/topo-tier-ring-tint-test.mjs +110 -0
  441. package/scripts/topo-tier-stagger-test.mjs +89 -0
  442. package/scripts/topo-title-block-tight-leading-test.mjs +95 -0
  443. package/scripts/topo-title-tracking-test.mjs +98 -0
  444. package/scripts/topo-toggle-inactive-cyan-hover-test.mjs +110 -0
  445. package/scripts/topo-top-rail-theme-ease-test.mjs +89 -0
  446. package/scripts/topo-tz-ghost-test.mjs +69 -0
  447. package/scripts/topo-vendor-chip-hover-test.mjs +111 -0
  448. package/scripts/topo-vendor-chip-self-hover-test.mjs +131 -0
  449. package/scripts/topo-vendor-chip-tabular-test.mjs +92 -0
  450. package/scripts/topo-vendor-chip-threshold-test.mjs +78 -0
  451. package/scripts/topo-vendor-letter-tooltip-test.mjs +92 -0
  452. package/scripts/topo-vendor-pill-test.mjs +125 -0
  453. package/scripts/topo-vendor-pin-test.mjs +125 -0
  454. package/scripts/topo-view-smooth-test.mjs +131 -0
  455. package/scripts/topo-watermark-tracking-test.mjs +99 -0
  456. package/scripts/topo-working-chip-pin-test.mjs +154 -0
  457. package/scripts/topo-working-halo-breath-retired-test.mjs +99 -0
  458. package/scripts/topo-wrapper-flow-arrow-theme-test.mjs +97 -0
  459. package/scripts/topo-wrapper-shadow-theme-ease-test.mjs +89 -0
  460. package/.next/static/chunks/0-7iowzu4.798.js +0 -1
  461. package/.next/static/chunks/01u5zo8b7r_r3.js +0 -1
  462. package/.next/static/chunks/02t5jr4shh.hy.js +0 -1
  463. package/.next/static/chunks/09nd.t_hd.y6t.css +0 -2
  464. package/.next/static/chunks/0_qfg5s5uzs7..js +0 -7
  465. package/.next/static/chunks/0elalb9n_.~di.js +0 -1
  466. package/.next/static/chunks/0fqit.b4j_6rz.js +0 -1
  467. package/.next/static/chunks/0j_q__o8p6g83.js +0 -1
  468. package/.next/static/chunks/0jl6_w50zh4l5.js +0 -1
  469. package/.next/static/chunks/0pl7l_.2im.j0.js +0 -7
  470. package/.next/static/chunks/0qcfcgdthhos6.js +0 -1
  471. package/.next/static/chunks/0r4q73.-1bkyl.js +0 -1
  472. package/.next/static/chunks/0r_c8eccg3z2o.js +0 -1
  473. package/.next/static/chunks/10oi7l-tycgl9.js +0 -1
  474. package/.next/static/chunks/11uk1izuv3~0t.js +0 -1
  475. /package/.next/static/{mgs4E0Fu2JlZsA5DB0XUu → Kkkh4U0z1GCAKfQMsfmjt}/_buildManifest.js +0 -0
  476. /package/.next/static/{mgs4E0Fu2JlZsA5DB0XUu → Kkkh4U0z1GCAKfQMsfmjt}/_clientMiddlewareManifest.js +0 -0
  477. /package/.next/static/{mgs4E0Fu2JlZsA5DB0XUu → Kkkh4U0z1GCAKfQMsfmjt}/_ssgManifest.js +0 -0
@@ -0,0 +1,97 @@
1
+ /* Round 260 verification: chip-row semantic gap — Layout toggle (control)
2
+ * separated from display chips by an extra 4px (mr-1 stacks on parent
3
+ * gap-2 → effective 12px).
4
+ *
5
+ * Pre-R260 the header chip-row rendered all 8 children at uniform
6
+ * gap-2 (8px):
7
+ *
8
+ * [Ring|Grid] [N working] [N online] [pressure ▮▮] [A:3 ?:1] [N active links] [filter…] [live · Ns]
9
+ * 8 8 8 8 8 8 8
10
+ *
11
+ * Spatial signal said "8 separate things" — but semantically only the
12
+ * Layout toggle is a CONTROL (changes layout mode); everything that
13
+ * follows is READ-ONLY display chrome. R260 widens the gap before the
14
+ * first display chip via mr-1 on the Layout toggle wrapper:
15
+ *
16
+ * [Ring|Grid] 12px [N working] 8 [N online] 8 [pressure ▮▮] …
17
+ * ↑
18
+ * control → display boundary
19
+ *
20
+ * Classic law-of-proximity polish — same pattern R255 applied to the
21
+ * bottom-right chrome strip (fleet vs view).
22
+ *
23
+ * Test scope:
24
+ * 1. Layout toggle present + tagged with data-topo-chrome-layout-trailer.
25
+ * 2. Gap from Layout toggle's right edge to working chip's left edge
26
+ * is ≥ 11px (target 12px, allow 1px sub-pixel slop).
27
+ * 3. Adjacent display chips' gap stays ~8px (working → online ∈ [6,10]).
28
+ * 4. Vertical center alignment preserved between Layout toggle and
29
+ * the working chip (Δ ≤ 1px).
30
+ */
31
+ import { chromium } from 'playwright';
32
+ import { readFileSync } from 'node:fs';
33
+
34
+ const TOKEN = JSON.parse(readFileSync('/home/vansin/.anet/config.json', 'utf8')).token;
35
+ const browser = await chromium.launch({ headless: true });
36
+ const ctx = await browser.newContext({ viewport: { width: 1500, height: 1500 } });
37
+ await ctx.addCookies([{ name: 'anet_dashboard_session', value: `v3:${TOKEN}`, domain: '127.0.0.1', path: '/' }]);
38
+ await ctx.addInitScript(() => {
39
+ try { localStorage.setItem('anet-theme', 'cyber'); sessionStorage.setItem('anet_v3_auth', '1'); } catch {}
40
+ });
41
+ const fresh = new Date(Date.now() - 60 * 1000).toISOString();
42
+ await ctx.route('**/api/hub/status*', async (route) => {
43
+ const r = await route.fetch();
44
+ const b = await r.json();
45
+ const nid = (b.sessions || [])[0]?.network_id || 'default';
46
+ const mk = (alias) => ({
47
+ alias, status: 'working', model: 'claude-opus-4', runtime: 'claude-code-cli',
48
+ network_id: nid, project_dir: null,
49
+ created_at: fresh, updated_at: fresh, last_seen_at: fresh,
50
+ });
51
+ await route.fulfill({ response: r, json: { ...b, sessions: [
52
+ mk('alpha'), mk('beta'), mk('gamma'), mk('delta'),
53
+ ] } });
54
+ });
55
+ await ctx.route('**/api/hub/messages*', (r) => r.fulfill({ json: { messages: [] } }));
56
+ await ctx.route('**/api/hub/tasks*', (r) => r.fulfill({ json: { tasks: [] } }));
57
+
58
+ const page = await ctx.newPage();
59
+ await page.goto('http://127.0.0.1:3000/', { waitUntil: 'domcontentloaded' });
60
+ await page.waitForFunction(() => document.querySelectorAll('g[data-node]').length === 4, { timeout: 30000 });
61
+ await page.waitForSelector('[data-topo-chrome-layout-trailer]', { timeout: 10000 });
62
+ await page.waitForSelector('[data-working-chip]', { timeout: 10000 });
63
+ await page.waitForSelector('[data-online-chip]', { timeout: 10000 });
64
+ await page.waitForTimeout(300);
65
+
66
+ const probe = await page.evaluate(() => {
67
+ const trailer = document.querySelector('[data-topo-chrome-layout-trailer]');
68
+ const working = document.querySelector('[data-working-chip]');
69
+ const online = document.querySelector('[data-online-chip]');
70
+ const r = (el) => el ? el.getBoundingClientRect() : null;
71
+ return {
72
+ trailer: r(trailer),
73
+ working: r(working),
74
+ online: r(online),
75
+ };
76
+ });
77
+ await browser.close();
78
+
79
+ const gapToggleToWorking = (probe.trailer && probe.working) ? probe.working.left - probe.trailer.right : null;
80
+ const gapWorkingToOnline = (probe.working && probe.online) ? probe.online.left - probe.working.right : null;
81
+ const yCenterDelta = (probe.trailer && probe.working)
82
+ ? Math.abs((probe.trailer.top + probe.trailer.height / 2) - (probe.working.top + probe.working.height / 2))
83
+ : null;
84
+
85
+ const results = {
86
+ trailer_present: probe.trailer !== null,
87
+ working_present: probe.working !== null,
88
+ online_present: probe.online !== null,
89
+ toggle_to_working_gap_widened: gapToggleToWorking != null && gapToggleToWorking >= 11,
90
+ working_to_online_gap_unchanged: gapWorkingToOnline != null && gapWorkingToOnline >= 6 && gapWorkingToOnline <= 10,
91
+ y_center_aligned: yCenterDelta != null && yCenterDelta <= 1,
92
+ };
93
+ const ok = Object.values(results).every(Boolean);
94
+ console.log(`${ok ? '✅' : '❌'} chip-row semantic gap:`, JSON.stringify(results),
95
+ '\n gaps: toggle→working =', gapToggleToWorking, 'working→online =', gapWorkingToOnline,
96
+ '\n yCenterΔ:', yCenterDelta);
97
+ process.exit(ok ? 0 : 1);
@@ -0,0 +1,111 @@
1
+ /* Round 232 verification: HTML chip row (working / online / active-
2
+ * links) gains the Tailwind `tabular-nums` utility class so the digit
3
+ * width stays stable across counter rollovers (9→10, 99→100).
4
+ *
5
+ * 7th surface in the info-density tabular-nums sweep — first on the
6
+ * HTML side (previous 6 were SVG <text>/<tspan>):
7
+ * R224 edge midpoint badge digit
8
+ * R225 hub center digit
9
+ * R225 recent panel header tspan
10
+ * R225 recent row count tspan
11
+ * R229 group-label · count chip
12
+ * R230 R58 status pip strip × 3 tiers
13
+ * R232 chip row × 3 chips (this round)
14
+ *
15
+ * Scenario: 4 working agents + 1 flow alpha→beta count=5. Drives
16
+ * workingCount=4, onlineNodes.length=4, flowLinks.length=1 → all
17
+ * three chips render with non-empty digits.
18
+ *
19
+ * Verifies for each chip:
20
+ * - element present at its data attr selector
21
+ * - getComputedStyle().fontVariantNumeric includes 'tabular-nums'
22
+ * - textContent starts with the expected digit (sanity)
23
+ */
24
+ import { chromium } from 'playwright';
25
+ import { readFileSync } from 'node:fs';
26
+
27
+ const TOKEN = JSON.parse(readFileSync('/home/vansin/.anet/config.json', 'utf8')).token;
28
+ const browser = await chromium.launch({ headless: true });
29
+ const ctx = await browser.newContext({ viewport: { width: 1500, height: 1500 } });
30
+ await ctx.addCookies([{ name: 'anet_dashboard_session', value: `v3:${TOKEN}`, domain: '127.0.0.1', path: '/' }]);
31
+ await ctx.addInitScript(() => {
32
+ try { localStorage.setItem('anet-theme', 'cyber'); sessionStorage.setItem('anet_v3_auth', '1'); } catch {}
33
+ });
34
+ const fresh = new Date(Date.now() - 60 * 1000).toISOString();
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: [
45
+ mk('alpha'), mk('beta'), mk('gamma'), mk('delta'),
46
+ ] } });
47
+ });
48
+ const now = Date.now();
49
+ const msgs = [];
50
+ for (let i = 0; i < 5; i++) {
51
+ msgs.push({
52
+ id: `m${i}`, from_alias: 'alpha', to_alias: 'beta', content: 'hi',
53
+ network_id: 'default', created_at: new Date(now - (1000 + i * 50)).toISOString(),
54
+ });
55
+ }
56
+ await ctx.route('**/api/hub/messages*', (r2) => r2.fulfill({ json: { messages: msgs } }));
57
+ await ctx.route('**/api/hub/tasks*', (r2) => r2.fulfill({ json: { tasks: [] } }));
58
+
59
+ const page = await ctx.newPage();
60
+ await page.goto('http://127.0.0.1:3000/', { waitUntil: 'domcontentloaded' });
61
+ await page.waitForFunction(() => document.querySelectorAll('g[data-node]').length === 4, { timeout: 30000 });
62
+ await page.waitForSelector('[data-working-chip]', { timeout: 10000, state: 'attached' });
63
+ await page.waitForSelector('[data-online-chip]', { timeout: 10000, state: 'attached' });
64
+ await page.waitForSelector('[data-active-links-chip]', { timeout: 10000, state: 'attached' });
65
+ await page.waitForTimeout(300);
66
+
67
+ const out = await page.evaluate(() => {
68
+ const grab = (sel, expectedPrefix) => {
69
+ const el = document.querySelector(sel);
70
+ if (!el) return null;
71
+ return {
72
+ present: true,
73
+ fontVarNumeric: getComputedStyle(el).fontVariantNumeric,
74
+ hasUtility: el.className.split(/\s+/).includes('tabular-nums'),
75
+ textStartsWith: (el.textContent || '').trim().startsWith(expectedPrefix),
76
+ text: (el.textContent || '').trim().slice(0, 30),
77
+ };
78
+ };
79
+ return {
80
+ working: grab('[data-working-chip]', '4 working'),
81
+ online: grab('[data-online-chip]', '4 online'),
82
+ activeLinks: grab('[data-active-links-chip]', '1 active'),
83
+ };
84
+ });
85
+ await browser.close();
86
+
87
+ const hasTab = (s) => /tabular-nums/.test(s || '');
88
+ const present = (o) => o && o.present;
89
+
90
+ const results = {
91
+ working_present: present(out.working),
92
+ working_class_utility: out.working?.hasUtility === true,
93
+ working_fvn_tabular: hasTab(out.working?.fontVarNumeric),
94
+ working_text_ok: out.working?.textStartsWith === true,
95
+
96
+ online_present: present(out.online),
97
+ online_class_utility: out.online?.hasUtility === true,
98
+ online_fvn_tabular: hasTab(out.online?.fontVarNumeric),
99
+ online_text_ok: out.online?.textStartsWith === true,
100
+
101
+ active_present: present(out.activeLinks),
102
+ active_class_utility: out.activeLinks?.hasUtility === true,
103
+ active_fvn_tabular: hasTab(out.activeLinks?.fontVarNumeric),
104
+ active_text_ok: out.activeLinks?.textStartsWith === true,
105
+ };
106
+ const ok = Object.values(results).every(Boolean);
107
+ console.log(`${ok ? '✅' : '❌'} chip row tabular-nums:`, JSON.stringify(results),
108
+ '\n working: ', out.working,
109
+ '\n online: ', out.online,
110
+ '\n activeLinks:', out.activeLinks);
111
+ process.exit(ok ? 0 : 1);
@@ -0,0 +1,107 @@
1
+ /* Round 154 verification: TopoGraph chrome buttons gain stable
2
+ * data-* hooks for tests + focus-visible ring matching the
3
+ * dashboard's cyan accent (browser default focus outline often
4
+ * vanishes on the dark canvas).
5
+ *
6
+ * Chrome inventory (bottom-right of canvas):
7
+ * data-topo-chrome (wrapper div)
8
+ * data-topo-chrome-nodesize=S|M|L (segmented control, R113)
9
+ * data-topo-chrome-nodesize-active="true|false"
10
+ * data-topo-chrome-zoom-out (R104)
11
+ * data-topo-chrome-zoom-level (readout, also R104)
12
+ * data-topo-chrome-zoom-in
13
+ * data-topo-chrome-reset
14
+ * data-topo-chrome-fullscreen
15
+ * data-topo-chrome-fullscreen-active="true|false"
16
+ *
17
+ * Each button gains focus-visible:ring-1 ring-cyan-400/60. Tabs
18
+ * land somewhere visible.
19
+ *
20
+ * Test: every chrome button surfaces its data attribute, plus the
21
+ * three S/M/L buttons report active correctly when one is picked.
22
+ */
23
+ import { chromium } from 'playwright';
24
+ import { readFileSync } from 'node:fs';
25
+
26
+ const TOKEN = JSON.parse(readFileSync('/home/vansin/.anet/config.json', 'utf8')).token;
27
+ const browser = await chromium.launch({ headless: true });
28
+
29
+ const ctx = await browser.newContext({ viewport: { width: 1400, height: 1500 } });
30
+ await ctx.addCookies([{ name: 'anet_dashboard_session', value: `v3:${TOKEN}`, domain: '127.0.0.1', path: '/' }]);
31
+ await ctx.addInitScript(() => {
32
+ try { localStorage.setItem('anet-theme', 'cyber'); sessionStorage.setItem('anet_v3_auth', '1'); } catch {}
33
+ });
34
+ const fresh = new Date(Date.now() - 60 * 1000).toISOString();
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: 'cli-claude-code',
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('alpha'), mk('beta')] } });
45
+ });
46
+ await ctx.route('**/api/hub/messages*', (route) => route.fulfill({ json: { messages: [] } }));
47
+ await ctx.route('**/api/hub/tasks*', (route) => route.fulfill({ json: { tasks: [] } }));
48
+
49
+ const page = await ctx.newPage();
50
+ await page.goto('http://127.0.0.1:3000/', { waitUntil: 'domcontentloaded' });
51
+ await page.waitForFunction(() => document.querySelectorAll('g[data-node]').length === 2, { timeout: 30000 });
52
+ await page.waitForSelector('[data-topo-chrome]', { timeout: 10000 });
53
+ await page.waitForTimeout(300);
54
+
55
+ const inspect = () => page.evaluate(() => {
56
+ const sel = (s) => document.querySelector(s);
57
+ const all = (s) => [...document.querySelectorAll(s)];
58
+ return {
59
+ wrapper: !!sel('[data-topo-chrome]'),
60
+ nodesizeS: sel('[data-topo-chrome-nodesize="S"]')?.getAttribute('data-topo-chrome-nodesize-active'),
61
+ nodesizeM: sel('[data-topo-chrome-nodesize="M"]')?.getAttribute('data-topo-chrome-nodesize-active'),
62
+ nodesizeL: sel('[data-topo-chrome-nodesize="L"]')?.getAttribute('data-topo-chrome-nodesize-active'),
63
+ zoomOut: !!sel('[data-topo-chrome-zoom-out]'),
64
+ zoomLevel: sel('[data-topo-chrome-zoom-level]')?.textContent?.trim(),
65
+ zoomIn: !!sel('[data-topo-chrome-zoom-in]'),
66
+ reset: !!sel('[data-topo-chrome-reset]'),
67
+ fullscreen: !!sel('[data-topo-chrome-fullscreen]'),
68
+ fullscreenActive: sel('[data-topo-chrome-fullscreen]')?.getAttribute('data-topo-chrome-fullscreen-active'),
69
+ // focus-visible ring is a CSS pseudo-class; just verify the
70
+ // className carries the focus-visible:ring tokens.
71
+ chromeButtonsHaveFocusRing: all('[data-topo-chrome] button').every(b =>
72
+ (b.className || '').includes('focus-visible:ring')),
73
+ };
74
+ });
75
+
76
+ const before = await inspect();
77
+
78
+ // Click L → it becomes active, M becomes inactive (default)
79
+ await page.locator('[data-topo-chrome-nodesize="L"]').click();
80
+ await page.waitForTimeout(150);
81
+ const afterL = await inspect();
82
+
83
+ await browser.close();
84
+
85
+ const results = {
86
+ wrapper_present: before.wrapper === true,
87
+ nodesizeS_present: before.nodesizeS === 'false',
88
+ nodesizeM_activeDefault: before.nodesizeM === 'true', // default scale 0.84 → M
89
+ nodesizeL_present: before.nodesizeL === 'false',
90
+ zoomOut_present: before.zoomOut === true,
91
+ zoomLevel_100pct: before.zoomLevel === '100%',
92
+ zoomIn_present: before.zoomIn === true,
93
+ reset_present: before.reset === true,
94
+ fullscreen_present: before.fullscreen === true,
95
+ fullscreenActive_false: before.fullscreenActive === 'false',
96
+ focusRing_onAllButtons: before.chromeButtonsHaveFocusRing === true,
97
+
98
+ // After clicking L: active flips to L
99
+ afterL_LActive: afterL.nodesizeL === 'true',
100
+ afterL_MInactive: afterL.nodesizeM === 'false',
101
+ afterL_SInactive: afterL.nodesizeS === 'false',
102
+ };
103
+ const ok = Object.values(results).every(Boolean);
104
+ console.log(`${ok ? '✅' : '❌'} chrome a11y:`, JSON.stringify(results),
105
+ `\n before=`, before,
106
+ `\n afterL=`, afterL);
107
+ process.exit(ok ? 0 : 1);
@@ -0,0 +1,95 @@
1
+ /* Round 288 verification: chrome strip icon strokeWidth unification.
2
+ *
3
+ * Pre-R288 the five chrome icons in the bottom-right strip carried
4
+ * two different stroke weights:
5
+ * zoom-in : strokeWidth 2.5
6
+ * zoom-out : strokeWidth 2.5
7
+ * reset : strokeWidth 2 ← outlier
8
+ * fullscreen : strokeWidth 2 ← outlier
9
+ * Operators reading the strip horizontally saw zoom icons rendering
10
+ * heavier than their reset/fullscreen siblings — same inconsistency
11
+ * R268 closed for chrome border colors.
12
+ *
13
+ * Post-R288: all five icons render at strokeWidth 2.5.
14
+ *
15
+ * Test scope:
16
+ * 1. zoom-in/zoom-out icons retain 2.5 (regression — no change).
17
+ * 2. reset icon stroke-width === '2.5'.
18
+ * 3. fullscreen icon (whichever variant rendered) stroke-width === '2.5'.
19
+ * 4. R287 minimap rect strokeWidth=1.5 still in place.
20
+ * 5. R283 monogram stroke + R282 watermark intact.
21
+ */
22
+ import { chromium } from 'playwright';
23
+ import { readFileSync } from 'node:fs';
24
+
25
+ const TOKEN = JSON.parse(readFileSync('/home/vansin/.anet/config.json', 'utf8')).token;
26
+ const browser = await chromium.launch({ headless: true });
27
+ const ctx = await browser.newContext({ viewport: { width: 1500, height: 1500 } });
28
+ await ctx.addCookies([{ name: 'anet_dashboard_session', value: `v3:${TOKEN}`, domain: '127.0.0.1', path: '/' }]);
29
+ await ctx.addInitScript(() => {
30
+ try { localStorage.setItem('anet-theme', 'cyber'); sessionStorage.setItem('anet_v3_auth', '1'); } catch {}
31
+ });
32
+ const fresh = new Date(Date.now() - 60 * 1000).toISOString();
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, model) => ({
38
+ alias, status: 'working', model, 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: [
43
+ mk('alpha', 'claude-opus-4'),
44
+ mk('beta', 'gpt-4o'),
45
+ ] } });
46
+ });
47
+ await ctx.route('**/api/hub/messages*', (r) => r.fulfill({ json: { messages: [] } }));
48
+ await ctx.route('**/api/hub/tasks*', (r) => r.fulfill({ json: { tasks: [] } }));
49
+
50
+ const page = await ctx.newPage();
51
+ await page.goto('http://127.0.0.1:3000/', { waitUntil: 'domcontentloaded' });
52
+ await page.waitForSelector('[data-topo-chrome-zoom-in-icon]', { timeout: 15000 });
53
+ await page.waitForSelector('[data-topo-brand-watermark]', { timeout: 10000 });
54
+ await page.waitForTimeout(300);
55
+
56
+ const probe = await page.evaluate(() => {
57
+ const zin = document.querySelector('[data-topo-chrome-zoom-in-icon]');
58
+ const zout = document.querySelector('[data-topo-chrome-zoom-out-icon]');
59
+ const reset = document.querySelector('[data-topo-chrome-reset-icon]');
60
+ const fs = document.querySelector('[data-topo-chrome-fullscreen-icon]');
61
+ const alphaNode = document.querySelector('g[data-node="alpha"]');
62
+ const alphaCircles = alphaNode ? [...alphaNode.querySelectorAll('circle')] : [];
63
+ const alphaAvatarCircle = alphaCircles
64
+ .map(c => ({ r: +c.getAttribute('r') || 0, sw: c.getAttribute('stroke-width'), isBadge: c.hasAttribute('data-runtime-badge') }))
65
+ .filter(c => c.r > 0 && c.r < 18 && !c.isBadge)
66
+ .sort((a, b) => b.r - a.r)[0];
67
+ const watermark = document.querySelector('[data-topo-brand-watermark]');
68
+ return {
69
+ zinStroke: zin?.getAttribute('stroke-width') ?? null,
70
+ zoutStroke: zout?.getAttribute('stroke-width') ?? null,
71
+ resetStroke: reset?.getAttribute('stroke-width') ?? null,
72
+ fsStroke: fs?.getAttribute('stroke-width') ?? null,
73
+ fsVariant: fs?.getAttribute('data-topo-chrome-fullscreen-icon') ?? null,
74
+ alphaAvatarStroke: alphaAvatarCircle?.sw ?? null,
75
+ watermarkPresent: watermark !== null,
76
+ };
77
+ });
78
+ await browser.close();
79
+
80
+ const results = {
81
+ zoom_in_stroke_2_5: probe.zinStroke === '2.5',
82
+ zoom_out_stroke_2_5: probe.zoutStroke === '2.5',
83
+ reset_stroke_2_5: probe.resetStroke === '2.5',
84
+ fullscreen_stroke_2_5: probe.fsStroke === '2.5',
85
+ fullscreen_variant_set: probe.fsVariant === 'enter' || probe.fsVariant === 'exit',
86
+ r283_monogram_stroke_kept: probe.alphaAvatarStroke === '1.5',
87
+ r282_watermark_present: probe.watermarkPresent,
88
+ };
89
+ const ok = Object.values(results).every(Boolean);
90
+ console.log(`${ok ? '✅' : '❌'} chrome icon stroke unify:`, JSON.stringify(results),
91
+ '\n zoom-in: ', probe.zinStroke,
92
+ '\n zoom-out: ', probe.zoutStroke,
93
+ '\n reset: ', probe.resetStroke,
94
+ '\n fullscreen: ', probe.fsStroke, `(variant: ${probe.fsVariant})`);
95
+ process.exit(ok ? 0 : 1);
@@ -0,0 +1,98 @@
1
+ /* Round 249 verification: chrome-pop click animation extends from
2
+ * the existing zoom-in/zoom-out pair to ring/grid layout toggle +
3
+ * fullscreen buttons. Whole chrome strip now speaks one click
4
+ * vocabulary instead of zoom-only-pops + silent-everything-else.
5
+ *
6
+ * Per button, on click:
7
+ * data-topo-chrome-{key}-popping flips 'false' → 'true' for ~240ms
8
+ * className gains 'anet-chrome-pop' for the same window
9
+ *
10
+ * Test scope:
11
+ * - Ring layout button: click → data-topo-chrome-layout-ring-popping='true' (within 100ms)
12
+ * - Grid layout button: click → data-topo-chrome-layout-grid-popping='true'
13
+ * - Fullscreen button: click → data-topo-chrome-fullscreen-popping='true'
14
+ *
15
+ * Hard-to-test trap: chromePopping is transient (240ms TTL). Probe
16
+ * immediately after Playwright click resolves. Wait full 240ms after
17
+ * for the second probe — must be 'false' again.
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 browser = await chromium.launch({ headless: true });
24
+ const ctx = await browser.newContext({ viewport: { width: 1500, height: 1500 } });
25
+ await ctx.addCookies([{ name: 'anet_dashboard_session', value: `v3:${TOKEN}`, domain: '127.0.0.1', path: '/' }]);
26
+ await ctx.addInitScript(() => {
27
+ try { localStorage.setItem('anet-theme', 'cyber'); sessionStorage.setItem('anet_v3_auth', '1'); } catch {}
28
+ });
29
+ const fresh = new Date(Date.now() - 60 * 1000).toISOString();
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: 'working', model: 'claude-opus-4', runtime: 'claude-code-cli',
36
+ network_id: nid, project_dir: null,
37
+ created_at: fresh, updated_at: fresh, last_seen_at: fresh,
38
+ });
39
+ await route.fulfill({ response: r, json: { ...b, sessions: [
40
+ mk('alpha'), mk('beta'), mk('gamma'), mk('delta'),
41
+ ] } });
42
+ });
43
+ await ctx.route('**/api/hub/messages*', (r2) => r2.fulfill({ json: { messages: [] } }));
44
+ await ctx.route('**/api/hub/tasks*', (r2) => r2.fulfill({ json: { tasks: [] } }));
45
+
46
+ const page = await ctx.newPage();
47
+ await page.goto('http://127.0.0.1:3000/', { waitUntil: 'domcontentloaded' });
48
+ await page.waitForFunction(() => document.querySelectorAll('g[data-node]').length === 4, { timeout: 30000 });
49
+ await page.waitForSelector('[data-topo-chrome-layout="ring"]', { timeout: 10000 });
50
+ await page.waitForSelector('[data-topo-chrome-fullscreen]', { timeout: 10000 });
51
+ await page.waitForTimeout(300);
52
+
53
+ const testButton = async (clickSelector, poppingAttr, label) => {
54
+ // Click + immediately read state. The chromePopping setState is
55
+ // synchronous within the click handler, so the DOM should reflect
56
+ // 'true' on the next React commit (very soon after click resolves).
57
+ await page.locator(clickSelector).click();
58
+ // Probe quickly — within the 240ms window
59
+ await page.waitForTimeout(50);
60
+ const duringPop = await page.locator(clickSelector).getAttribute(poppingAttr);
61
+ const classDuring = await page.locator(clickSelector).getAttribute('class');
62
+ // Wait for the pop to clear
63
+ await page.waitForTimeout(300);
64
+ const afterPop = await page.locator(clickSelector).getAttribute(poppingAttr);
65
+ const classAfter = await page.locator(clickSelector).getAttribute('class');
66
+ return {
67
+ label,
68
+ duringAttr: duringPop,
69
+ duringClass: /anet-chrome-pop/.test(classDuring || ''),
70
+ afterAttr: afterPop,
71
+ afterClass: /anet-chrome-pop/.test(classAfter || ''),
72
+ };
73
+ };
74
+
75
+ const ring = await testButton('[data-topo-chrome-layout="ring"]', 'data-topo-chrome-layout-ring-popping', 'ring');
76
+ const grid = await testButton('[data-topo-chrome-layout="grid"]', 'data-topo-chrome-layout-grid-popping', 'grid');
77
+ // For fullscreen, browser context may not honour requestFullscreen in
78
+ // headless mode — wrap in try/catch on the page side. Test only the
79
+ // data attr + className.
80
+ const fullscreen = await testButton('[data-topo-chrome-fullscreen]', 'data-topo-chrome-fullscreen-popping', 'fullscreen');
81
+
82
+ await browser.close();
83
+
84
+ const ok_each = (b) =>
85
+ b.duringAttr === 'true' && b.duringClass === true &&
86
+ b.afterAttr === 'false' && b.afterClass === false;
87
+
88
+ const results = {
89
+ ring_pops_on_click: ok_each(ring),
90
+ grid_pops_on_click: ok_each(grid),
91
+ fullscreen_pops_on_click: ok_each(fullscreen),
92
+ };
93
+ const ok = Object.values(results).every(Boolean);
94
+ console.log(`${ok ? '✅' : '❌'} chrome-pop extension:`, JSON.stringify(results),
95
+ '\n ring: ', ring,
96
+ '\n grid: ', grid,
97
+ '\n fullscreen:', fullscreen);
98
+ process.exit(ok ? 0 : 1);
@@ -0,0 +1,88 @@
1
+ /* Round 250 verification: nodeSize S/M/L buttons close the chrome-
2
+ * pop click-feedback family. Every clickable chrome button now fires
3
+ * the R186 .anet-chrome-pop 220ms scale-pulse on release.
4
+ *
5
+ * R171 nodeSizeSwitching canvas crossfade still masks the radius
6
+ * change at the global scope; R250 chrome-pop adds the LOCAL
7
+ * button-level click confirmation.
8
+ *
9
+ * Test scope: click each of S/M/L → within 50ms data-topo-chrome-
10
+ * nodesize-popping='true' + className contains 'anet-chrome-pop'.
11
+ * After 300ms both clear.
12
+ */
13
+ import { chromium } from 'playwright';
14
+ import { readFileSync } from 'node:fs';
15
+
16
+ const TOKEN = JSON.parse(readFileSync('/home/vansin/.anet/config.json', 'utf8')).token;
17
+ const browser = await chromium.launch({ headless: true });
18
+ const ctx = await browser.newContext({ viewport: { width: 1500, height: 1500 } });
19
+ await ctx.addCookies([{ name: 'anet_dashboard_session', value: `v3:${TOKEN}`, domain: '127.0.0.1', path: '/' }]);
20
+ await ctx.addInitScript(() => {
21
+ try { localStorage.setItem('anet-theme', 'cyber'); sessionStorage.setItem('anet_v3_auth', '1'); } catch {}
22
+ });
23
+ const fresh = new Date(Date.now() - 60 * 1000).toISOString();
24
+ await ctx.route('**/api/hub/status*', async (route) => {
25
+ const r = await route.fetch();
26
+ const b = await r.json();
27
+ const nid = (b.sessions || [])[0]?.network_id || 'default';
28
+ const mk = (alias) => ({
29
+ alias, status: 'working', model: 'claude-opus-4', runtime: 'claude-code-cli',
30
+ network_id: nid, project_dir: null,
31
+ created_at: fresh, updated_at: fresh, last_seen_at: fresh,
32
+ });
33
+ await route.fulfill({ response: r, json: { ...b, sessions: [
34
+ mk('alpha'), mk('beta'), mk('gamma'), mk('delta'),
35
+ ] } });
36
+ });
37
+ await ctx.route('**/api/hub/messages*', (r2) => r2.fulfill({ json: { messages: [] } }));
38
+ await ctx.route('**/api/hub/tasks*', (r2) => r2.fulfill({ json: { tasks: [] } }));
39
+
40
+ const page = await ctx.newPage();
41
+ await page.goto('http://127.0.0.1:3000/', { waitUntil: 'domcontentloaded' });
42
+ await page.waitForFunction(() => document.querySelectorAll('g[data-node]').length === 4, { timeout: 30000 });
43
+ await page.waitForSelector('[data-topo-chrome-nodesize="S"]', { timeout: 10000 });
44
+ await page.waitForTimeout(300);
45
+
46
+ const testButton = async (size) => {
47
+ const sel = `[data-topo-chrome-nodesize="${size}"]`;
48
+ await page.locator(sel).click();
49
+ await page.waitForTimeout(50);
50
+ const duringAttr = await page.locator(sel).getAttribute('data-topo-chrome-nodesize-popping');
51
+ const duringClass = await page.locator(sel).getAttribute('class');
52
+ // Wait past the 240ms TTL
53
+ await page.waitForTimeout(300);
54
+ const afterAttr = await page.locator(sel).getAttribute('data-topo-chrome-nodesize-popping');
55
+ const afterClass = await page.locator(sel).getAttribute('class');
56
+ return {
57
+ size,
58
+ duringAttr,
59
+ duringClassHasPop: /anet-chrome-pop/.test(duringClass || ''),
60
+ afterAttr,
61
+ afterClassHasPop: /anet-chrome-pop/.test(afterClass || ''),
62
+ };
63
+ };
64
+
65
+ // Click each in order S → L → M to mix up state
66
+ const small = await testButton('S');
67
+ const large = await testButton('L');
68
+ const medium = await testButton('M');
69
+
70
+ await browser.close();
71
+
72
+ const ok_each = (b) =>
73
+ b.duringAttr === 'true' &&
74
+ b.duringClassHasPop === true &&
75
+ b.afterAttr === 'false' &&
76
+ b.afterClassHasPop === false;
77
+
78
+ const results = {
79
+ small_pops: ok_each(small),
80
+ medium_pops: ok_each(medium),
81
+ large_pops: ok_each(large),
82
+ };
83
+ const ok = Object.values(results).every(Boolean);
84
+ console.log(`${ok ? '✅' : '❌'} chrome-pop nodesize:`, JSON.stringify(results),
85
+ '\n small: ', small,
86
+ '\n medium:', medium,
87
+ '\n large: ', large);
88
+ process.exit(ok ? 0 : 1);