@sleep2agi/agent-network-dashboard 0.5.3-preview.99 → 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 (410) 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 +3 -3
  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/{084e1mr6acfta.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 +4591 -216
  233. package/app/globals.css +839 -0
  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-links-chip-halo-layers-test.mjs +81 -0
  245. package/scripts/topo-alias-chat-brightness-test.mjs +79 -0
  246. package/scripts/topo-alias-text-halo-layers-test.mjs +98 -0
  247. package/scripts/topo-animation-temporal-modes-catalog-test.mjs +144 -0
  248. package/scripts/topo-avatar-chat-gate-test.mjs +77 -0
  249. package/scripts/topo-avatar-drop-shadow-test.mjs +86 -0
  250. package/scripts/topo-avatar-fallback-rotate-test.mjs +92 -0
  251. package/scripts/topo-avatar-rotate-test.mjs +85 -0
  252. package/scripts/topo-avatar-scale-test.mjs +89 -0
  253. package/scripts/topo-badge-chat-gate-test.mjs +74 -0
  254. package/scripts/topo-brand-drop-shadow-test.mjs +71 -0
  255. package/scripts/topo-brand-logo-halo-layers-test.mjs +85 -0
  256. package/scripts/topo-canvas-desc-a11y-test.mjs +87 -0
  257. package/scripts/topo-canvas-entrance-animation-test.mjs +117 -0
  258. package/scripts/topo-canvas-scan-beam-diagonal-test.mjs +148 -0
  259. package/scripts/topo-canvas-scan-beam-test.mjs +109 -0
  260. package/scripts/topo-canvas-scan-beam-vertical-test.mjs +123 -0
  261. package/scripts/topo-card-chat-brightness-test.mjs +86 -0
  262. package/scripts/topo-chat-ring-breath-curve-test.mjs +114 -0
  263. package/scripts/topo-chat-ring-brightness-test.mjs +80 -0
  264. package/scripts/topo-chat-ring-halo-layers-test.mjs +100 -0
  265. package/scripts/topo-chat-ring-r-breath-test.mjs +121 -0
  266. package/scripts/topo-chat-ring-status-halo-test.mjs +106 -0
  267. package/scripts/topo-chat-ring-sw-breath-test.mjs +123 -0
  268. package/scripts/topo-chip-pin-halo-test.mjs +85 -0
  269. package/scripts/topo-chrome-control-halo-layers-test.mjs +22 -0
  270. package/scripts/topo-chrome-fullscreen-breath-test.mjs +121 -0
  271. package/scripts/topo-chrome-layout-trailer-breath-test.mjs +86 -0
  272. package/scripts/topo-chrome-nodesize-trailer-breath-test.mjs +86 -0
  273. package/scripts/topo-chrome-reset-breath-test.mjs +115 -0
  274. package/scripts/topo-chrome-strip-entrance-animation-test.mjs +115 -0
  275. package/scripts/topo-chrome-wrapper-halo-test.mjs +83 -0
  276. package/scripts/topo-chrome-zoom-wrapper-breath-test.mjs +85 -0
  277. package/scripts/topo-click-ripple-glow-test.mjs +86 -0
  278. package/scripts/topo-click-ripple-halo-layers-test.mjs +79 -0
  279. package/scripts/topo-click-ripple-sw-test.mjs +110 -0
  280. package/scripts/topo-crescent-envelope-breath-test.mjs +103 -0
  281. package/scripts/topo-dense-alias-chat-halo-test.mjs +73 -0
  282. package/scripts/topo-dense-alias-halo-layers-test.mjs +80 -0
  283. package/scripts/topo-dual-axis-surfaces-catalog-test.mjs +94 -0
  284. package/scripts/topo-edge-badge-circle-brightness-test.mjs +82 -0
  285. package/scripts/topo-edge-badge-circle-hot-pulse-test.mjs +100 -0
  286. package/scripts/topo-edge-badge-digit-halo-layers-test.mjs +107 -0
  287. package/scripts/topo-edge-badge-endpoint-gate-test.mjs +94 -0
  288. package/scripts/topo-edge-badge-halo-layers-test.mjs +85 -0
  289. package/scripts/topo-edge-badge-hot-pulse-test.mjs +92 -0
  290. package/scripts/topo-edge-chat-gate-test.mjs +71 -0
  291. package/scripts/topo-edge-flow-rail-halo-layers-test.mjs +89 -0
  292. package/scripts/topo-edge-particle-halo-layers-test.mjs +91 -0
  293. package/scripts/topo-edge-pin-halo-test.mjs +99 -0
  294. package/scripts/topo-edge-visible-halo-layers-test.mjs +87 -0
  295. package/scripts/topo-endpoint-ring-flow-halo-test.mjs +107 -0
  296. package/scripts/topo-endpoint-ring-halo-layers-test.mjs +100 -0
  297. package/scripts/topo-filter-pill-halo-layers-test.mjs +27 -0
  298. package/scripts/topo-flow-arrow-brightness-test.mjs +82 -0
  299. package/scripts/topo-fullscreen-brightness-test.mjs +84 -0
  300. package/scripts/topo-group-box-brightness-test.mjs +84 -0
  301. package/scripts/topo-group-box-halo-layers-test.mjs +91 -0
  302. package/scripts/topo-group-chat-gate-test.mjs +77 -0
  303. package/scripts/topo-group-label-halo-layers-test.mjs +78 -0
  304. package/scripts/topo-group-tint-brightness-test.mjs +82 -0
  305. package/scripts/topo-h2-dual-axis-breath-test.mjs +92 -0
  306. package/scripts/topo-h2-triple-axis-breath-test.mjs +142 -0
  307. package/scripts/topo-halo-chat-gate-test.mjs +72 -0
  308. package/scripts/topo-hover-detail-halo-test.mjs +76 -0
  309. package/scripts/topo-hub-a11y-title-test.mjs +95 -0
  310. package/scripts/topo-hub-core-brightness-test.mjs +82 -0
  311. package/scripts/topo-hub-core-halo-layers-test.mjs +81 -0
  312. package/scripts/topo-hub-digit-halo-layers-test.mjs +76 -0
  313. package/scripts/topo-hub-halo-halo-layers-test.mjs +76 -0
  314. package/scripts/topo-hub-highlight-halo-layers-test.mjs +78 -0
  315. package/scripts/topo-hub-hover-ring-halo-layers-test.mjs +71 -0
  316. package/scripts/topo-hub-spoke-halo-layers-test.mjs +97 -0
  317. package/scripts/topo-hub-spoke-self-filter-test.mjs +119 -0
  318. package/scripts/topo-kicker-breath-test.mjs +100 -0
  319. package/scripts/topo-kicker-dual-axis-breath-test.mjs +81 -0
  320. package/scripts/topo-kicker-halo-layers-test.mjs +82 -0
  321. package/scripts/topo-kicker-triple-axis-breath-test.mjs +124 -0
  322. package/scripts/topo-label-card-brightness-test.mjs +81 -0
  323. package/scripts/topo-layout-toggle-brightness-test.mjs +94 -0
  324. package/scripts/topo-layout-toggle-halo-layers-test.mjs +95 -0
  325. package/scripts/topo-legend-count-brightness-test.mjs +80 -0
  326. package/scripts/topo-legend-count-halo-layers-test.mjs +79 -0
  327. package/scripts/topo-legend-panel-title-breath-test.mjs +86 -0
  328. package/scripts/topo-legend-pin-ring-brightness-test.mjs +82 -0
  329. package/scripts/topo-legend-pin-ring-halo-layers-test.mjs +71 -0
  330. package/scripts/topo-legend-row-count-brightness-test.mjs +85 -0
  331. package/scripts/topo-legend-tint-brightness-test.mjs +83 -0
  332. package/scripts/topo-legend-trio-halo-layers-test.mjs +22 -0
  333. package/scripts/topo-live-lanes.mjs +48 -0
  334. package/scripts/topo-minimap-container-halo-test.mjs +82 -0
  335. package/scripts/topo-minimap-dot-chat-gate-test.mjs +81 -0
  336. package/scripts/topo-minimap-viewport-brightness-test.mjs +84 -0
  337. package/scripts/topo-minimap-viewport-halo-layers-test.mjs +24 -0
  338. package/scripts/topo-more-footer-brightness-test.mjs +94 -0
  339. package/scripts/topo-node-avatar-halo-layers-test.mjs +25 -0
  340. package/scripts/topo-node-hover-ring-halo-layers-test.mjs +70 -0
  341. package/scripts/topo-node-label-card-halo-test.mjs +76 -0
  342. package/scripts/topo-nodesize-brightness-test.mjs +82 -0
  343. package/scripts/topo-nodesize-halo-layers-test.mjs +89 -0
  344. package/scripts/topo-overlap-test.mjs +22 -8
  345. package/scripts/topo-panel-count-halo-layers-test.mjs +91 -0
  346. package/scripts/topo-panel-rect-halo-test.mjs +90 -0
  347. package/scripts/topo-panel-titles-dual-axis-breath-test.mjs +94 -0
  348. package/scripts/topo-panel-titles-halo-layers-test.mjs +23 -0
  349. package/scripts/topo-panel-titles-triple-axis-breath-test.mjs +161 -0
  350. package/scripts/topo-pip-brightness-test.mjs +85 -0
  351. package/scripts/topo-pressure-bar-halo-layers-test.mjs +19 -0
  352. package/scripts/topo-r717-scan-beam-pair-pattern-test.mjs +100 -0
  353. package/scripts/topo-r717-triple-axis-pair-pattern-test.mjs +113 -0
  354. package/scripts/topo-r717-triple-axis-tier-pattern-test.mjs +117 -0
  355. package/scripts/topo-recent-count-brightness-test.mjs +84 -0
  356. package/scripts/topo-recent-more-halo-layers-test.mjs +90 -0
  357. package/scripts/topo-recent-panel-hot-pulse-test.mjs +105 -0
  358. package/scripts/topo-recent-panel-title-breath-test.mjs +91 -0
  359. package/scripts/topo-recent-pip-halo-layers-test.mjs +82 -0
  360. package/scripts/topo-recent-row-chat-gate-test.mjs +75 -0
  361. package/scripts/topo-recent-row-content-lift-test.mjs +140 -0
  362. package/scripts/topo-recent-row-text-halo-layers-test.mjs +67 -0
  363. package/scripts/topo-recent-tint-brightness-test.mjs +80 -0
  364. package/scripts/topo-recent-ts-brightness-test.mjs +86 -0
  365. package/scripts/topo-reset-brightness-test.mjs +83 -0
  366. package/scripts/topo-respiratory-axis-count-stats-test.mjs +154 -0
  367. package/scripts/topo-respiratory-patterns-catalog-test.mjs +112 -0
  368. package/scripts/topo-respiratory-rolodex-test.mjs +83 -0
  369. package/scripts/topo-respiratory-tiers-catalog-test.mjs +119 -0
  370. package/scripts/topo-respiratory-triple-axis-surfaces-catalog-test.mjs +127 -0
  371. package/scripts/topo-runtime-badge-brightness-test.mjs +78 -0
  372. package/scripts/topo-runtime-badge-halo-layers-test.mjs +87 -0
  373. package/scripts/topo-runtime-badge-rotate-test.mjs +85 -0
  374. package/scripts/topo-section-title-breath-test.mjs +83 -0
  375. package/scripts/topo-section-title-halo-layers-test.mjs +88 -0
  376. package/scripts/topo-spoke-chat-gate-test.mjs +72 -0
  377. package/scripts/topo-status-pin-pill-halo-layers-test.mjs +17 -0
  378. package/scripts/topo-status-ring-chat-gate-test.mjs +72 -0
  379. package/scripts/topo-status-ring-halo-layers-test.mjs +105 -0
  380. package/scripts/topo-status-ring-status-halo-test.mjs +110 -0
  381. package/scripts/topo-sub-text-chat-brightness-test.mjs +81 -0
  382. package/scripts/topo-svg-title-a11y-r731-test.mjs +93 -0
  383. package/scripts/topo-svg-title-a11y-test.mjs +88 -0
  384. package/scripts/topo-title-block-entrance-animation-test.mjs +127 -0
  385. package/scripts/topo-title-block-envelope-breath-test.mjs +87 -0
  386. package/scripts/topo-tree-diag.mjs +95 -0
  387. package/scripts/topo-vendor-chip-halo-layers-test.mjs +18 -0
  388. package/scripts/topo-vendor-chip-pin-halo-test.mjs +88 -0
  389. package/scripts/topo-vendor-count-suffix-halo-layers-test.mjs +79 -0
  390. package/scripts/topo-vendor-distribution-wrapper-halo-test.mjs +93 -0
  391. package/scripts/topo-vendor-letter-halo-layers-test.mjs +93 -0
  392. package/scripts/topo-watermark-dual-axis-breath-test.mjs +88 -0
  393. package/scripts/topo-watermark-envelope-breath-test.mjs +88 -0
  394. package/scripts/topo-watermark-triple-axis-breath-test.mjs +129 -0
  395. package/scripts/topo-working-online-chip-halo-layers-test.mjs +94 -0
  396. package/scripts/topo-zoom-buttons-brightness-test.mjs +94 -0
  397. package/scripts/topo-zoom-in-out-halo-layers-test.mjs +97 -0
  398. package/scripts/topo-zoom-level-breath-test.mjs +87 -0
  399. package/scripts/topo-zoom-level-brightness-test.mjs +83 -0
  400. package/scripts/topo-zoom-level-dual-axis-breath-test.mjs +83 -0
  401. package/scripts/topo-zoom-level-halo-layers-test.mjs +78 -0
  402. package/scripts/topo-zoom-level-triple-axis-breath-test.mjs +148 -0
  403. package/.next/static/chunks/09oxd2mm27b_n.js +0 -1
  404. package/.next/static/chunks/0ots8-uksxz9p.js +0 -4
  405. package/.next/static/chunks/0voxs92keb6tg.js +0 -1
  406. package/.next/static/chunks/13~aih56vx-cf.css +0 -2
  407. /package/.next/server/chunks/{[externals]__11vad82._.js.map → 0ykm__next-internal_server_app_api_hub_upload_route_actions_03_eqnf.js.map} +0 -0
  408. /package/.next/static/{Ha31LjrNJgJIEydZivRlp → xq88BMF7fMUHWh10yaKTn}/_buildManifest.js +0 -0
  409. /package/.next/static/{Ha31LjrNJgJIEydZivRlp → xq88BMF7fMUHWh10yaKTn}/_clientMiddlewareManifest.js +0 -0
  410. /package/.next/static/{Ha31LjrNJgJIEydZivRlp → xq88BMF7fMUHWh10yaKTn}/_ssgManifest.js +0 -0
@@ -0,0 +1,127 @@
1
+ /* Round 742 — title-block entrance animation. 2nd member of the
2
+ * entrance family (after R740 canvas root). Staggered choreography:
3
+ * R740 canvas 0 → 600 ms scale 0.99 → 1, opacity 0.8 → 1
4
+ * R742 title-block 200 → 700 ms translateY -4 → 0, opacity 0.7 → 1
5
+ *
6
+ * Assertions:
7
+ * - .anet-topo-title-block-entrance class on title-block wrapper
8
+ * - data-topo-section-titleblock-entrance="true"
9
+ * - CSS @keyframes 0% translateY(-4px) opacity 0.7 → 100% translateY(0) opacity 1
10
+ * - .anet-topo-title-block-entrance binds 500ms ease-out 200ms delay
11
+ * - animation NOT infinite (runtime iteration count === '1')
12
+ * - prefers-reduced-motion guard present
13
+ * - Animation completes within ~900ms (200ms delay + 500ms + 200ms buffer)
14
+ * → after 900ms wait, computed transform is identity & opacity = 1
15
+ * - Existing R706 envelope-breath class still composed (regression)
16
+ * - R741 catalog one-shot-mount.members === 2, includes title-block in examples
17
+ * - R740 canvas entrance still present (regression)
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: 'idle', model: 'claude-opus-4', runtime: 'claude-code-cli',
41
+ network_id: nid, project_dir: null,
42
+ created_at: fresh, updated_at: fresh, last_seen_at: fresh,
43
+ });
44
+ await route.fulfill({ response: r, json: { ...b, sessions: [mk('a·1'), mk('a·2')] } });
45
+ });
46
+ await ctx.route('**/api/hub/messages*', (r) => r.fulfill({ json: { messages: [] } }));
47
+ await ctx.route('**/api/hub/tasks*', (r) => r.fulfill({ json: { tasks: [] } }));
48
+ const page = await ctx.newPage();
49
+ await page.goto('http://127.0.0.1:3000/', { waitUntil: 'networkidle' });
50
+ await page.waitForSelector('[data-topo-section-titleblock-group]', { timeout: 15000, state: 'attached' });
51
+ /* Wait for both R740 (0-600ms) and R742 (200-700ms) animations to
52
+ * complete plus a safety buffer. */
53
+ await page.waitForTimeout(900);
54
+
55
+ const state = await page.evaluate(() => {
56
+ const tb = document.querySelector('[data-topo-section-titleblock-group]');
57
+ const svg = document.querySelector('[data-topo-canvas-aria]');
58
+ if (!tb) return null;
59
+ const cs = getComputedStyle(tb);
60
+ return {
61
+ has_entrance_class: tb.classList.contains('anet-topo-title-block-entrance'),
62
+ entrance_attr: tb.getAttribute('data-topo-section-titleblock-entrance'),
63
+ envelope_breath_kept: tb.classList.contains('anet-topo-title-block-envelope-breath'),
64
+ anim_name: cs.animationName,
65
+ anim_duration: cs.animationDuration,
66
+ anim_delay: cs.animationDelay,
67
+ anim_iteration: cs.animationIterationCount,
68
+ computed_transform: cs.transform,
69
+ computed_opacity: cs.opacity,
70
+ canvas_entrance_class: svg?.classList.contains('anet-topo-canvas-entrance') ?? null,
71
+ temporal_modes: svg?.getAttribute('data-topo-animation-temporal-modes') ?? null,
72
+ };
73
+ });
74
+
75
+ await browser.close();
76
+
77
+ const cssSrc = readFileSync('/home/vansin/agent-network-dashboard/app/globals.css', 'utf8');
78
+ const cssKfStart = /@keyframes anet-topo-title-block-entrance-kf\s*\{[\s\S]*?0%\s*\{[\s\S]*?transform:\s*translateY\(-4px\)[\s\S]*?opacity:\s*0\.7/.test(cssSrc);
79
+ const cssKfEnd = /@keyframes anet-topo-title-block-entrance-kf\s*\{[\s\S]*?100%\s*\{[\s\S]*?transform:\s*translateY\(0\)[\s\S]*?opacity:\s*1/.test(cssSrc);
80
+ const cssClassBound = /\.anet-topo-title-block-entrance\s*\{[\s\S]*?animation:\s*anet-topo-title-block-entrance-kf\s+500ms\s+ease-out\s+200ms\s+backwards/.test(cssSrc);
81
+ const cssReducedMotion = /@media\s*\(prefers-reduced-motion:\s*reduce\)\s*\{[\s\S]*?\.anet-topo-title-block-entrance\s*\{\s*animation:\s*none/.test(cssSrc);
82
+
83
+ const transformSettled = state?.computed_transform === 'none'
84
+ || state?.computed_transform === 'matrix(1, 0, 0, 1, 0, 0)';
85
+ /* The title-block carries TWO animations via the R742 compound:
86
+ * 1. entrance one-shot, 500ms — settles after ~700ms
87
+ * 2. envelope-breath infinite, 11s — opacity 0.92 ↔ 1 forever (R706)
88
+ * After the entrance completes, opacity is governed by the ongoing
89
+ * envelope breath, so it sits SOMEWHERE in [0.92, 1] — never exactly
90
+ * 1 at a random sample. Assert opacity ∈ [0.90, 1.00] (the R706
91
+ * breath band with a small tolerance) rather than === 1. */
92
+ const opacityInBreathBand = (() => {
93
+ const o = parseFloat(state?.computed_opacity ?? '0');
94
+ return o >= 0.90 && o <= 1.0;
95
+ })();
96
+ /* The compound animation's FIRST entry is the one-shot entrance;
97
+ * the SECOND is the infinite breath. Verify the entrance part is
98
+ * one-shot by checking the first iteration-count token === '1'. */
99
+ const entranceIsOneShot = (state?.anim_iteration ?? '').split(',')[0].trim() === '1';
100
+ const entranceIsFirstInCompound = (state?.anim_name ?? '').split(',')[0].trim() === 'anet-topo-title-block-entrance-kf';
101
+
102
+ let modes = null;
103
+ try { modes = JSON.parse(state?.temporal_modes ?? ''); } catch {}
104
+ const oneShot = Array.isArray(modes) ? modes.find(m => m.mode === 'one-shot-mount') : null;
105
+ const oneShotHas2 = oneShot?.members === 2 && Array.isArray(oneShot?.examples) && oneShot.examples.includes('title-block');
106
+
107
+ const results = {
108
+ has_entrance_class: state?.has_entrance_class === true,
109
+ entrance_attr_true: state?.entrance_attr === 'true',
110
+ envelope_breath_kept: state?.envelope_breath_kept === true,
111
+ css_keyframe_start: cssKfStart,
112
+ css_keyframe_end: cssKfEnd,
113
+ css_class_binds_500ms_delay_200: cssClassBound,
114
+ css_reduced_motion_guard: cssReducedMotion,
115
+ entrance_part_is_one_shot: entranceIsOneShot,
116
+ entrance_first_in_compound: entranceIsFirstInCompound,
117
+ transform_settled: transformSettled,
118
+ opacity_in_breath_band: opacityInBreathBand,
119
+ r740_canvas_entrance_kept: state?.canvas_entrance_class === true,
120
+ r741_one_shot_members_now_2: oneShotHas2,
121
+ };
122
+ const ok = Object.values(results).every(Boolean);
123
+ console.log(`${ok ? '✅' : '❌'} R742 title-block entrance animation (2nd one-shot member, staggered after canvas):`,
124
+ JSON.stringify(results, null, 2),
125
+ `\n state: ${JSON.stringify(state)}`,
126
+ `\n one-shot entry: ${JSON.stringify(oneShot)}`);
127
+ process.exit(ok ? 0 : 1);
@@ -0,0 +1,87 @@
1
+ /* Round 706 — title-block wrapper envelope breath at 11s. Mirrors the
2
+ * canvas-brand-pair nested-envelope pattern (R704/R705) at the title-
3
+ * block scope. Creates triply-nested respiration: 3 inner trio anchors
4
+ * (brand-logo 5s + kicker 6s + H2 10s) inside outer wrapper (11s).
5
+ *
6
+ * 11s coprime with all 3 inner cadences (5, 6, 10) — no common factor.
7
+ * Tighter alpha (0.92 ↔ 1, ~8%) than canvas-brand envelopes since
8
+ * title-block carries primary text identity.
9
+ */
10
+ import { chromium } from 'playwright';
11
+ import { readFileSync } from 'node:fs';
12
+
13
+ const TOKEN = JSON.parse(readFileSync('/home/vansin/.anet/config.json', 'utf8')).token;
14
+ const fresh = new Date(Date.now() - 60 * 1000).toISOString();
15
+
16
+ const browser = await chromium.launch({ headless: true });
17
+ const ctx = await browser.newContext({ viewport: { width: 1500, height: 1200 } });
18
+ await ctx.addCookies([{ name: 'anet_dashboard_session', value: `v3:${TOKEN}`, domain: '127.0.0.1', path: '/' }]);
19
+ await ctx.addInitScript(() => {
20
+ try {
21
+ localStorage.setItem('anet-theme', 'cyber');
22
+ localStorage.setItem('anet-topo-layout', 'ring');
23
+ sessionStorage.setItem('anet_v3_auth', '1');
24
+ } catch {}
25
+ });
26
+ await ctx.route('**/api/hub/status*', async (route) => {
27
+ const r = await route.fetch();
28
+ const b = await r.json();
29
+ const nid = (b.sessions || [])[0]?.network_id || 'default';
30
+ const mk = (alias) => ({
31
+ alias, status: 'idle', model: 'claude-opus-4', runtime: 'claude-code-cli',
32
+ network_id: nid, project_dir: null,
33
+ created_at: fresh, updated_at: fresh, last_seen_at: fresh,
34
+ });
35
+ await route.fulfill({ response: r, json: { ...b, sessions: [mk('a·1'), mk('a·2')] } });
36
+ });
37
+ await ctx.route('**/api/hub/messages*', (r) => r.fulfill({ json: { messages: [] } }));
38
+ await ctx.route('**/api/hub/tasks*', (r) => r.fulfill({ json: { tasks: [] } }));
39
+ const page = await ctx.newPage();
40
+ await page.goto('http://127.0.0.1:3000/', { waitUntil: 'networkidle' });
41
+ await page.waitForSelector('[data-topo-section-titleblock-group]', { timeout: 15000, state: 'attached' });
42
+ await page.waitForTimeout(300);
43
+
44
+ const runtimeState = await page.evaluate(() => {
45
+ const wrap = document.querySelector('[data-topo-section-titleblock-group]');
46
+ if (!wrap) return null;
47
+ const cs = getComputedStyle(wrap);
48
+ return {
49
+ has_class: wrap.classList.contains('anet-topo-title-block-envelope-breath'),
50
+ breath_attr: wrap.getAttribute('data-topo-section-titleblock-envelope-breath'),
51
+ anim_name: cs.animationName,
52
+ anim_duration: cs.animationDuration,
53
+ anim_iter: cs.animationIterationCount,
54
+ };
55
+ });
56
+
57
+ await browser.close();
58
+
59
+ const cssSrc = readFileSync('/home/vansin/agent-network-dashboard/app/globals.css', 'utf8');
60
+ const tsxSrc = readFileSync('/home/vansin/agent-network-dashboard/app/components/TopoGraph.tsx', 'utf8');
61
+
62
+ const cssKeyframes = /@keyframes anet-topo-title-block-envelope-breath-kf\s*\{[\s\S]*?0%, 100%\s*\{\s*opacity:\s*1;\s*\}[\s\S]*?50%\s*\{\s*opacity:\s*0\.92;/.test(cssSrc);
63
+ const cssRule = /\.anet-topo-title-block-envelope-breath\s*\{[\s\S]*?animation:\s*anet-topo-title-block-envelope-breath-kf\s+11s\s+ease-in-out\s+infinite/.test(cssSrc);
64
+ const cssReducedMotion = /prefers-reduced-motion:\s*reduce\s*\)\s*\{\s*\.anet-topo-title-block-envelope-breath\s*\{\s*animation:\s*none/.test(cssSrc);
65
+ const tsxClass = /anet-topo-title-block-envelope-breath group flex items-center gap-2\.5/.test(tsxSrc);
66
+ const tsxAttr = /data-topo-section-titleblock-envelope-breath="11s"/.test(tsxSrc);
67
+
68
+ const runtimeAnim = runtimeState?.anim_name === 'anet-topo-title-block-envelope-breath-kf' || runtimeState?.anim_name === 'none';
69
+ const runtimeDuration = runtimeState?.anim_duration === '11s' || runtimeState?.anim_name === 'none';
70
+
71
+ const results = {
72
+ wrapper_present: !!runtimeState,
73
+ has_breath_class: runtimeState?.has_class === true,
74
+ breath_attr_11s: runtimeState?.breath_attr === '11s',
75
+ runtime_anim_ok: runtimeAnim,
76
+ runtime_duration_ok: runtimeDuration,
77
+ css_keyframes: cssKeyframes,
78
+ css_rule: cssRule,
79
+ css_reduced_motion: cssReducedMotion,
80
+ tsx_class: tsxClass,
81
+ tsx_breath_attr: tsxAttr,
82
+ };
83
+ const ok = Object.values(results).every(Boolean);
84
+ console.log(`${ok ? '✅' : '❌'} R706 title-block wrapper envelope breath (11s, triply-nested respiration):`,
85
+ JSON.stringify(results, null, 2),
86
+ `\n runtime: ${JSON.stringify(runtimeState)}`);
87
+ process.exit(ok ? 0 : 1);
@@ -0,0 +1,95 @@
1
+ /* Diagnostic: compare grid vs tree node frontend presentation.
2
+ * Vincent UX complaint — tree view "没有像 grid 视图那样的前端展示".
3
+ * Screenshots both layouts + dumps per-node visual element counts. */
4
+ import { chromium } from 'playwright';
5
+ import { readFileSync, mkdirSync } from 'node:fs';
6
+
7
+ const TOKEN = JSON.parse(readFileSync('/home/vansin/.anet/config.json', 'utf8')).token;
8
+ mkdirSync('/tmp/anet-tree-diag', { recursive: true });
9
+
10
+ const lead = (a) => ({ alias: a, runtime: 'claude-code-cli' });
11
+ const dep = (a) => ({ alias: a, runtime: 'codex-sdk' });
12
+ const mem = (a) => ({ alias: a, runtime: 'claude-agent-sdk' });
13
+ const FLEET = [
14
+ lead('总指挥'), lead('副指挥A'), lead('副指挥B'),
15
+ [lead, dep, mem, mem, mem, mem].map((f, i) => f(['A站内容', 'A站评测', 'A站数据', 'A站设计', 'A站运营', 'A站工程'][i])),
16
+ [lead, dep, mem, mem, mem].map((f, i) => f(['B站产品', 'B站工程', 'B站测试', 'B站运维', 'B站运营'][i])),
17
+ [lead, dep, mem, mem].map((f, i) => f(['P站产品', 'P站工程', 'P站测试', 'P站运维'][i])),
18
+ [lead, dep, mem, mem].map((f, i) => f(['通信龙', '通信牛', '通信马', '通信SDK马'][i])),
19
+ ['srv-a', 'srv-b', 'srv-c'].map(a => ({ alias: a, runtime: 'http-api', project_dir: '/home/v/agent-orchestra' })),
20
+ ['群星马', '书生1号', '微信马', '飞书马', '独立节点', '研究员1号', '研究员2号', '游侠马'].map(a => mem(a)),
21
+ ].flat();
22
+
23
+ const browser = await chromium.launch({ headless: true });
24
+
25
+ async function shot(layout) {
26
+ const ctx = await browser.newContext({ viewport: { width: 1280, height: 920 } });
27
+ await ctx.addCookies([{ name: 'anet_dashboard_session', value: `v3:${TOKEN}`, domain: '127.0.0.1', path: '/' }]);
28
+ await ctx.addInitScript((lay) => {
29
+ try {
30
+ localStorage.setItem('anet-theme', 'cyber');
31
+ localStorage.removeItem('anet-brand');
32
+ localStorage.removeItem('anet-topo-view');
33
+ localStorage.removeItem('anet-topo-nodescale');
34
+ localStorage.setItem('anet-topo-layout', lay);
35
+ sessionStorage.setItem('anet_v3_auth', '1');
36
+ } catch {}
37
+ }, layout);
38
+ await ctx.route('**/api/hub/status*', async (route) => {
39
+ const r = await route.fetch();
40
+ const b = await r.json();
41
+ const nid = (b.sessions || [])[0]?.network_id || 'default';
42
+ const sessions = FLEET.map((f, i) => ({
43
+ alias: f.alias, status: i % 5 === 0 ? 'working' : 'idle', network_id: nid,
44
+ project_dir: f.project_dir ?? null, runtime: f.runtime ?? null,
45
+ created_at: '2026-05-15T00:00:00Z', updated_at: '2026-05-15T00:00:00Z',
46
+ last_seen_at: new Date().toISOString(),
47
+ }));
48
+ await route.fulfill({ response: r, json: { ...b, sessions } });
49
+ });
50
+ await ctx.route('**/api/hub/tasks*', (route) => route.fulfill({ json: { tasks: [] } }));
51
+ const page = await ctx.newPage();
52
+ await page.goto('http://127.0.0.1:3000/', { waitUntil: 'domcontentloaded' });
53
+ await page.waitForFunction(() => {
54
+ const svg = document.querySelector('svg[viewBox="0 0 1000 680"]');
55
+ return !!svg && svg.querySelectorAll('g[data-node]').length > 20;
56
+ }, { timeout: 30000 }).catch(() => {});
57
+ await page.waitForTimeout(1200);
58
+ await page.evaluate(() => {
59
+ const svg = document.querySelector('svg[viewBox="0 0 1000 680"]');
60
+ svg?.scrollIntoView({ behavior: 'instant', block: 'center' });
61
+ });
62
+ await page.waitForTimeout(500);
63
+
64
+ const facts = await page.evaluate(() => {
65
+ const svg = document.querySelector('svg[viewBox="0 0 1000 680"]');
66
+ const nodes = [...svg.querySelectorAll('g[data-node]')];
67
+ const sample = nodes.slice(0, 3).map(g => ({
68
+ alias: g.getAttribute('data-node'),
69
+ circles: g.querySelectorAll('circle').length,
70
+ images: g.querySelectorAll('image').length,
71
+ texts: g.querySelectorAll('text').length,
72
+ paths: g.querySelectorAll('path').length,
73
+ }));
74
+ const viewG = svg.querySelector('g[data-topo-viewport], g[transform*="scale"]');
75
+ const groups = svg.querySelectorAll('g[data-group]').length;
76
+ return {
77
+ nodeCount: nodes.length,
78
+ groupBoxes: groups,
79
+ viewportTransform: viewG ? viewG.getAttribute('transform') : null,
80
+ sample,
81
+ };
82
+ });
83
+ const svgEl = await page.$('svg[viewBox="0 0 1000 680"]');
84
+ await svgEl.screenshot({ path: `/tmp/anet-tree-diag/${layout}.png`, animations: 'disabled' });
85
+ await ctx.close();
86
+ return facts;
87
+ }
88
+
89
+ for (const lay of ['grid', 'tree']) {
90
+ const f = await shot(lay);
91
+ console.log(`\n=== ${lay} ===`);
92
+ console.log(JSON.stringify(f, null, 2));
93
+ }
94
+ await browser.close();
95
+ console.log('\nscreenshots: /tmp/anet-tree-diag/{grid,tree}.png');
@@ -0,0 +1,18 @@
1
+ /* Round 663 — vendor chip filter gains a 2nd outer drop-shadow at
2
+ * 6px with halved color-mix opacity on both pin (60%→30%) + hover
3
+ * (40%→20%) branches. 22nd anchor in multi-layer halo family.
4
+ */
5
+ import { readFileSync } from 'node:fs';
6
+
7
+ const src = readFileSync('/home/vansin/agent-network-dashboard/app/components/TopoGraph.tsx', 'utf8');
8
+ const sourcePin = /`drop-shadow\(0 0 3px color-mix\(in srgb, \$\{v\.color\} 60%, transparent\)\) drop-shadow\(0 0 6px color-mix\(in srgb, \$\{v\.color\} 30%, transparent\)\) brightness\(1\.15\)`/.test(src);
9
+ const sourceHover = /`drop-shadow\(0 0 3px color-mix\(in srgb, \$\{v\.color\} 40%, transparent\)\) drop-shadow\(0 0 6px color-mix\(in srgb, \$\{v\.color\} 20%, transparent\)\) brightness\(1\.15\)`/.test(src);
10
+
11
+ const results = {
12
+ source_pin_branch: sourcePin,
13
+ source_hover_branch: sourceHover,
14
+ };
15
+ const ok = Object.values(results).every(Boolean);
16
+ console.log(`${ok ? '✅' : '❌'} R663 vendor chip multi-layer halo (pin + hover branches):`,
17
+ JSON.stringify(results, null, 2));
18
+ process.exit(ok ? 0 : 1);
@@ -0,0 +1,88 @@
1
+ /* Round 690 — extends vendor letter glyph (R676) + count suffix (R688)
2
+ * halo gates from hover-only to (hover || pin). When a vendor is
3
+ * pinned, all 3 nested layers (outer chip rect R663 + inner letter +
4
+ * count) glow persistently in the brand hue. Closes vendor chip
5
+ * pin-gesture symmetry — sibling to R689 (working/online chip pin-
6
+ * gated halo).
7
+ *
8
+ * Source assertions:
9
+ * - vendor letter glyph filter gate: (hoveredVendor || isPinned)
10
+ * - count suffix filter gate: (hoveredVendor || isPinned)
11
+ * - halo-layers attrs reflect extended gate logic
12
+ *
13
+ * Runtime assertions:
14
+ * - vendor letter glyphs + suffixes render (multiple vendors)
15
+ * - rest halo-layers='0' on both (no hover, no pin)
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, model) => ({
38
+ alias, status: 'idle', 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('a·1', 'claude-opus-4'),
44
+ mk('a·2', 'gpt-4o'),
45
+ mk('a·3', 'gemini-pro'),
46
+ ] } });
47
+ });
48
+ await ctx.route('**/api/hub/messages*', (r) => r.fulfill({ json: { messages: [] } }));
49
+ await ctx.route('**/api/hub/tasks*', (r) => r.fulfill({ json: { tasks: [] } }));
50
+ const page = await ctx.newPage();
51
+ await page.goto('http://127.0.0.1:3000/', { waitUntil: 'networkidle' });
52
+ await page.waitForSelector('[data-vendor-letter-glyph]', { timeout: 15000, state: 'attached' });
53
+ await page.waitForTimeout(300);
54
+
55
+ const runtimeState = await page.evaluate(() => {
56
+ const glyphs = Array.from(document.querySelectorAll('[data-vendor-letter-glyph]'));
57
+ const suffixes = Array.from(document.querySelectorAll('[data-vendor-letter-count-suffix]'));
58
+ return {
59
+ glyphs_count: glyphs.length,
60
+ suffixes_count: suffixes.length,
61
+ rest_glyph_layers_all_zero: glyphs.every(el => el.getAttribute('data-vendor-letter-glyph-halo-layers') === '0'),
62
+ rest_suffix_layers_all_zero: suffixes.every(el => el.getAttribute('data-vendor-letter-count-suffix-halo-layers') === '0'),
63
+ };
64
+ });
65
+
66
+ await browser.close();
67
+
68
+ const src = readFileSync('/home/vansin/agent-network-dashboard/app/components/TopoGraph.tsx', 'utf8');
69
+ const sourceGlyphGate = /data-vendor-letter-glyph-halo-layers=\{\(hoveredVendor === v\.initial \|\| isPinned\) \? '2' : '0'\}/.test(src);
70
+ const sourceSuffixGate = /data-vendor-letter-count-suffix-halo-layers=\{\(hoveredVendor === v\.initial \|\| isPinned\) \? '2' : '0'\}/.test(src);
71
+ const sourceGlyphFilter = /filter: \(hoveredVendor === v\.initial \|\| isPinned\) \? `drop-shadow\(0 0 2px \$\{v\.color\}80\) drop-shadow\(0 0 4px \$\{v\.color\}40\) brightness\(1\.15\)`/.test(src);
72
+ const sourceSuffixFilter = /filter: \(hoveredVendor === v\.initial \|\| isPinned\)\s*\?\s*`drop-shadow\(0 0 2px \$\{v\.color\}80\) drop-shadow\(0 0 4px \$\{v\.color\}40\)`/.test(src);
73
+
74
+ const results = {
75
+ glyphs_present: runtimeState.glyphs_count >= 2,
76
+ suffixes_present: runtimeState.suffixes_count >= 2,
77
+ rest_glyph_zero: runtimeState.rest_glyph_layers_all_zero,
78
+ rest_suffix_zero: runtimeState.rest_suffix_layers_all_zero,
79
+ source_glyph_gate: sourceGlyphGate,
80
+ source_suffix_gate: sourceSuffixGate,
81
+ source_glyph_filter: sourceGlyphFilter,
82
+ source_suffix_filter: sourceSuffixFilter,
83
+ };
84
+ const ok = Object.values(results).every(Boolean);
85
+ console.log(`${ok ? '✅' : '❌'} R690 vendor letter glyph + count suffix pin-gated halo:`,
86
+ JSON.stringify(results, null, 2),
87
+ `\n runtime: glyphs=${runtimeState.glyphs_count}, suffixes=${runtimeState.suffixes_count}`);
88
+ process.exit(ok ? 0 : 1);
@@ -0,0 +1,79 @@
1
+ /* Round 688 — vendor count suffix `:N` (next to each vendor letter
2
+ * glyph) extends from 2 group-hover axes (opacity + tracking-wide)
3
+ * to also include multi-layer halo paint axis. Uses the SAME per-
4
+ * vendor v.color tint as the inner letter glyph (R676) and the outer
5
+ * chip (R663) — vendor letter chip now 3/3 nested elements glow in
6
+ * the same brand hue under hover. 2+4 stride, alpha 80/40.
7
+ *
8
+ * Source assertions:
9
+ * - filter uses v.color at 80/40 with 2+4 stride, gated on
10
+ * hoveredVendor === v.initial
11
+ * - data-vendor-letter-count-suffix-halo-layers attr toggles '2'/'0'
12
+ *
13
+ * Runtime assertions:
14
+ * - count suffix spans present (≥2 vendors so multiple ':N' renders)
15
+ * - rest halo-layers='0' on all
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, model) => ({
38
+ alias, status: 'idle', 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('a·1', 'claude-opus-4'),
44
+ mk('a·2', 'gpt-4o'),
45
+ mk('a·3', 'gemini-pro'),
46
+ mk('a·4', 'claude-opus-4'),
47
+ ] } });
48
+ });
49
+ await ctx.route('**/api/hub/messages*', (r) => r.fulfill({ json: { messages: [] } }));
50
+ await ctx.route('**/api/hub/tasks*', (r) => r.fulfill({ json: { tasks: [] } }));
51
+ const page = await ctx.newPage();
52
+ await page.goto('http://127.0.0.1:3000/', { waitUntil: 'networkidle' });
53
+ await page.waitForSelector('[data-vendor-letter-count-suffix]', { timeout: 15000, state: 'attached' });
54
+ await page.waitForTimeout(300);
55
+
56
+ const restState = await page.evaluate(() => {
57
+ return Array.from(document.querySelectorAll('[data-vendor-letter-count-suffix]')).map(el => ({
58
+ layers: el.getAttribute('data-vendor-letter-count-suffix-halo-layers'),
59
+ text: el.textContent,
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: hoveredVendor === v\.initial\s*\?\s*`drop-shadow\(0 0 2px \$\{v\.color\}80\) drop-shadow\(0 0 4px \$\{v\.color\}40\)`\s*: undefined/.test(src);
67
+ const sourceAttr = /data-vendor-letter-count-suffix-halo-layers=\{hoveredVendor === v\.initial \? '2' : '0'\}/.test(src);
68
+
69
+ const results = {
70
+ suffixes_present: restState.length >= 2,
71
+ rest_all_layers_0: restState.every(e => e.layers === '0'),
72
+ source_filter: sourceFilter,
73
+ source_layers_attr: sourceAttr,
74
+ };
75
+ const ok = Object.values(results).every(Boolean);
76
+ console.log(`${ok ? '✅' : '❌'} R688 vendor count suffix multi-layer halo (closes vendor letter chip 3/3):`,
77
+ JSON.stringify(results, null, 2),
78
+ `\n count: ${restState.length}, sample: ${JSON.stringify(restState.slice(0, 3))}`);
79
+ process.exit(ok ? 0 : 1);
@@ -0,0 +1,93 @@
1
+ /* Round 698 — vendor-distribution chip-row outer wrapper joins the
2
+ * R697 wrapper-level :has() halo family. Pre-R698 only the chrome-strip
3
+ * wrappers (Layout/nodeSize/zoom) echoed inner-button hover at the
4
+ * parent scope. R698 extends to a NEW parent: the vendor-distribution
5
+ * chip-row outer <span>. Inner vendor letter chips are <span role="button">
6
+ * (not real <button>), so the CSS uses :has([role="button"]:hover) — a
7
+ * new selector variant extending R697's vocabulary from real-button
8
+ * children to ARIA-button children.
9
+ *
10
+ * Source assertions:
11
+ * - globals.css :has([role="button"]:hover) rule on wrapper attr
12
+ * - globals.css transition rule for the wrapper includes filter
13
+ * - TopoGraph.tsx outer <span> has data-topo-chrome-vendor-distribution-wrapper
14
+ *
15
+ * Runtime assertions:
16
+ * - wrapper present when vendorDist.length > 2 (3+ vendors)
17
+ * - data-attr matches "true"
18
+ *
19
+ * Mock 3 vendors so vendorDist.length > 2 triggers the chip row.
20
+ */
21
+ import { chromium } from 'playwright';
22
+ import { readFileSync } from 'node:fs';
23
+
24
+ const TOKEN = JSON.parse(readFileSync('/home/vansin/.anet/config.json', 'utf8')).token;
25
+ const fresh = new Date(Date.now() - 60 * 1000).toISOString();
26
+
27
+ const browser = await chromium.launch({ headless: true });
28
+ const ctx = await browser.newContext({ viewport: { width: 1500, height: 1200 } });
29
+ await ctx.addCookies([{ name: 'anet_dashboard_session', value: `v3:${TOKEN}`, domain: '127.0.0.1', path: '/' }]);
30
+ await ctx.addInitScript(() => {
31
+ try {
32
+ localStorage.setItem('anet-theme', 'cyber');
33
+ localStorage.setItem('anet-topo-layout', 'ring');
34
+ sessionStorage.setItem('anet_v3_auth', '1');
35
+ } catch {}
36
+ });
37
+ await ctx.route('**/api/hub/status*', async (route) => {
38
+ const r = await route.fetch();
39
+ const b = await r.json();
40
+ const nid = (b.sessions || [])[0]?.network_id || 'default';
41
+ const mk = (alias, model) => ({
42
+ alias, status: 'idle', model, runtime: 'claude-code-cli',
43
+ network_id: nid, project_dir: null,
44
+ created_at: fresh, updated_at: fresh, last_seen_at: fresh,
45
+ });
46
+ // 3 distinct vendors → vendorDist.length === 3 → chip row renders.
47
+ await route.fulfill({ response: r, json: { ...b, sessions: [
48
+ mk('a·1', 'claude-opus-4'),
49
+ mk('a·2', 'gpt-5'),
50
+ mk('a·3', 'glm-4.6'),
51
+ ] } });
52
+ });
53
+ await ctx.route('**/api/hub/messages*', (r) => r.fulfill({ json: { messages: [] } }));
54
+ await ctx.route('**/api/hub/tasks*', (r) => r.fulfill({ json: { tasks: [] } }));
55
+ const page = await ctx.newPage();
56
+ await page.goto('http://127.0.0.1:3000/', { waitUntil: 'networkidle' });
57
+ await page.waitForSelector('[data-topo-chrome-vendor-distribution-wrapper]', { timeout: 15000, state: 'attached' });
58
+ await page.waitForTimeout(300);
59
+
60
+ const runtimeState = await page.evaluate(() => {
61
+ const wrapper = document.querySelector('[data-topo-chrome-vendor-distribution-wrapper]');
62
+ if (!wrapper) return null;
63
+ // Count inner role="button" children (the vendor letter chips).
64
+ const innerChips = wrapper.querySelectorAll('[role="button"]');
65
+ return {
66
+ wrapper_present: true,
67
+ wrapper_attr: wrapper.getAttribute('data-topo-chrome-vendor-distribution-wrapper'),
68
+ inner_role_button_count: innerChips.length,
69
+ };
70
+ });
71
+
72
+ await browser.close();
73
+
74
+ const cssSrc = readFileSync('/home/vansin/agent-network-dashboard/app/globals.css', 'utf8');
75
+ const tsxSrc = readFileSync('/home/vansin/agent-network-dashboard/app/components/TopoGraph.tsx', 'utf8');
76
+
77
+ const cssHoverRule = /\[data-topo-chrome-vendor-distribution-wrapper\]:has\(\[role="button"\]:hover\)\s*\{[\s\S]*?drop-shadow\(0 0 2px rgba\(103, 232, 249, 0\.5\)\)[\s\S]*?drop-shadow\(0 0 4px rgba\(103, 232, 249, 0\.25\)\)/.test(cssSrc);
78
+ const cssTransition = /\[data-topo-chrome-vendor-distribution-wrapper\]\s*\{[\s\S]*?transition:[\s\S]*?filter 200ms/.test(cssSrc);
79
+ const tsxWrapperAttr = /data-topo-chrome-vendor-distribution-wrapper="true"/.test(tsxSrc);
80
+
81
+ const results = {
82
+ wrapper_present: !!runtimeState?.wrapper_present,
83
+ wrapper_attr_true: runtimeState?.wrapper_attr === 'true',
84
+ inner_chips_present: (runtimeState?.inner_role_button_count ?? 0) >= 3,
85
+ css_hover_rule: cssHoverRule,
86
+ css_transition: cssTransition,
87
+ tsx_wrapper_attr: tsxWrapperAttr,
88
+ };
89
+ const ok = Object.values(results).every(Boolean);
90
+ console.log(`${ok ? '✅' : '❌'} R698 vendor-distribution wrapper :has() multi-layer halo (54th anchor — 2nd wrapper-level :has() anchor):`,
91
+ JSON.stringify(results, null, 2),
92
+ `\n runtime: ${JSON.stringify(runtimeState)}`);
93
+ process.exit(ok ? 0 : 1);