@sleep2agi/agent-network-dashboard 0.4.6-preview.32 → 0.4.6-preview.34

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 (161) 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 +31 -31
  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/agent-network-dashboard_09kk21a._.js +1 -1
  133. package/.next/server/chunks/ssr/agent-network-dashboard_09kk21a._.js.map +1 -1
  134. package/.next/server/chunks/ssr/agent-network-dashboard_app_01jhlxz._.js +1 -1
  135. package/.next/server/chunks/ssr/agent-network-dashboard_app_01jhlxz._.js.map +1 -1
  136. package/.next/server/chunks/ssr/agent-network-dashboard_app_09d29my._.js +1 -1
  137. package/.next/server/chunks/ssr/agent-network-dashboard_app_09d29my._.js.map +1 -1
  138. package/.next/server/chunks/ssr/agent-network-dashboard_app_components_0mvyi-4._.js +1 -1
  139. package/.next/server/chunks/ssr/agent-network-dashboard_app_components_0mvyi-4._.js.map +1 -1
  140. package/.next/server/middleware-build-manifest.js +3 -3
  141. package/.next/server/pages/404.html +2 -2
  142. package/.next/server/pages/500.html +1 -1
  143. package/.next/server/server-reference-manifest.js +1 -1
  144. package/.next/server/server-reference-manifest.json +1 -1
  145. package/.next/static/chunks/{0h_~v6f9o~_in.js → 02pgt3ua.i4ac.js} +1 -1
  146. package/.next/static/chunks/{08b1xx89c0ts9.js → 0fiwcvzqs7ily.js} +1 -1
  147. package/.next/static/chunks/{0pl7l_.2im.j0.js → 0kwf..oq7.27x.js} +3 -3
  148. package/.next/static/chunks/12m8i9_5p2n~8.js +1 -0
  149. package/.next/static/chunks/{09nd.t_hd.y6t.css → 13.zti9ix.1eh.css} +1 -1
  150. package/.next/trace +2 -2
  151. package/.next/trace-build +1 -1
  152. package/app/components/HelpOverlay.tsx +16 -0
  153. package/app/components/TopoGraph.tsx +38 -9
  154. package/package.json +1 -1
  155. package/scripts/help-overlay-topo-test.mjs +44 -0
  156. package/scripts/topo-label-lift-test.mjs +115 -0
  157. package/scripts/topo-overlap-test.mjs +32 -5
  158. package/.next/static/chunks/0_8snedeata9k.js +0 -1
  159. /package/.next/static/{QkCLPQNNPLHlzKVvmAInn → CF6cwAmsx-YPti9XxgcEF}/_buildManifest.js +0 -0
  160. /package/.next/static/{QkCLPQNNPLHlzKVvmAInn → CF6cwAmsx-YPti9XxgcEF}/_clientMiddlewareManifest.js +0 -0
  161. /package/.next/static/{QkCLPQNNPLHlzKVvmAInn → CF6cwAmsx-YPti9XxgcEF}/_ssgManifest.js +0 -0
package/.next/trace CHANGED
@@ -1,2 +1,2 @@
1
- [{"name":"generate-buildid","duration":258,"timestamp":13338461602,"id":4,"parentId":1,"tags":{},"startTime":1778821310708,"traceId":"5d9c6e2d2cb0bace"},{"name":"load-custom-routes","duration":490,"timestamp":13338461996,"id":5,"parentId":1,"tags":{},"startTime":1778821310708,"traceId":"5d9c6e2d2cb0bace"},{"name":"create-dist-dir","duration":624,"timestamp":13338462529,"id":6,"parentId":1,"tags":{},"startTime":1778821310709,"traceId":"5d9c6e2d2cb0bace"},{"name":"clean","duration":497,"timestamp":13338463742,"id":7,"parentId":1,"tags":{},"startTime":1778821310710,"traceId":"5d9c6e2d2cb0bace"},{"name":"discover-routes","duration":9640,"timestamp":13338543556,"id":8,"parentId":1,"tags":{},"startTime":1778821310790,"traceId":"5d9c6e2d2cb0bace"},{"name":"create-root-mapping","duration":105,"timestamp":13338553253,"id":9,"parentId":1,"tags":{},"startTime":1778821310800,"traceId":"5d9c6e2d2cb0bace"},{"name":"generate-route-types","duration":33652,"timestamp":13338555886,"id":10,"parentId":1,"tags":{},"startTime":1778821310802,"traceId":"5d9c6e2d2cb0bace"},{"name":"public-dir-conflict-check","duration":129,"timestamp":13338589706,"id":11,"parentId":1,"tags":{},"startTime":1778821310836,"traceId":"5d9c6e2d2cb0bace"},{"name":"generate-routes-manifest","duration":5731,"timestamp":13338589997,"id":12,"parentId":1,"tags":{},"startTime":1778821310836,"traceId":"5d9c6e2d2cb0bace"},{"name":"run-turbopack","duration":5226573,"timestamp":13338602363,"id":14,"parentId":1,"tags":{},"startTime":1778821310849,"traceId":"5d9c6e2d2cb0bace"},{"name":"turbopack-build-events","duration":102,"timestamp":13338892687,"id":15,"parentId":1,"tags":{},"startTime":1778821311139,"traceId":"5d9c6e2d2cb0bace"},{"name":"run-typescript","duration":8146172,"timestamp":13343840026,"id":16,"parentId":1,"tags":{},"startTime":1778821316086,"traceId":"5d9c6e2d2cb0bace"},{"name":"generate-required-server-files","duration":2106,"timestamp":13351987276,"id":18,"parentId":1,"tags":{},"startTime":1778821324234,"traceId":"5d9c6e2d2cb0bace"},{"name":"check-static-error-page","duration":12792,"timestamp":13352161429,"id":20,"parentId":19,"tags":{},"startTime":1778821324408,"traceId":"5d9c6e2d2cb0bace"},{"name":"is-page-static","duration":469507,"timestamp":13352177480,"id":63,"parentId":22,"tags":{},"startTime":1778821324424,"traceId":"5d9c6e2d2cb0bace"},{"name":"check-page","duration":483595,"timestamp":13352163611,"id":22,"parentId":19,"tags":{"page":"/_global-error"},"startTime":1778821324410,"traceId":"5d9c6e2d2cb0bace"},{"name":"is-page-static","duration":566142,"timestamp":13352178148,"id":67,"parentId":28,"tags":{},"startTime":1778821324424,"traceId":"5d9c6e2d2cb0bace"},{"name":"check-page","duration":579976,"timestamp":13352166193,"id":28,"parentId":19,"tags":{"page":"/api/hub/audit-log"},"startTime":1778821324412,"traceId":"5d9c6e2d2cb0bace"},{"name":"is-page-static","duration":571289,"timestamp":13352178314,"id":68,"parentId":29,"tags":{},"startTime":1778821324425,"traceId":"5d9c6e2d2cb0bace"},{"name":"check-page","duration":583379,"timestamp":13352166276,"id":29,"parentId":19,"tags":{"page":"/api/hub/auth"},"startTime":1778821324413,"traceId":"5d9c6e2d2cb0bace"},{"name":"is-page-static","duration":576093,"timestamp":13352178756,"id":71,"parentId":33,"tags":{},"startTime":1778821324425,"traceId":"5d9c6e2d2cb0bace"},{"name":"check-page","duration":588137,"timestamp":13352166768,"id":33,"parentId":19,"tags":{"page":"/api/hub/inbox"},"startTime":1778821324413,"traceId":"5d9c6e2d2cb0bace"},{"name":"is-page-static","duration":579050,"timestamp":13352178673,"id":70,"parentId":32,"tags":{},"startTime":1778821324425,"traceId":"5d9c6e2d2cb0bace"},{"name":"check-page","duration":591138,"timestamp":13352166640,"id":32,"parentId":19,"tags":{"page":"/api/hub/health"},"startTime":1778821324413,"traceId":"5d9c6e2d2cb0bace"},{"name":"is-page-static","duration":583169,"timestamp":13352178475,"id":69,"parentId":30,"tags":{},"startTime":1778821324425,"traceId":"5d9c6e2d2cb0bace"},{"name":"check-page","duration":595331,"timestamp":13352166370,"id":30,"parentId":19,"tags":{"page":"/api/hub/broadcast"},"startTime":1778821324413,"traceId":"5d9c6e2d2cb0bace"},{"name":"is-page-static","duration":590755,"timestamp":13352177622,"id":64,"parentId":25,"tags":{},"startTime":1778821324424,"traceId":"5d9c6e2d2cb0bace"},{"name":"check-page","duration":602599,"timestamp":13352165831,"id":25,"parentId":19,"tags":{"page":"/api/auth/login"},"startTime":1778821324412,"traceId":"5d9c6e2d2cb0bace"},{"name":"is-page-static","duration":594606,"timestamp":13352179073,"id":75,"parentId":37,"tags":{},"startTime":1778821324425,"traceId":"5d9c6e2d2cb0bace"},{"name":"check-page","duration":605927,"timestamp":13352167795,"id":37,"parentId":19,"tags":{"page":"/api/hub/nodes"},"startTime":1778821324414,"traceId":"5d9c6e2d2cb0bace"},{"name":"is-page-static","duration":596080,"timestamp":13352177857,"id":66,"parentId":27,"tags":{},"startTime":1778821324424,"traceId":"5d9c6e2d2cb0bace"},{"name":"check-page","duration":607873,"timestamp":13352166106,"id":27,"parentId":19,"tags":{"page":"/api/auth/v3"},"startTime":1778821324412,"traceId":"5d9c6e2d2cb0bace"},{"name":"is-page-static","duration":600008,"timestamp":13352177084,"id":62,"parentId":21,"tags":{},"startTime":1778821324423,"traceId":"5d9c6e2d2cb0bace"},{"name":"check-page","duration":614606,"timestamp":13352162551,"id":21,"parentId":19,"tags":{"page":"/_not-found"},"startTime":1778821324409,"traceId":"5d9c6e2d2cb0bace"},{"name":"is-page-static","duration":599718,"timestamp":13352178889,"id":73,"parentId":35,"tags":{},"startTime":1778821324425,"traceId":"5d9c6e2d2cb0bace"},{"name":"check-page","duration":611613,"timestamp":13352167036,"id":35,"parentId":19,"tags":{"page":"/api/hub/messages"},"startTime":1778821324413,"traceId":"5d9c6e2d2cb0bace"},{"name":"is-page-static","duration":604265,"timestamp":13352179145,"id":79,"parentId":41,"tags":{},"startTime":1778821324425,"traceId":"5d9c6e2d2cb0bace"},{"name":"check-page","duration":615266,"timestamp":13352168184,"id":41,"parentId":19,"tags":{"page":"/api/hub/servers"},"startTime":1778821324414,"traceId":"5d9c6e2d2cb0bace"},{"name":"is-page-static","duration":604993,"timestamp":13352178846,"id":72,"parentId":34,"tags":{},"startTime":1778821324425,"traceId":"5d9c6e2d2cb0bace"},{"name":"check-page","duration":616998,"timestamp":13352166886,"id":34,"parentId":19,"tags":{"page":"/api/hub/license"},"startTime":1778821324413,"traceId":"5d9c6e2d2cb0bace"},{"name":"is-page-static","duration":606695,"timestamp":13352179032,"id":74,"parentId":36,"tags":{},"startTime":1778821324425,"traceId":"5d9c6e2d2cb0bace"},{"name":"check-page","duration":618130,"timestamp":13352167632,"id":36,"parentId":19,"tags":{"page":"/api/hub/networks"},"startTime":1778821324414,"traceId":"5d9c6e2d2cb0bace"},{"name":"is-page-static","duration":610741,"timestamp":13352179160,"id":80,"parentId":42,"tags":{},"startTime":1778821324425,"traceId":"5d9c6e2d2cb0bace"},{"name":"check-page","duration":621676,"timestamp":13352168259,"id":42,"parentId":19,"tags":{"page":"/api/hub/session"},"startTime":1778821324415,"traceId":"5d9c6e2d2cb0bace"},{"name":"is-page-static","duration":614873,"timestamp":13352179203,"id":83,"parentId":45,"tags":{},"startTime":1778821324425,"traceId":"5d9c6e2d2cb0bace"},{"name":"check-page","duration":625684,"timestamp":13352168449,"id":45,"parentId":19,"tags":{"page":"/api/hub/task-events"},"startTime":1778821324415,"traceId":"5d9c6e2d2cb0bace"},{"name":"is-page-static","duration":618430,"timestamp":13352179175,"id":81,"parentId":43,"tags":{},"startTime":1778821324425,"traceId":"5d9c6e2d2cb0bace"},{"name":"check-page","duration":629332,"timestamp":13352168323,"id":43,"parentId":19,"tags":{"page":"/api/hub/stats"},"startTime":1778821324415,"traceId":"5d9c6e2d2cb0bace"},{"name":"is-page-static","duration":619597,"timestamp":13352179218,"id":84,"parentId":46,"tags":{},"startTime":1778821324425,"traceId":"5d9c6e2d2cb0bace"},{"name":"check-page","duration":630345,"timestamp":13352168509,"id":46,"parentId":19,"tags":{"page":"/api/hub/tasks"},"startTime":1778821324415,"traceId":"5d9c6e2d2cb0bace"},{"name":"is-page-static","duration":622981,"timestamp":13352179089,"id":76,"parentId":38,"tags":{},"startTime":1778821324425,"traceId":"5d9c6e2d2cb0bace"},{"name":"check-page","duration":634192,"timestamp":13352167929,"id":38,"parentId":19,"tags":{"page":"/api/hub/register"},"startTime":1778821324414,"traceId":"5d9c6e2d2cb0bace"},{"name":"is-page-static","duration":623587,"timestamp":13352179244,"id":86,"parentId":48,"tags":{},"startTime":1778821324426,"traceId":"5d9c6e2d2cb0bace"},{"name":"check-page","duration":634211,"timestamp":13352168659,"id":48,"parentId":19,"tags":{"page":"/api/hub/tokens"},"startTime":1778821324415,"traceId":"5d9c6e2d2cb0bace"},{"name":"is-page-static","duration":620742,"timestamp":13352187947,"id":88,"parentId":24,"tags":{},"startTime":1778821324434,"traceId":"5d9c6e2d2cb0bace"},{"name":"check-page","duration":644755,"timestamp":13352163976,"id":24,"parentId":19,"tags":{"page":"/api/anet/config"},"startTime":1778821324410,"traceId":"5d9c6e2d2cb0bace"},{"name":"is-page-static","duration":630222,"timestamp":13352179117,"id":77,"parentId":39,"tags":{},"startTime":1778821324425,"traceId":"5d9c6e2d2cb0bace"},{"name":"check-page","duration":641343,"timestamp":13352168036,"id":39,"parentId":19,"tags":{"page":"/api/hub/send"},"startTime":1778821324414,"traceId":"5d9c6e2d2cb0bace"},{"name":"is-page-static","duration":624474,"timestamp":13352189423,"id":89,"parentId":31,"tags":{},"startTime":1778821324436,"traceId":"5d9c6e2d2cb0bace"},{"name":"check-page","duration":647490,"timestamp":13352166447,"id":31,"parentId":19,"tags":{"page":"/api/hub/events"},"startTime":1778821324413,"traceId":"5d9c6e2d2cb0bace"},{"name":"is-page-static","duration":639370,"timestamp":13352179190,"id":82,"parentId":44,"tags":{},"startTime":1778821324425,"traceId":"5d9c6e2d2cb0bace"},{"name":"check-page","duration":650221,"timestamp":13352168381,"id":44,"parentId":19,"tags":{"page":"/api/hub/status"},"startTime":1778821324415,"traceId":"5d9c6e2d2cb0bace"},{"name":"is-page-static","duration":639502,"timestamp":13352179259,"id":87,"parentId":49,"tags":{},"startTime":1778821324426,"traceId":"5d9c6e2d2cb0bace"},{"name":"check-page","duration":650075,"timestamp":13352168722,"id":49,"parentId":19,"tags":{"page":"/favicon.ico"},"startTime":1778821324415,"traceId":"5d9c6e2d2cb0bace"},{"name":"is-page-static","duration":644321,"timestamp":13352179233,"id":85,"parentId":47,"tags":{},"startTime":1778821324426,"traceId":"5d9c6e2d2cb0bace"},{"name":"check-page","duration":654996,"timestamp":13352168597,"id":47,"parentId":19,"tags":{"page":"/api/hub/tmux"},"startTime":1778821324415,"traceId":"5d9c6e2d2cb0bace"},{"name":"is-page-static","duration":654956,"timestamp":13352177742,"id":65,"parentId":26,"tags":{},"startTime":1778821324424,"traceId":"5d9c6e2d2cb0bace"},{"name":"check-page","duration":666775,"timestamp":13352165974,"id":26,"parentId":19,"tags":{"page":"/api/auth/logout"},"startTime":1778821324412,"traceId":"5d9c6e2d2cb0bace"},{"name":"is-page-static","duration":678705,"timestamp":13352191902,"id":91,"parentId":50,"tags":{},"startTime":1778821324438,"traceId":"5d9c6e2d2cb0bace"},{"name":"check-page","duration":701599,"timestamp":13352169078,"id":50,"parentId":19,"tags":{"page":"/login"},"startTime":1778821324415,"traceId":"5d9c6e2d2cb0bace"},{"name":"is-page-static","duration":683994,"timestamp":13352191928,"id":93,"parentId":52,"tags":{},"startTime":1778821324438,"traceId":"5d9c6e2d2cb0bace"},{"name":"check-page","duration":706630,"timestamp":13352169636,"id":52,"parentId":19,"tags":{"page":"/messages"},"startTime":1778821324416,"traceId":"5d9c6e2d2cb0bace"},{"name":"is-page-static","duration":697355,"timestamp":13352179133,"id":78,"parentId":40,"tags":{},"startTime":1778821324425,"traceId":"5d9c6e2d2cb0bace"},{"name":"check-page","duration":708412,"timestamp":13352168119,"id":40,"parentId":19,"tags":{"page":"/api/hub/server-logs"},"startTime":1778821324414,"traceId":"5d9c6e2d2cb0bace"},{"name":"is-page-static","duration":684740,"timestamp":13352191914,"id":92,"parentId":51,"tags":{},"startTime":1778821324438,"traceId":"5d9c6e2d2cb0bace"},{"name":"check-page","duration":707388,"timestamp":13352169291,"id":51,"parentId":19,"tags":{"page":"/logs"},"startTime":1778821324416,"traceId":"5d9c6e2d2cb0bace"},{"name":"is-page-static","duration":689103,"timestamp":13352191967,"id":96,"parentId":56,"tags":{},"startTime":1778821324438,"traceId":"5d9c6e2d2cb0bace"},{"name":"check-page","duration":710139,"timestamp":13352170992,"id":56,"parentId":19,"tags":{"page":"/server-logs"},"startTime":1778821324417,"traceId":"5d9c6e2d2cb0bace"},{"name":"is-page-static","duration":689438,"timestamp":13352191871,"id":90,"parentId":23,"tags":{},"startTime":1778821324438,"traceId":"5d9c6e2d2cb0bace"},{"name":"check-page","duration":717559,"timestamp":13352163799,"id":23,"parentId":19,"tags":{"page":"/admin"},"startTime":1778821324410,"traceId":"5d9c6e2d2cb0bace"},{"name":"is-page-static","duration":691241,"timestamp":13352191981,"id":97,"parentId":57,"tags":{},"startTime":1778821324438,"traceId":"5d9c6e2d2cb0bace"},{"name":"check-page","duration":710212,"timestamp":13352173044,"id":57,"parentId":19,"tags":{"page":"/settings/networks"},"startTime":1778821324419,"traceId":"5d9c6e2d2cb0bace"},{"name":"is-page-static","duration":693396,"timestamp":13352192048,"id":100,"parentId":61,"tags":{},"startTime":1778821324438,"traceId":"5d9c6e2d2cb0bace"},{"name":"check-page","duration":711514,"timestamp":13352173967,"id":61,"parentId":19,"tags":{"page":"/tasks"},"startTime":1778821324420,"traceId":"5d9c6e2d2cb0bace"},{"name":"is-page-static","duration":694755,"timestamp":13352191994,"id":98,"parentId":59,"tags":{},"startTime":1778821324438,"traceId":"5d9c6e2d2cb0bace"},{"name":"check-page","duration":713079,"timestamp":13352173704,"id":59,"parentId":19,"tags":{"page":"/settings/tokens"},"startTime":1778821324420,"traceId":"5d9c6e2d2cb0bace"},{"name":"is-page-static","duration":688417,"timestamp":13352200944,"id":101,"parentId":55,"tags":{},"startTime":1778821324447,"traceId":"5d9c6e2d2cb0bace"},{"name":"check-page","duration":718957,"timestamp":13352170437,"id":55,"parentId":19,"tags":{"page":"/"},"startTime":1778821324417,"traceId":"5d9c6e2d2cb0bace"},{"name":"is-page-static","duration":683437,"timestamp":13352206550,"id":102,"parentId":58,"tags":{},"startTime":1778821324453,"traceId":"5d9c6e2d2cb0bace"},{"name":"check-page","duration":716781,"timestamp":13352173275,"id":58,"parentId":19,"tags":{"page":"/settings"},"startTime":1778821324420,"traceId":"5d9c6e2d2cb0bace"},{"name":"is-page-static","duration":699613,"timestamp":13352192029,"id":99,"parentId":60,"tags":{},"startTime":1778821324438,"traceId":"5d9c6e2d2cb0bace"},{"name":"check-page","duration":717832,"timestamp":13352173844,"id":60,"parentId":19,"tags":{"page":"/tasks/[id]"},"startTime":1778821324420,"traceId":"5d9c6e2d2cb0bace"},{"name":"is-page-static","duration":700256,"timestamp":13352191943,"id":94,"parentId":53,"tags":{},"startTime":1778821324438,"traceId":"5d9c6e2d2cb0bace"},{"name":"check-page","duration":722294,"timestamp":13352169923,"id":53,"parentId":19,"tags":{"page":"/node"},"startTime":1778821324416,"traceId":"5d9c6e2d2cb0bace"},{"name":"is-page-static","duration":717727,"timestamp":13352191953,"id":95,"parentId":54,"tags":{},"startTime":1778821324438,"traceId":"5d9c6e2d2cb0bace"},{"name":"check-page","duration":739537,"timestamp":13352170182,"id":54,"parentId":19,"tags":{"page":"/nodes"},"startTime":1778821324416,"traceId":"5d9c6e2d2cb0bace"},{"name":"static-check","duration":749057,"timestamp":13352160715,"id":19,"parentId":1,"tags":{},"startTime":1778821324407,"traceId":"5d9c6e2d2cb0bace"},{"name":"write-routes-manifest","duration":407,"timestamp":13352915993,"id":104,"parentId":1,"tags":{},"startTime":1778821325162,"traceId":"5d9c6e2d2cb0bace"},{"name":"load-dotenv","duration":37,"timestamp":13352927633,"id":107,"parentId":106,"tags":{},"startTime":1778821325174,"traceId":"5d9c6e2d2cb0bace"},{"name":"run-export-path-map","duration":665,"timestamp":13352930684,"id":108,"parentId":106,"tags":{},"startTime":1778821325177,"traceId":"5d9c6e2d2cb0bace"},{"name":"next-export","duration":569893,"timestamp":13352926380,"id":106,"parentId":1,"tags":{},"startTime":1778821325173,"traceId":"5d9c6e2d2cb0bace"}]
2
- [{"name":"move-exported-app-not-found-","duration":2455,"timestamp":13353499993,"id":109,"parentId":105,"tags":{},"startTime":1778821325746,"traceId":"5d9c6e2d2cb0bace"},{"name":"move-exported-app-global-error-","duration":642,"timestamp":13353502578,"id":110,"parentId":105,"tags":{},"startTime":1778821325749,"traceId":"5d9c6e2d2cb0bace"},{"name":"static-generation","duration":585023,"timestamp":13352920461,"id":105,"parentId":1,"tags":{},"startTime":1778821325167,"traceId":"5d9c6e2d2cb0bace"},{"name":"write-routes-manifest","duration":588,"timestamp":13353505718,"id":111,"parentId":1,"tags":{},"startTime":1778821325752,"traceId":"5d9c6e2d2cb0bace"},{"name":"print-tree-view","duration":3910,"timestamp":13353524082,"id":112,"parentId":1,"tags":{},"startTime":1778821325770,"traceId":"5d9c6e2d2cb0bace"},{"name":"write-route-bundle-stats","duration":12257,"timestamp":13353528048,"id":113,"parentId":1,"tags":{},"startTime":1778821325774,"traceId":"5d9c6e2d2cb0bace"},{"name":"telemetry-flush","duration":21736,"timestamp":13353540336,"id":114,"parentId":1,"tags":{},"startTime":1778821325787,"traceId":"5d9c6e2d2cb0bace"},{"name":"next-build","duration":15155339,"timestamp":13338406775,"id":1,"tags":{"buildMode":"default","version":"16.2.3","bundler":"turbopack","has-custom-webpack-config":"false","use-build-worker":"true"},"startTime":1778821310653,"traceId":"5d9c6e2d2cb0bace"}]
1
+ [{"name":"generate-buildid","duration":324,"timestamp":14660751802,"id":4,"parentId":1,"tags":{},"startTime":1778822632998,"traceId":"c1985a2799753063"},{"name":"load-custom-routes","duration":673,"timestamp":14660752281,"id":5,"parentId":1,"tags":{},"startTime":1778822632999,"traceId":"c1985a2799753063"},{"name":"create-dist-dir","duration":752,"timestamp":14660753035,"id":6,"parentId":1,"tags":{},"startTime":1778822632999,"traceId":"c1985a2799753063"},{"name":"clean","duration":587,"timestamp":14660754460,"id":7,"parentId":1,"tags":{},"startTime":1778822633001,"traceId":"c1985a2799753063"},{"name":"discover-routes","duration":11274,"timestamp":14660847101,"id":8,"parentId":1,"tags":{},"startTime":1778822633093,"traceId":"c1985a2799753063"},{"name":"create-root-mapping","duration":118,"timestamp":14660858445,"id":9,"parentId":1,"tags":{},"startTime":1778822633105,"traceId":"c1985a2799753063"},{"name":"generate-route-types","duration":32115,"timestamp":14660861587,"id":10,"parentId":1,"tags":{},"startTime":1778822633108,"traceId":"c1985a2799753063"},{"name":"public-dir-conflict-check","duration":102,"timestamp":14660893865,"id":11,"parentId":1,"tags":{},"startTime":1778822633140,"traceId":"c1985a2799753063"},{"name":"generate-routes-manifest","duration":6615,"timestamp":14660894143,"id":12,"parentId":1,"tags":{},"startTime":1778822633140,"traceId":"c1985a2799753063"},{"name":"run-turbopack","duration":5936003,"timestamp":14660907302,"id":14,"parentId":1,"tags":{},"startTime":1778822633154,"traceId":"c1985a2799753063"},{"name":"turbopack-build-events","duration":114,"timestamp":14661209357,"id":15,"parentId":1,"tags":{},"startTime":1778822633456,"traceId":"c1985a2799753063"},{"name":"run-typescript","duration":8724258,"timestamp":14666853018,"id":16,"parentId":1,"tags":{},"startTime":1778822639099,"traceId":"c1985a2799753063"},{"name":"generate-required-server-files","duration":2624,"timestamp":14675578600,"id":18,"parentId":1,"tags":{},"startTime":1778822647825,"traceId":"c1985a2799753063"},{"name":"check-static-error-page","duration":12974,"timestamp":14675752124,"id":20,"parentId":19,"tags":{},"startTime":1778822647998,"traceId":"c1985a2799753063"},{"name":"is-page-static","duration":557687,"timestamp":14675769801,"id":66,"parentId":27,"tags":{},"startTime":1778822648016,"traceId":"c1985a2799753063"},{"name":"check-page","duration":569843,"timestamp":14675757827,"id":27,"parentId":19,"tags":{"page":"/api/auth/v3"},"startTime":1778822648004,"traceId":"c1985a2799753063"},{"name":"is-page-static","duration":562825,"timestamp":14675770389,"id":69,"parentId":30,"tags":{},"startTime":1778822648017,"traceId":"c1985a2799753063"},{"name":"check-page","duration":575005,"timestamp":14675758288,"id":30,"parentId":19,"tags":{"page":"/api/hub/broadcast"},"startTime":1778822648005,"traceId":"c1985a2799753063"},{"name":"is-page-static","duration":592823,"timestamp":14675768429,"id":63,"parentId":22,"tags":{},"startTime":1778822648015,"traceId":"c1985a2799753063"},{"name":"check-page","duration":606857,"timestamp":14675754471,"id":22,"parentId":19,"tags":{"page":"/_global-error"},"startTime":1778822648001,"traceId":"c1985a2799753063"},{"name":"is-page-static","duration":592003,"timestamp":14675769506,"id":64,"parentId":25,"tags":{},"startTime":1778822648016,"traceId":"c1985a2799753063"},{"name":"check-page","duration":604058,"timestamp":14675757491,"id":25,"parentId":19,"tags":{"page":"/api/auth/login"},"startTime":1778822648004,"traceId":"c1985a2799753063"},{"name":"is-page-static","duration":591128,"timestamp":14675770566,"id":70,"parentId":32,"tags":{},"startTime":1778822648017,"traceId":"c1985a2799753063"},{"name":"check-page","duration":603058,"timestamp":14675758675,"id":32,"parentId":19,"tags":{"page":"/api/hub/health"},"startTime":1778822648005,"traceId":"c1985a2799753063"},{"name":"is-page-static","duration":596374,"timestamp":14675770770,"id":73,"parentId":35,"tags":{},"startTime":1778822648017,"traceId":"c1985a2799753063"},{"name":"check-page","duration":608252,"timestamp":14675758951,"id":35,"parentId":19,"tags":{"page":"/api/hub/messages"},"startTime":1778822648005,"traceId":"c1985a2799753063"},{"name":"is-page-static","duration":603245,"timestamp":14675770902,"id":74,"parentId":36,"tags":{},"startTime":1778822648017,"traceId":"c1985a2799753063"},{"name":"check-page","duration":614789,"timestamp":14675759422,"id":36,"parentId":19,"tags":{"page":"/api/hub/networks"},"startTime":1778822648006,"traceId":"c1985a2799753063"},{"name":"is-page-static","duration":609120,"timestamp":14675770097,"id":67,"parentId":28,"tags":{},"startTime":1778822648016,"traceId":"c1985a2799753063"},{"name":"check-page","duration":621325,"timestamp":14675757955,"id":28,"parentId":19,"tags":{"page":"/api/hub/audit-log"},"startTime":1778822648004,"traceId":"c1985a2799753063"},{"name":"is-page-static","duration":614321,"timestamp":14675770961,"id":76,"parentId":38,"tags":{},"startTime":1778822648017,"traceId":"c1985a2799753063"},{"name":"check-page","duration":625552,"timestamp":14675759803,"id":38,"parentId":19,"tags":{"page":"/api/hub/register"},"startTime":1778822648006,"traceId":"c1985a2799753063"},{"name":"is-page-static","duration":616544,"timestamp":14675770736,"id":72,"parentId":34,"tags":{},"startTime":1778822648017,"traceId":"c1985a2799753063"},{"name":"check-page","duration":628468,"timestamp":14675758865,"id":34,"parentId":19,"tags":{"page":"/api/hub/license"},"startTime":1778822648005,"traceId":"c1985a2799753063"},{"name":"is-page-static","duration":617835,"timestamp":14675769704,"id":65,"parentId":26,"tags":{},"startTime":1778822648016,"traceId":"c1985a2799753063"},{"name":"check-page","duration":629890,"timestamp":14675757685,"id":26,"parentId":19,"tags":{"page":"/api/auth/logout"},"startTime":1778822648004,"traceId":"c1985a2799753063"},{"name":"is-page-static","duration":617913,"timestamp":14675770940,"id":75,"parentId":37,"tags":{},"startTime":1778822648017,"traceId":"c1985a2799753063"},{"name":"check-page","duration":629244,"timestamp":14675759650,"id":37,"parentId":19,"tags":{"page":"/api/hub/nodes"},"startTime":1778822648006,"traceId":"c1985a2799753063"},{"name":"is-page-static","duration":622267,"timestamp":14675770256,"id":68,"parentId":29,"tags":{},"startTime":1778822648017,"traceId":"c1985a2799753063"},{"name":"check-page","duration":634446,"timestamp":14675758119,"id":29,"parentId":19,"tags":{"page":"/api/hub/auth"},"startTime":1778822648004,"traceId":"c1985a2799753063"},{"name":"is-page-static","duration":623394,"timestamp":14675771043,"id":80,"parentId":42,"tags":{},"startTime":1778822648017,"traceId":"c1985a2799753063"},{"name":"check-page","duration":634354,"timestamp":14675760126,"id":42,"parentId":19,"tags":{"page":"/api/hub/session"},"startTime":1778822648006,"traceId":"c1985a2799753063"},{"name":"is-page-static","duration":626584,"timestamp":14675768110,"id":62,"parentId":21,"tags":{},"startTime":1778822648014,"traceId":"c1985a2799753063"},{"name":"check-page","duration":641400,"timestamp":14675753328,"id":21,"parentId":19,"tags":{"page":"/_not-found"},"startTime":1778822648000,"traceId":"c1985a2799753063"},{"name":"is-page-static","duration":623879,"timestamp":14675770995,"id":78,"parentId":40,"tags":{},"startTime":1778822648017,"traceId":"c1985a2799753063"},{"name":"check-page","duration":634955,"timestamp":14675759956,"id":40,"parentId":19,"tags":{"page":"/api/hub/server-logs"},"startTime":1778822648006,"traceId":"c1985a2799753063"},{"name":"is-page-static","duration":630181,"timestamp":14675771069,"id":82,"parentId":44,"tags":{},"startTime":1778822648017,"traceId":"c1985a2799753063"},{"name":"check-page","duration":641020,"timestamp":14675760295,"id":44,"parentId":19,"tags":{"page":"/api/hub/status"},"startTime":1778822648007,"traceId":"c1985a2799753063"},{"name":"is-page-static","duration":637070,"timestamp":14675771113,"id":85,"parentId":47,"tags":{},"startTime":1778822648017,"traceId":"c1985a2799753063"},{"name":"check-page","duration":647709,"timestamp":14675760527,"id":47,"parentId":19,"tags":{"page":"/api/hub/tmux"},"startTime":1778822648007,"traceId":"c1985a2799753063"},{"name":"is-page-static","duration":638314,"timestamp":14675771098,"id":84,"parentId":46,"tags":{},"startTime":1778822648017,"traceId":"c1985a2799753063"},{"name":"check-page","duration":649036,"timestamp":14675760435,"id":46,"parentId":19,"tags":{"page":"/api/hub/tasks"},"startTime":1778822648007,"traceId":"c1985a2799753063"},{"name":"is-page-static","duration":640206,"timestamp":14675770976,"id":77,"parentId":39,"tags":{},"startTime":1778822648017,"traceId":"c1985a2799753063"},{"name":"check-page","duration":651343,"timestamp":14675759884,"id":39,"parentId":19,"tags":{"page":"/api/hub/send"},"startTime":1778822648006,"traceId":"c1985a2799753063"},{"name":"is-page-static","duration":640234,"timestamp":14675771124,"id":86,"parentId":48,"tags":{},"startTime":1778822648017,"traceId":"c1985a2799753063"},{"name":"check-page","duration":650792,"timestamp":14675760598,"id":48,"parentId":19,"tags":{"page":"/api/hub/tokens"},"startTime":1778822648007,"traceId":"c1985a2799753063"},{"name":"is-page-static","duration":642766,"timestamp":14675771137,"id":87,"parentId":49,"tags":{},"startTime":1778822648017,"traceId":"c1985a2799753063"},{"name":"check-page","duration":651836,"timestamp":14675762123,"id":49,"parentId":19,"tags":{"page":"/favicon.ico"},"startTime":1778822648008,"traceId":"c1985a2799753063"},{"name":"is-page-static","duration":642455,"timestamp":14675775707,"id":89,"parentId":31,"tags":{},"startTime":1778822648022,"traceId":"c1985a2799753063"},{"name":"check-page","duration":659805,"timestamp":14675758408,"id":31,"parentId":19,"tags":{"page":"/api/hub/events"},"startTime":1778822648005,"traceId":"c1985a2799753063"},{"name":"is-page-static","duration":654150,"timestamp":14675771058,"id":81,"parentId":43,"tags":{},"startTime":1778822648017,"traceId":"c1985a2799753063"},{"name":"check-page","duration":665022,"timestamp":14675760226,"id":43,"parentId":19,"tags":{"page":"/api/hub/stats"},"startTime":1778822648006,"traceId":"c1985a2799753063"},{"name":"is-page-static","duration":650836,"timestamp":14675774538,"id":88,"parentId":24,"tags":{},"startTime":1778822648021,"traceId":"c1985a2799753063"},{"name":"check-page","duration":670502,"timestamp":14675754896,"id":24,"parentId":19,"tags":{"page":"/api/anet/config"},"startTime":1778822648001,"traceId":"c1985a2799753063"},{"name":"is-page-static","duration":654470,"timestamp":14675771027,"id":79,"parentId":41,"tags":{},"startTime":1778822648017,"traceId":"c1985a2799753063"},{"name":"check-page","duration":665479,"timestamp":14675760039,"id":41,"parentId":19,"tags":{"page":"/api/hub/servers"},"startTime":1778822648006,"traceId":"c1985a2799753063"},{"name":"is-page-static","duration":692670,"timestamp":14675783267,"id":90,"parentId":23,"tags":{},"startTime":1778822648030,"traceId":"c1985a2799753063"},{"name":"check-page","duration":721344,"timestamp":14675754697,"id":23,"parentId":19,"tags":{"page":"/admin"},"startTime":1778822648001,"traceId":"c1985a2799753063"},{"name":"is-page-static","duration":709415,"timestamp":14675771082,"id":83,"parentId":45,"tags":{},"startTime":1778822648017,"traceId":"c1985a2799753063"},{"name":"check-page","duration":720341,"timestamp":14675760369,"id":45,"parentId":19,"tags":{"page":"/api/hub/task-events"},"startTime":1778822648007,"traceId":"c1985a2799753063"},{"name":"is-page-static","duration":701448,"timestamp":14675783373,"id":95,"parentId":54,"tags":{},"startTime":1778822648030,"traceId":"c1985a2799753063"},{"name":"check-page","duration":721886,"timestamp":14675762983,"id":54,"parentId":19,"tags":{"page":"/nodes"},"startTime":1778822648009,"traceId":"c1985a2799753063"},{"name":"is-page-static","duration":708391,"timestamp":14675783389,"id":96,"parentId":56,"tags":{},"startTime":1778822648030,"traceId":"c1985a2799753063"},{"name":"check-page","duration":728258,"timestamp":14675763566,"id":56,"parentId":19,"tags":{"page":"/server-logs"},"startTime":1778822648010,"traceId":"c1985a2799753063"},{"name":"is-page-static","duration":708666,"timestamp":14675783304,"id":91,"parentId":50,"tags":{},"startTime":1778822648030,"traceId":"c1985a2799753063"},{"name":"check-page","duration":729568,"timestamp":14675762463,"id":50,"parentId":19,"tags":{"page":"/login"},"startTime":1778822648009,"traceId":"c1985a2799753063"},{"name":"is-page-static","duration":708782,"timestamp":14675783404,"id":97,"parentId":57,"tags":{},"startTime":1778822648030,"traceId":"c1985a2799753063"},{"name":"check-page","duration":728422,"timestamp":14675763794,"id":57,"parentId":19,"tags":{"page":"/settings/networks"},"startTime":1778822648010,"traceId":"c1985a2799753063"},{"name":"is-page-static","duration":713307,"timestamp":14675783342,"id":93,"parentId":52,"tags":{},"startTime":1778822648030,"traceId":"c1985a2799753063"},{"name":"check-page","duration":734011,"timestamp":14675762704,"id":52,"parentId":19,"tags":{"page":"/messages"},"startTime":1778822648009,"traceId":"c1985a2799753063"},{"name":"is-page-static","duration":717239,"timestamp":14675783362,"id":94,"parentId":53,"tags":{},"startTime":1778822648030,"traceId":"c1985a2799753063"},{"name":"check-page","duration":737813,"timestamp":14675762843,"id":53,"parentId":19,"tags":{"page":"/node"},"startTime":1778822648009,"traceId":"c1985a2799753063"},{"name":"is-page-static","duration":717324,"timestamp":14675783416,"id":98,"parentId":59,"tags":{},"startTime":1778822648030,"traceId":"c1985a2799753063"},{"name":"check-page","duration":736311,"timestamp":14675764459,"id":59,"parentId":19,"tags":{"page":"/settings/tokens"},"startTime":1778822648011,"traceId":"c1985a2799753063"},{"name":"is-page-static","duration":717507,"timestamp":14675783326,"id":92,"parentId":51,"tags":{},"startTime":1778822648030,"traceId":"c1985a2799753063"},{"name":"check-page","duration":738276,"timestamp":14675762578,"id":51,"parentId":19,"tags":{"page":"/logs"},"startTime":1778822648009,"traceId":"c1985a2799753063"},{"name":"is-page-static","duration":719117,"timestamp":14675783457,"id":100,"parentId":61,"tags":{},"startTime":1778822648030,"traceId":"c1985a2799753063"},{"name":"check-page","duration":737814,"timestamp":14675764813,"id":61,"parentId":19,"tags":{"page":"/tasks"},"startTime":1778822648011,"traceId":"c1985a2799753063"},{"name":"is-page-static","duration":720666,"timestamp":14675783473,"id":101,"parentId":58,"tags":{},"startTime":1778822648030,"traceId":"c1985a2799753063"},{"name":"check-page","duration":740188,"timestamp":14675763982,"id":58,"parentId":19,"tags":{"page":"/settings"},"startTime":1778822648010,"traceId":"c1985a2799753063"},{"name":"is-page-static","duration":707426,"timestamp":14675799861,"id":102,"parentId":55,"tags":{},"startTime":1778822648046,"traceId":"c1985a2799753063"},{"name":"check-page","duration":744144,"timestamp":14675763169,"id":55,"parentId":19,"tags":{"page":"/"},"startTime":1778822648009,"traceId":"c1985a2799753063"},{"name":"is-page-static","duration":736961,"timestamp":14675770653,"id":71,"parentId":33,"tags":{},"startTime":1778822648017,"traceId":"c1985a2799753063"},{"name":"check-page","duration":748850,"timestamp":14675758784,"id":33,"parentId":19,"tags":{"page":"/api/hub/inbox"},"startTime":1778822648005,"traceId":"c1985a2799753063"},{"name":"is-page-static","duration":725501,"timestamp":14675783436,"id":99,"parentId":60,"tags":{},"startTime":1778822648030,"traceId":"c1985a2799753063"},{"name":"check-page","duration":744330,"timestamp":14675764641,"id":60,"parentId":19,"tags":{"page":"/tasks/[id]"},"startTime":1778822648011,"traceId":"c1985a2799753063"},{"name":"static-check","duration":757736,"timestamp":14675751277,"id":19,"parentId":1,"tags":{},"startTime":1778822647998,"traceId":"c1985a2799753063"},{"name":"write-routes-manifest","duration":431,"timestamp":14676515459,"id":104,"parentId":1,"tags":{},"startTime":1778822648762,"traceId":"c1985a2799753063"},{"name":"load-dotenv","duration":49,"timestamp":14676526346,"id":107,"parentId":106,"tags":{},"startTime":1778822648773,"traceId":"c1985a2799753063"},{"name":"run-export-path-map","duration":600,"timestamp":14676529939,"id":108,"parentId":106,"tags":{},"startTime":1778822648776,"traceId":"c1985a2799753063"},{"name":"next-export","duration":597471,"timestamp":14676525105,"id":106,"parentId":1,"tags":{},"startTime":1778822648771,"traceId":"c1985a2799753063"}]
2
+ [{"name":"move-exported-app-not-found-","duration":1811,"timestamp":14677126365,"id":109,"parentId":105,"tags":{},"startTime":1778822649373,"traceId":"c1985a2799753063"},{"name":"move-exported-app-global-error-","duration":1094,"timestamp":14677128264,"id":110,"parentId":105,"tags":{},"startTime":1778822649375,"traceId":"c1985a2799753063"},{"name":"static-generation","duration":611576,"timestamp":14676519845,"id":105,"parentId":1,"tags":{},"startTime":1778822648766,"traceId":"c1985a2799753063"},{"name":"write-routes-manifest","duration":446,"timestamp":14677131589,"id":111,"parentId":1,"tags":{},"startTime":1778822649378,"traceId":"c1985a2799753063"},{"name":"print-tree-view","duration":3692,"timestamp":14677143233,"id":112,"parentId":1,"tags":{},"startTime":1778822649390,"traceId":"c1985a2799753063"},{"name":"write-route-bundle-stats","duration":13407,"timestamp":14677146963,"id":113,"parentId":1,"tags":{},"startTime":1778822649393,"traceId":"c1985a2799753063"},{"name":"telemetry-flush","duration":28059,"timestamp":14677160402,"id":114,"parentId":1,"tags":{},"startTime":1778822649407,"traceId":"c1985a2799753063"},{"name":"next-build","duration":16489128,"timestamp":14660699368,"id":1,"tags":{"buildMode":"default","version":"16.2.3","bundler":"turbopack","has-custom-webpack-config":"false","use-build-worker":"true"},"startTime":1778822632946,"traceId":"c1985a2799753063"}]
package/.next/trace-build CHANGED
@@ -1 +1 @@
1
- [{"name":"run-turbopack","duration":5226573,"timestamp":13338602363,"id":14,"parentId":1,"tags":{},"startTime":1778821310849,"traceId":"5d9c6e2d2cb0bace"},{"name":"turbopack-build-events","duration":102,"timestamp":13338892687,"id":15,"parentId":1,"tags":{},"startTime":1778821311139,"traceId":"5d9c6e2d2cb0bace"},{"name":"run-typescript","duration":8146172,"timestamp":13343840026,"id":16,"parentId":1,"tags":{},"startTime":1778821316086,"traceId":"5d9c6e2d2cb0bace"},{"name":"static-check","duration":749057,"timestamp":13352160715,"id":19,"parentId":1,"tags":{},"startTime":1778821324407,"traceId":"5d9c6e2d2cb0bace"},{"name":"static-generation","duration":585023,"timestamp":13352920461,"id":105,"parentId":1,"tags":{},"startTime":1778821325167,"traceId":"5d9c6e2d2cb0bace"},{"name":"telemetry-flush","duration":21736,"timestamp":13353540336,"id":114,"parentId":1,"tags":{},"startTime":1778821325787,"traceId":"5d9c6e2d2cb0bace"},{"name":"next-build","duration":15155339,"timestamp":13338406775,"id":1,"tags":{"buildMode":"default","version":"16.2.3","bundler":"turbopack","has-custom-webpack-config":"false","use-build-worker":"true"},"startTime":1778821310653,"traceId":"5d9c6e2d2cb0bace"}]
1
+ [{"name":"run-turbopack","duration":5936003,"timestamp":14660907302,"id":14,"parentId":1,"tags":{},"startTime":1778822633154,"traceId":"c1985a2799753063"},{"name":"turbopack-build-events","duration":114,"timestamp":14661209357,"id":15,"parentId":1,"tags":{},"startTime":1778822633456,"traceId":"c1985a2799753063"},{"name":"run-typescript","duration":8724258,"timestamp":14666853018,"id":16,"parentId":1,"tags":{},"startTime":1778822639099,"traceId":"c1985a2799753063"},{"name":"static-check","duration":757736,"timestamp":14675751277,"id":19,"parentId":1,"tags":{},"startTime":1778822647998,"traceId":"c1985a2799753063"},{"name":"static-generation","duration":611576,"timestamp":14676519845,"id":105,"parentId":1,"tags":{},"startTime":1778822648766,"traceId":"c1985a2799753063"},{"name":"telemetry-flush","duration":28059,"timestamp":14677160402,"id":114,"parentId":1,"tags":{},"startTime":1778822649407,"traceId":"c1985a2799753063"},{"name":"next-build","duration":16489128,"timestamp":14660699368,"id":1,"tags":{"buildMode":"default","version":"16.2.3","bundler":"turbopack","has-custom-webpack-config":"false","use-build-worker":"true"},"startTime":1778822632946,"traceId":"c1985a2799753063"}]
@@ -44,6 +44,22 @@ const SHORTCUTS: { group: string; items: Shortcut[] }[] = [
44
44
  { keys: ['type'], label: 'Filter — searches commands, agents, tasks' },
45
45
  ],
46
46
  },
47
+ // Round 25 / Loop: TopoGraph keys + mouse gestures from rounds 21-23
48
+ // were only surfaced in button titles. Consolidating here gives the
49
+ // Help overlay (the canonical discovery surface) a single place to
50
+ // learn the canvas controls.
51
+ {
52
+ group: 'Topology canvas',
53
+ items: [
54
+ { keys: ['+'], label: 'Zoom in (also =)' },
55
+ { keys: ['−'], label: 'Zoom out' },
56
+ { keys: ['0'], label: 'Reset zoom + pan' },
57
+ { keys: ['⌘', 'wheel'], label: 'Zoom toward cursor (Ctrl on Windows/Linux)' },
58
+ { keys: ['drag'], label: 'Pan the canvas (cursor → grabbing)' },
59
+ { keys: ['dbl-click'], label: 'Reset zoom + pan' },
60
+ { keys: ['click'], label: 'Open chat popover on a node (Esc to close)' },
61
+ ],
62
+ },
47
63
  ];
48
64
 
49
65
  const GO_TARGETS: Record<string, string> = {
@@ -424,12 +424,17 @@ export function TopoGraph({ sessions, sseSessions, renameSignal }: TopoGraphProp
424
424
  // index, so contiguous-in-array becomes contiguous-in-ring, i.e.
425
425
  // each team visually clusters. localeCompare keeps CJK ordering sane.
426
426
  const byAlias = (a: Session, b: Session) => a.alias.localeCompare(b.alias);
427
- // #112 umbrella: ghost age-out — an offline node not seen for over a day
428
- // is almost certainly a deleted node the server `/api/status` still
427
+ // #112 umbrella: ghost age-out — an offline node not seen recently is
428
+ // almost certainly a deleted node the server `/api/status` still
429
429
  // returns (#74 root cause is server-side; this is the dashboard-side
430
430
  // fallback so stale ghosts stop cluttering the topology). A missing
431
431
  // last_seen_at is kept (conservative — could be a legitimately new node).
432
- const GHOST_MS = 24 * 60 * 60 * 1000;
432
+ // Round 27 / P0: the 24h threshold was too lenient — Vincent's preview.29
433
+ // screenshot showed B站马 nodes deleted ~4 h earlier still visible. A
434
+ // healthy agent heartbeats every few seconds; if it's been silent for
435
+ // an hour it's effectively gone. 1 h gives a fresh disconnect time to
436
+ // come back while removing dead nodes well within an operator session.
437
+ const GHOST_MS = 60 * 60 * 1000;
433
438
  const now = Date.now();
434
439
  const isGhost = (s: Session) => {
435
440
  if (s.status !== 'offline' || sseCount(s) || !s.last_seen_at) return false;
@@ -497,11 +502,25 @@ export function TopoGraph({ sessions, sseSessions, renameSignal }: TopoGraphProp
497
502
  // padding always fit and stacked group boxes never touch; past the
498
503
  // floor the grid overflows and zoom/pan handles it.
499
504
  const GROUP_TOP = nodeR + 20;
500
- // Row-height floor = the tightest of: a node + its label below it
501
- // (2·nodeR + ~22), and the label band + min box padding (GROUP_TOP + 12).
502
- // Below this, rows would overlap; past it the grid overflows and
503
- // zoom/pan covers the rest.
504
- const cellH = Math.max(2 * nodeR + 22, GROUP_TOP + 12, Math.min(100, (gy1 - gy0) / totalRows));
505
+ // Round 27 / P0 (Vincent screenshot preview.29): dense plain-text
506
+ // node labels (`pos.y + radius + denseDrop`, with a 3 px containerBg
507
+ // stroke halo for readability) at the BOTTOM row of band N would
508
+ // paint OVER the start of band N+1's group label, creating the
509
+ // "blueleap → eleap", "agent-network-dashboard → t-network / board"
510
+ // visual chopping. Geometry of the collision:
511
+ // dense label visual bottom = node_N.y + radius + denseDrop + halo
512
+ // group label glyph top = boxY + 4 (text y=boxY+14, ~10px ascent)
513
+ // = node_N+1.y - GROUP_TOP + 4
514
+ // node_N+1.y - node_N.y = cellH for consecutive rows, so no-collide:
515
+ // cellH ≥ radius + denseDrop + halo + GROUP_TOP - 4 + buffer
516
+ // With halo=3 buffer=4: cellH ≥ nodeR + denseDrop + GROUP_TOP + 3.
517
+ const denseDrop = nodeScale < 0.8 ? 12 : 14;
518
+ const cellH = Math.max(
519
+ 2 * nodeR + 22, // node + dense label within band
520
+ GROUP_TOP + 12, // group-label band + box padding
521
+ nodeR + denseDrop + GROUP_TOP + 3, // round-27 dense↔group label clearance
522
+ Math.min(100, (gy1 - gy0) / totalRows),
523
+ );
505
524
 
506
525
  // Pass 2 — place each band's members.
507
526
  for (const band of bands) {
@@ -1529,8 +1548,17 @@ export function TopoGraph({ sessions, sseSessions, renameSignal }: TopoGraphProp
1529
1548
  const fullMax = isSmall ? 11 : 12;
1530
1549
  const denseFs = isSmall ? 9 : 10;
1531
1550
  const denseDrop = isSmall ? 12 : 14;
1551
+ // Round 26 / Loop: micro-lift the label group on hover —
1552
+ // 1.5 px upward, 200 ms ease. Pairs with the Round 18
1553
+ // group-box hover-accent treatment to give the same
1554
+ // "this is the focused element" feedback at the per-
1555
+ // node level. CSS transform stacks onto the SVG
1556
+ // positioning transform attribute (SVG 2 cascade);
1557
+ // bbox is unchanged at rest, so the overlap-test gate
1558
+ // continues to see the geometric layout it expects.
1532
1559
  return showFullLabel ? (
1533
- <g transform={`translate(${pos.x}, ${pos.y + radius + dropY})`} style={{ pointerEvents: 'none' }}>
1560
+ <g transform={`translate(${pos.x}, ${pos.y + radius + dropY})`} style={{ pointerEvents: 'none' }}
1561
+ className="transition-transform duration-200 group-hover:-translate-y-[1.5px]">
1534
1562
  <rect x={-cardW / 2} y={cardTopY} width={cardW} height={cardH} rx="6" fill={pal.labelBox.fill} stroke={pal.labelBox.stroke} opacity={isLight ? 1 : 0.94} />
1535
1563
  <text x="0" y="1" textAnchor="middle" fill={status.text} fontSize={aliasFs} fontFamily="monospace" fontWeight="700">
1536
1564
  {truncate(session.alias, fullMax)}
@@ -1549,6 +1577,7 @@ export function TopoGraph({ sessions, sseSessions, renameSignal }: TopoGraphProp
1549
1577
  fontFamily="monospace"
1550
1578
  fontWeight="700"
1551
1579
  opacity={0.9}
1580
+ className="transition-transform duration-200 group-hover:-translate-y-[1.5px]"
1552
1581
  style={{ pointerEvents: 'none', paintOrder: 'stroke' }}
1553
1582
  stroke={pal.containerBg}
1554
1583
  strokeWidth="3"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sleep2agi/agent-network-dashboard",
3
- "version": "0.4.6-preview.32",
3
+ "version": "0.4.6-preview.34",
4
4
  "description": "Agent Network Dashboard — Web UI for managing AI Agent networks",
5
5
  "scripts": {
6
6
  "dev": "next dev",
@@ -0,0 +1,44 @@
1
+ /* Round 25 verification: pressing `?` opens the help overlay, and the
2
+ * new "Topology canvas" section is present with the documented keys. */
3
+ import { chromium } from 'playwright';
4
+ import { readFileSync } from 'node:fs';
5
+
6
+ const TOKEN = JSON.parse(readFileSync('/home/vansin/.anet/config.json', 'utf8')).token;
7
+ const browser = await chromium.launch({ headless: true });
8
+ const ctx = await browser.newContext({ viewport: { width: 1280, height: 900 } });
9
+ await ctx.addCookies([{ name: 'anet_dashboard_session', value: `v3:${TOKEN}`, domain: '127.0.0.1', path: '/' }]);
10
+ await ctx.addInitScript(() => {
11
+ try { sessionStorage.setItem('anet_v3_auth', '1'); } catch {}
12
+ });
13
+ await ctx.route('**/api/hub/status*', (route) => route.fulfill({ json: { sessions: [] } }));
14
+ await ctx.route('**/api/hub/tasks*', (route) => route.fulfill({ json: { tasks: [] } }));
15
+ const page = await ctx.newPage();
16
+ await page.goto('http://127.0.0.1:3000/', { waitUntil: 'domcontentloaded' });
17
+ await page.waitForTimeout(400);
18
+
19
+ await page.keyboard.press('?');
20
+ await page.waitForTimeout(200);
21
+
22
+ // The overlay contains group headings; find the Topology canvas group + its rows.
23
+ const data = await page.evaluate(() => {
24
+ // The group heading is a <div>; its parent wraps heading + the <ul> of items.
25
+ const heading = [...document.querySelectorAll('[role="dialog"] div')].find(el => el.textContent === 'Topology canvas');
26
+ if (!heading) return null;
27
+ return {
28
+ headingPresent: true,
29
+ sectionText: (heading.parentElement?.textContent || '').replace(/\s+/g, ' ').trim(),
30
+ };
31
+ });
32
+
33
+ await browser.close();
34
+ const results = {
35
+ overlayOpened: !!data,
36
+ topologySectionPresent: !!data?.headingPresent,
37
+ hasZoomKeys: !!data && /Zoom in/.test(data.sectionText) && /Zoom out/.test(data.sectionText) && /Reset zoom/.test(data.sectionText),
38
+ hasMouseGestures: !!data && /wheel/.test(data.sectionText) && /Pan the canvas/.test(data.sectionText),
39
+ hasClickHint: !!data && /chat popover/.test(data.sectionText) && /dbl-click/.test(data.sectionText),
40
+ };
41
+ const ok = Object.values(results).every(Boolean);
42
+ console.log(`${ok ? '✅' : '❌'} help overlay topology section:`, JSON.stringify(results));
43
+ if (!ok && data) console.log('section text:', data.sectionText.slice(0, 300));
44
+ process.exit(ok ? 0 : 1);
@@ -0,0 +1,115 @@
1
+ /* Round 26 verification: hovering a node lifts its label group up by
2
+ * 1.5 px (CSS transform stacked on the SVG positioning translate). Both
3
+ * the full-card path (sparse fleet) and the dense plain-text path
4
+ * (large fleet) should respond. */
5
+ import { chromium } from 'playwright';
6
+ import { readFileSync } from 'node:fs';
7
+
8
+ const TOKEN = JSON.parse(readFileSync('/home/vansin/.anet/config.json', 'utf8')).token;
9
+ const browser = await chromium.launch({ headless: true });
10
+
11
+ async function probe(fleetSize) {
12
+ const ctx = await browser.newContext({ viewport: { width: 1280, height: 1600 } });
13
+ await ctx.addCookies([{ name: 'anet_dashboard_session', value: `v3:${TOKEN}`, domain: '127.0.0.1', path: '/' }]);
14
+ await ctx.addInitScript(() => {
15
+ try {
16
+ localStorage.setItem('anet-theme', 'cyber');
17
+ localStorage.setItem('anet-topo-layout', 'grid');
18
+ localStorage.setItem('anet-topo-nodescale', '1');
19
+ sessionStorage.setItem('anet_v3_auth', '1');
20
+ } catch {}
21
+ });
22
+ const fresh = new Date(Date.now() - 60 * 1000).toISOString();
23
+ await ctx.route('**/api/hub/status*', async (route) => {
24
+ const r = await route.fetch();
25
+ const b = await r.json();
26
+ const nid = (b.sessions || [])[0]?.network_id || 'default';
27
+ const sessions = Array.from({ length: fleetSize }, (_, i) => ({
28
+ alias: `lab${i + 1}`, status: 'idle', network_id: nid, project_dir: null,
29
+ created_at: fresh, updated_at: fresh, last_seen_at: fresh,
30
+ }));
31
+ await route.fulfill({ response: r, json: { ...b, sessions } });
32
+ });
33
+ await ctx.route('**/api/hub/tasks*', (route) => route.fulfill({ json: { tasks: [] } }));
34
+ const page = await ctx.newPage();
35
+ await page.goto('http://127.0.0.1:3000/', { waitUntil: 'domcontentloaded' });
36
+ await page.waitForFunction((n) => {
37
+ const svg = document.querySelector('svg[viewBox="0 0 1000 680"]');
38
+ return !!svg && svg.querySelectorAll('g[data-node]').length === n;
39
+ }, fleetSize, { timeout: 30000 }).catch(() => {});
40
+ await page.waitForTimeout(500);
41
+
42
+ // Re-query the label element fresh each sample — React re-renders on
43
+ // hover (hoveredAlias state change) so any element handle captured
44
+ // before the hover would be detached/stale by the time we read its
45
+ // post-hover position.
46
+ const readLabelTop = () => page.evaluate(() => {
47
+ const node = document.querySelector('g[data-node="lab1"]');
48
+ if (!node) return null;
49
+ const full = [...node.querySelectorAll('g')].find(g => /group-hover:-translate-y/.test(g.getAttribute('class') || ''));
50
+ const el = full || [...node.querySelectorAll('text')].find(t => /group-hover:-translate-y/.test(t.getAttribute('class') || ''));
51
+ return el ? el.getBoundingClientRect().top : null;
52
+ });
53
+
54
+ const beforeY = await readLabelTop();
55
+ await page.locator('g[data-node="lab1"]').hover();
56
+ await page.waitForTimeout(300);
57
+ const afterY = await readLabelTop();
58
+
59
+ await ctx.close();
60
+ return { beforeY, afterY };
61
+ }
62
+
63
+ const sparse = await probe(4);
64
+ // Note: in dense mode the same alias's hover triggers `showFullLabel`,
65
+ // which swaps the plain-text element for the full-card <g>. That path
66
+ // switch makes a same-element before/after comparison meaningless.
67
+ // The plain-text element still carries the same hover-lift class, so
68
+ // the lift wiring is verified at the DOM level via the second probe.
69
+ const denseClassPresent = await (async () => {
70
+ const ctx = await browser.newContext({ viewport: { width: 1280, height: 1600 } });
71
+ const TOKEN = JSON.parse(readFileSync('/home/vansin/.anet/config.json', 'utf8')).token;
72
+ await ctx.addCookies([{ name: 'anet_dashboard_session', value: `v3:${TOKEN}`, domain: '127.0.0.1', path: '/' }]);
73
+ await ctx.addInitScript(() => {
74
+ localStorage.setItem('anet-topo-layout', 'grid');
75
+ localStorage.setItem('anet-topo-nodescale', '1');
76
+ sessionStorage.setItem('anet_v3_auth', '1');
77
+ });
78
+ const fresh = new Date(Date.now() - 60 * 1000).toISOString();
79
+ await ctx.route('**/api/hub/status*', async (route) => {
80
+ const r = await route.fetch();
81
+ const b = await r.json();
82
+ const nid = (b.sessions || [])[0]?.network_id || 'default';
83
+ const sessions = Array.from({ length: 28 }, (_, i) => ({
84
+ alias: `lab${i + 1}`, status: 'idle', network_id: nid, project_dir: null,
85
+ created_at: fresh, updated_at: fresh, last_seen_at: fresh,
86
+ }));
87
+ await route.fulfill({ response: r, json: { ...b, sessions } });
88
+ });
89
+ await ctx.route('**/api/hub/tasks*', (route) => route.fulfill({ json: { tasks: [] } }));
90
+ const page = await ctx.newPage();
91
+ await page.goto('http://127.0.0.1:3000/', { waitUntil: 'domcontentloaded' });
92
+ await page.waitForFunction(() => document.querySelectorAll('g[data-node]').length === 28, { timeout: 30000 }).catch(() => {});
93
+ await page.waitForTimeout(500);
94
+ const has = await page.evaluate(() => {
95
+ const node = document.querySelector('g[data-node="lab2"]'); // not the one we'd hover
96
+ if (!node) return false;
97
+ const t = [...node.querySelectorAll('text')].find(x => /group-hover:-translate-y/.test(x.getAttribute('class') || ''));
98
+ return !!t;
99
+ });
100
+ await ctx.close();
101
+ return has;
102
+ })();
103
+
104
+ await browser.close();
105
+
106
+ const lifted = (m) => m.beforeY != null && m.afterY != null && m.beforeY - m.afterY >= 1 && m.beforeY - m.afterY <= 2.5;
107
+
108
+ const results = {
109
+ sparseLabelLifts: lifted(sparse),
110
+ densePlainTextHasLiftClass: denseClassPresent,
111
+ };
112
+ const ok = Object.values(results).every(Boolean);
113
+ console.log(`${ok ? '✅' : '❌'} label hover lift:`, JSON.stringify(results),
114
+ `sparse=Δ${(sparse.beforeY - sparse.afterY)?.toFixed(2)}px`);
115
+ process.exit(ok ? 0 : 1);
@@ -3,7 +3,10 @@
3
3
  * - node ↔ node — status rings don't intersect
4
4
  * - node ↔ panel — no node circle intersects an overlay panel rect
5
5
  * - node ↔ group-label — no group-box label text covers a node
6
- * - group-box ↔ box — no two group boxes overlap */
6
+ * - group-box ↔ box — no two group boxes overlap
7
+ * - label ↔ label — no two text labels overlap (Round 27 — caught
8
+ * the dense-node-label vs group-label collision
9
+ * Vincent reported in preview.29) */
7
10
  import { chromium } from 'playwright';
8
11
  import { readFileSync, mkdirSync } from 'node:fs';
9
12
 
@@ -80,11 +83,24 @@ async function check(layout) {
80
83
  label: { x: bb.x, y: bb.y, w: bb.width, h: bb.height },
81
84
  };
82
85
  });
83
- return { nodes, panels, groups };
86
+ // Round 27 / P0: every visible label bbox (node alias text + group
87
+ // headings) so we can assert label↔label clearance. Skip elements
88
+ // with empty bboxes (e.g., text inside an unrendered <g>).
89
+ const allLabels = [];
90
+ for (const t of svg.querySelectorAll('g[data-node] text, g[data-group] text')) {
91
+ const bb = t.getBBox();
92
+ if (bb.width === 0 || bb.height === 0) continue;
93
+ allLabels.push({
94
+ kind: t.closest('g[data-group]') ? 'group' : 'node',
95
+ owner: (t.closest('g[data-group]')?.getAttribute('data-group')) || (t.closest('g[data-node]')?.getAttribute('data-node')) || '?',
96
+ x: bb.x, y: bb.y, w: bb.width, h: bb.height,
97
+ });
98
+ }
99
+ return { nodes, panels, groups, allLabels };
84
100
  });
85
101
 
86
102
  const TOL = 2; // px slack — touching edges is fine, real overlap is not
87
- let nodeNode = 0, nodePanel = 0, nodeLabel = 0, boxBox = 0;
103
+ let nodeNode = 0, nodePanel = 0, nodeLabel = 0, boxBox = 0, labelLabel = 0;
88
104
 
89
105
  // node ↔ node
90
106
  for (let i = 0; i < data.nodes.length; i++) {
@@ -119,12 +135,23 @@ async function check(layout) {
119
135
  overlaps1D(a.y, a.y + a.h, b.y, b.y + b.h, TOL)) boxBox++;
120
136
  }
121
137
  }
138
+ // label ↔ label (Round 27)
139
+ // Same-node node-labels (e.g. alias + sub-status in the full card) are
140
+ // intentionally close and adjacent — skip pairs that share an owner.
141
+ for (let i = 0; i < data.allLabels.length; i++) {
142
+ for (let j = i + 1; j < data.allLabels.length; j++) {
143
+ const a = data.allLabels[i], b = data.allLabels[j];
144
+ if (a.owner === b.owner) continue;
145
+ if (overlaps1D(a.x, a.x + a.w, b.x, b.x + b.w, TOL) &&
146
+ overlaps1D(a.y, a.y + a.h, b.y, b.y + b.h, TOL)) labelLabel++;
147
+ }
148
+ }
122
149
 
123
150
  await page.screenshot({ path: `/tmp/anet-issue-112/overlap-${layout}.png` });
124
151
  await ctx.close();
125
- const ok = nodeNode === 0 && nodePanel === 0 && nodeLabel === 0 && boxBox === 0;
152
+ const ok = nodeNode === 0 && nodePanel === 0 && nodeLabel === 0 && boxBox === 0 && labelLabel === 0;
126
153
  console.log(`${ok ? '✅' : '❌'} [${layout}] nodes=${data.nodes.length} groups=${data.groups.length} — ` +
127
- `node↔node:${nodeNode} node↔panel:${nodePanel} node↔label:${nodeLabel} box↔box:${boxBox}`);
154
+ `node↔node:${nodeNode} node↔panel:${nodePanel} node↔label:${nodeLabel} box↔box:${boxBox} label↔label:${labelLabel}`);
128
155
  return ok;
129
156
  }
130
157