@sleep2agi/agent-network-dashboard 0.6.3-preview.43 → 0.6.3-preview.44

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 (242) hide show
  1. package/.next/BUILD_COMMIT +1 -0
  2. package/.next/BUILD_ID +1 -1
  3. package/.next/build-manifest.json +3 -3
  4. package/.next/diagnostics/route-bundle-stats.json +78 -78
  5. package/.next/fallback-build-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.js.nft.json +1 -1
  14. package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  15. package/.next/server/app/_not-found.html +2 -2
  16. package/.next/server/app/_not-found.rsc +12 -12
  17. package/.next/server/app/_not-found.segments/_full.segment.rsc +12 -12
  18. package/.next/server/app/_not-found.segments/_head.segment.rsc +4 -4
  19. package/.next/server/app/_not-found.segments/_index.segment.rsc +7 -7
  20. package/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +2 -2
  21. package/.next/server/app/_not-found.segments/_not-found.segment.rsc +3 -3
  22. package/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  23. package/.next/server/app/admin/page.js.nft.json +1 -1
  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 +14 -14
  27. package/.next/server/app/admin.segments/_full.segment.rsc +14 -14
  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 +1 -1
  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/index.html +2 -2
  34. package/.next/server/app/index.rsc +14 -14
  35. package/.next/server/app/index.segments/__PAGE__.segment.rsc +4 -4
  36. package/.next/server/app/index.segments/_full.segment.rsc +14 -14
  37. package/.next/server/app/index.segments/_head.segment.rsc +4 -4
  38. package/.next/server/app/index.segments/_index.segment.rsc +7 -7
  39. package/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  40. package/.next/server/app/login/page.js.nft.json +1 -1
  41. package/.next/server/app/login/page_client-reference-manifest.js +1 -1
  42. package/.next/server/app/login.html +2 -2
  43. package/.next/server/app/login.rsc +14 -14
  44. package/.next/server/app/login.segments/_full.segment.rsc +14 -14
  45. package/.next/server/app/login.segments/_head.segment.rsc +4 -4
  46. package/.next/server/app/login.segments/_index.segment.rsc +7 -7
  47. package/.next/server/app/login.segments/_tree.segment.rsc +1 -1
  48. package/.next/server/app/login.segments/login/__PAGE__.segment.rsc +4 -4
  49. package/.next/server/app/login.segments/login.segment.rsc +3 -3
  50. package/.next/server/app/logs/page.js.nft.json +1 -1
  51. package/.next/server/app/logs/page_client-reference-manifest.js +1 -1
  52. package/.next/server/app/logs.html +2 -2
  53. package/.next/server/app/logs.rsc +14 -14
  54. package/.next/server/app/logs.segments/_full.segment.rsc +14 -14
  55. package/.next/server/app/logs.segments/_head.segment.rsc +4 -4
  56. package/.next/server/app/logs.segments/_index.segment.rsc +7 -7
  57. package/.next/server/app/logs.segments/_tree.segment.rsc +1 -1
  58. package/.next/server/app/logs.segments/logs/__PAGE__.segment.rsc +4 -4
  59. package/.next/server/app/logs.segments/logs.segment.rsc +3 -3
  60. package/.next/server/app/messages/page.js.nft.json +1 -1
  61. package/.next/server/app/messages/page_client-reference-manifest.js +1 -1
  62. package/.next/server/app/messages.html +2 -2
  63. package/.next/server/app/messages.rsc +14 -14
  64. package/.next/server/app/messages.segments/_full.segment.rsc +14 -14
  65. package/.next/server/app/messages.segments/_head.segment.rsc +4 -4
  66. package/.next/server/app/messages.segments/_index.segment.rsc +7 -7
  67. package/.next/server/app/messages.segments/_tree.segment.rsc +1 -1
  68. package/.next/server/app/messages.segments/messages/__PAGE__.segment.rsc +4 -4
  69. package/.next/server/app/messages.segments/messages.segment.rsc +3 -3
  70. package/.next/server/app/node/page.js.nft.json +1 -1
  71. package/.next/server/app/node/page_client-reference-manifest.js +1 -1
  72. package/.next/server/app/node.html +2 -2
  73. package/.next/server/app/node.rsc +14 -14
  74. package/.next/server/app/node.segments/_full.segment.rsc +14 -14
  75. package/.next/server/app/node.segments/_head.segment.rsc +4 -4
  76. package/.next/server/app/node.segments/_index.segment.rsc +7 -7
  77. package/.next/server/app/node.segments/_tree.segment.rsc +1 -1
  78. package/.next/server/app/node.segments/node/__PAGE__.segment.rsc +4 -4
  79. package/.next/server/app/node.segments/node.segment.rsc +3 -3
  80. package/.next/server/app/nodes/page.js.nft.json +1 -1
  81. package/.next/server/app/nodes/page_client-reference-manifest.js +1 -1
  82. package/.next/server/app/nodes.html +2 -2
  83. package/.next/server/app/nodes.rsc +14 -14
  84. package/.next/server/app/nodes.segments/_full.segment.rsc +14 -14
  85. package/.next/server/app/nodes.segments/_head.segment.rsc +4 -4
  86. package/.next/server/app/nodes.segments/_index.segment.rsc +7 -7
  87. package/.next/server/app/nodes.segments/_tree.segment.rsc +1 -1
  88. package/.next/server/app/nodes.segments/nodes/__PAGE__.segment.rsc +4 -4
  89. package/.next/server/app/nodes.segments/nodes.segment.rsc +3 -3
  90. package/.next/server/app/page.js.nft.json +1 -1
  91. package/.next/server/app/page_client-reference-manifest.js +1 -1
  92. package/.next/server/app/providers/page.js.nft.json +1 -1
  93. package/.next/server/app/providers/page_client-reference-manifest.js +1 -1
  94. package/.next/server/app/providers.html +2 -2
  95. package/.next/server/app/providers.rsc +14 -14
  96. package/.next/server/app/providers.segments/_full.segment.rsc +14 -14
  97. package/.next/server/app/providers.segments/_head.segment.rsc +4 -4
  98. package/.next/server/app/providers.segments/_index.segment.rsc +7 -7
  99. package/.next/server/app/providers.segments/_tree.segment.rsc +1 -1
  100. package/.next/server/app/providers.segments/providers/__PAGE__.segment.rsc +4 -4
  101. package/.next/server/app/providers.segments/providers.segment.rsc +3 -3
  102. package/.next/server/app/server-logs/page.js.nft.json +1 -1
  103. package/.next/server/app/server-logs/page_client-reference-manifest.js +1 -1
  104. package/.next/server/app/server-logs.html +2 -2
  105. package/.next/server/app/server-logs.rsc +14 -14
  106. package/.next/server/app/server-logs.segments/_full.segment.rsc +14 -14
  107. package/.next/server/app/server-logs.segments/_head.segment.rsc +4 -4
  108. package/.next/server/app/server-logs.segments/_index.segment.rsc +7 -7
  109. package/.next/server/app/server-logs.segments/_tree.segment.rsc +1 -1
  110. package/.next/server/app/server-logs.segments/server-logs/__PAGE__.segment.rsc +4 -4
  111. package/.next/server/app/server-logs.segments/server-logs.segment.rsc +3 -3
  112. package/.next/server/app/servers/page.js.nft.json +1 -1
  113. package/.next/server/app/servers/page_client-reference-manifest.js +1 -1
  114. package/.next/server/app/servers.html +2 -2
  115. package/.next/server/app/servers.rsc +14 -14
  116. package/.next/server/app/servers.segments/_full.segment.rsc +14 -14
  117. package/.next/server/app/servers.segments/_head.segment.rsc +4 -4
  118. package/.next/server/app/servers.segments/_index.segment.rsc +7 -7
  119. package/.next/server/app/servers.segments/_tree.segment.rsc +1 -1
  120. package/.next/server/app/servers.segments/servers/__PAGE__.segment.rsc +4 -4
  121. package/.next/server/app/servers.segments/servers.segment.rsc +3 -3
  122. package/.next/server/app/settings/networks/page.js.nft.json +1 -1
  123. package/.next/server/app/settings/networks/page_client-reference-manifest.js +1 -1
  124. package/.next/server/app/settings/networks.html +2 -2
  125. package/.next/server/app/settings/networks.rsc +14 -14
  126. package/.next/server/app/settings/networks.segments/_full.segment.rsc +14 -14
  127. package/.next/server/app/settings/networks.segments/_head.segment.rsc +4 -4
  128. package/.next/server/app/settings/networks.segments/_index.segment.rsc +7 -7
  129. package/.next/server/app/settings/networks.segments/_tree.segment.rsc +1 -1
  130. package/.next/server/app/settings/networks.segments/settings/networks/__PAGE__.segment.rsc +4 -4
  131. package/.next/server/app/settings/networks.segments/settings/networks.segment.rsc +3 -3
  132. package/.next/server/app/settings/networks.segments/settings.segment.rsc +3 -3
  133. package/.next/server/app/settings/page.js.nft.json +1 -1
  134. package/.next/server/app/settings/page_client-reference-manifest.js +1 -1
  135. package/.next/server/app/settings/tokens/page.js.nft.json +1 -1
  136. package/.next/server/app/settings/tokens/page_client-reference-manifest.js +1 -1
  137. package/.next/server/app/settings/tokens.html +2 -2
  138. package/.next/server/app/settings/tokens.rsc +14 -14
  139. package/.next/server/app/settings/tokens.segments/_full.segment.rsc +14 -14
  140. package/.next/server/app/settings/tokens.segments/_head.segment.rsc +4 -4
  141. package/.next/server/app/settings/tokens.segments/_index.segment.rsc +7 -7
  142. package/.next/server/app/settings/tokens.segments/_tree.segment.rsc +1 -1
  143. package/.next/server/app/settings/tokens.segments/settings/tokens/__PAGE__.segment.rsc +4 -4
  144. package/.next/server/app/settings/tokens.segments/settings/tokens.segment.rsc +3 -3
  145. package/.next/server/app/settings/tokens.segments/settings.segment.rsc +3 -3
  146. package/.next/server/app/settings.html +2 -2
  147. package/.next/server/app/settings.rsc +14 -14
  148. package/.next/server/app/settings.segments/_full.segment.rsc +14 -14
  149. package/.next/server/app/settings.segments/_head.segment.rsc +4 -4
  150. package/.next/server/app/settings.segments/_index.segment.rsc +7 -7
  151. package/.next/server/app/settings.segments/_tree.segment.rsc +1 -1
  152. package/.next/server/app/settings.segments/settings/__PAGE__.segment.rsc +4 -4
  153. package/.next/server/app/settings.segments/settings.segment.rsc +3 -3
  154. package/.next/server/app/tasks/[id]/page.js.nft.json +1 -1
  155. package/.next/server/app/tasks/[id]/page_client-reference-manifest.js +1 -1
  156. package/.next/server/app/tasks/page.js.nft.json +1 -1
  157. package/.next/server/app/tasks/page_client-reference-manifest.js +1 -1
  158. package/.next/server/app/tasks.html +2 -2
  159. package/.next/server/app/tasks.rsc +14 -14
  160. package/.next/server/app/tasks.segments/_full.segment.rsc +14 -14
  161. package/.next/server/app/tasks.segments/_head.segment.rsc +4 -4
  162. package/.next/server/app/tasks.segments/_index.segment.rsc +7 -7
  163. package/.next/server/app/tasks.segments/_tree.segment.rsc +1 -1
  164. package/.next/server/app/tasks.segments/tasks/__PAGE__.segment.rsc +4 -4
  165. package/.next/server/app/tasks.segments/tasks.segment.rsc +3 -3
  166. package/.next/server/chunks/ssr/[root-of-the-server]__0jns048._.js +3 -0
  167. package/.next/server/chunks/ssr/[root-of-the-server]__0jns048._.js.map +1 -0
  168. package/.next/server/chunks/ssr/[root-of-the-server]__0va6h-y._.js +3 -3
  169. package/.next/server/chunks/ssr/[root-of-the-server]__0va6h-y._.js.map +1 -1
  170. package/.next/server/chunks/ssr/{[root-of-the-server]__056tw5g._.js → [root-of-the-server]__0z0lvdf._.js} +2 -2
  171. package/.next/server/chunks/ssr/[root-of-the-server]__0z0lvdf._.js.map +1 -0
  172. package/.next/server/chunks/ssr/[root-of-the-server]__13svd64._.js +3 -0
  173. package/.next/server/chunks/ssr/[root-of-the-server]__13svd64._.js.map +1 -0
  174. package/.next/server/chunks/ssr/dash-492_agent-network-dashboard_0f4savf._.js +3 -3
  175. package/.next/server/chunks/ssr/dash-492_agent-network-dashboard_0f4savf._.js.map +1 -1
  176. package/.next/server/chunks/ssr/{dash-492_agent-network-dashboard_app_12yiaen._.js → dash-492_agent-network-dashboard_app_07foku.._.js} +2 -2
  177. package/.next/server/chunks/ssr/dash-492_agent-network-dashboard_app_07foku.._.js.map +1 -0
  178. package/.next/server/chunks/ssr/dash-492_agent-network-dashboard_app_0fv9~x1._.js +1 -1
  179. package/.next/server/chunks/ssr/dash-492_agent-network-dashboard_app_0fv9~x1._.js.map +1 -1
  180. package/.next/server/chunks/ssr/dash-492_agent-network-dashboard_app_0jey2is._.js +3 -0
  181. package/.next/server/chunks/ssr/dash-492_agent-network-dashboard_app_0jey2is._.js.map +1 -0
  182. package/.next/server/chunks/ssr/dash-492_agent-network-dashboard_app_0tbukk6._.js +3 -0
  183. package/.next/server/chunks/ssr/dash-492_agent-network-dashboard_app_0tbukk6._.js.map +1 -0
  184. package/.next/server/chunks/ssr/dash-492_agent-network-dashboard_app_10nv4wt._.js +3 -0
  185. package/.next/server/chunks/ssr/{dash-492_agent-network-dashboard_app_02~ml1y._.js.map → dash-492_agent-network-dashboard_app_10nv4wt._.js.map} +1 -1
  186. package/.next/server/chunks/ssr/dash-492_agent-network-dashboard_app_components_07gcm8v._.js +3 -3
  187. package/.next/server/chunks/ssr/dash-492_agent-network-dashboard_app_components_07gcm8v._.js.map +1 -1
  188. package/.next/server/middleware-build-manifest.js +3 -3
  189. package/.next/server/pages/404.html +2 -2
  190. package/.next/server/pages/500.html +1 -1
  191. package/.next/static/chunks/0.t9q6b8-tp7o.js +1 -0
  192. package/.next/static/chunks/03kazq4f2o8kc.js +1 -0
  193. package/.next/static/chunks/0adq.v18n1i97.js +7 -0
  194. package/.next/static/chunks/{07hmiozabjis~.js → 0b3jrmai2phnc.js} +1 -1
  195. package/.next/static/chunks/0casvy.vqveum.js +7 -0
  196. package/.next/static/chunks/0e3gktr80d3im.js +2 -0
  197. package/.next/static/chunks/0jgo1j.i.wd5q.js +7 -0
  198. package/.next/static/chunks/0mqxob_pphde0.js +1 -0
  199. package/.next/static/chunks/0uj3h67aerffm.js +1 -0
  200. package/.next/static/chunks/0ws5f9sp.pgiv.js +1 -0
  201. package/.next/static/chunks/16._eot2r-z1r.js +1 -0
  202. package/.next/static/chunks/17bch5v2vnph5.js +4 -0
  203. package/.next/trace +2 -2
  204. package/.next/trace-build +1 -1
  205. package/app/components/ChatPopover.tsx +9 -2
  206. package/app/components/Sidebar.tsx +14 -1
  207. package/app/components/TaskChatPanel.tsx +11 -3
  208. package/app/components/TopoGraph.tsx +25 -11
  209. package/app/lib/presence.ts +43 -0
  210. package/app/page.tsx +7 -11
  211. package/package.json +1 -1
  212. package/tests/e2e-515-presence-predicate.spec.ts +75 -0
  213. package/tests/e2e-515-presence.spec.ts +148 -0
  214. package/.next/server/chunks/ssr/[root-of-the-server]__056tw5g._.js.map +0 -1
  215. package/.next/server/chunks/ssr/[root-of-the-server]__06g2-qq._.js +0 -3
  216. package/.next/server/chunks/ssr/[root-of-the-server]__06g2-qq._.js.map +0 -1
  217. package/.next/server/chunks/ssr/[root-of-the-server]__0qv41lg._.js +0 -3
  218. package/.next/server/chunks/ssr/[root-of-the-server]__0qv41lg._.js.map +0 -1
  219. package/.next/server/chunks/ssr/dash-492_agent-network-dashboard_app_02~ml1y._.js +0 -3
  220. package/.next/server/chunks/ssr/dash-492_agent-network-dashboard_app_04nejob._.js +0 -3
  221. package/.next/server/chunks/ssr/dash-492_agent-network-dashboard_app_04nejob._.js.map +0 -1
  222. package/.next/server/chunks/ssr/dash-492_agent-network-dashboard_app_0kehfih._.js +0 -3
  223. package/.next/server/chunks/ssr/dash-492_agent-network-dashboard_app_0kehfih._.js.map +0 -1
  224. package/.next/server/chunks/ssr/dash-492_agent-network-dashboard_app_0vvr81v._.js +0 -3
  225. package/.next/server/chunks/ssr/dash-492_agent-network-dashboard_app_0vvr81v._.js.map +0 -1
  226. package/.next/server/chunks/ssr/dash-492_agent-network-dashboard_app_0~9qq2o._.js +0 -3
  227. package/.next/server/chunks/ssr/dash-492_agent-network-dashboard_app_0~9qq2o._.js.map +0 -1
  228. package/.next/server/chunks/ssr/dash-492_agent-network-dashboard_app_12yiaen._.js.map +0 -1
  229. package/.next/static/chunks/00kg.oomong9m.js +0 -1
  230. package/.next/static/chunks/02a6-zbyr.zoy.js +0 -2
  231. package/.next/static/chunks/06ww0tn_jfcfd.js +0 -1
  232. package/.next/static/chunks/0_90al8hntttb.js +0 -1
  233. package/.next/static/chunks/0idb.71vziyhz.js +0 -7
  234. package/.next/static/chunks/0qw7i_y5i75.q.js +0 -1
  235. package/.next/static/chunks/0szzm0ma-335n.js +0 -4
  236. package/.next/static/chunks/0xxfl.bqy.bd4.js +0 -7
  237. package/.next/static/chunks/0yscbgm2a_d1u.js +0 -1
  238. package/.next/static/chunks/0zj956.f-k1jj.js +0 -7
  239. package/.next/static/chunks/17ns4oqzib99e.js +0 -1
  240. /package/.next/static/{BXw6vds1QR_zb-M-KgpT7 → VeCvA8ZJHnHbQwP2X4xfs}/_buildManifest.js +0 -0
  241. /package/.next/static/{BXw6vds1QR_zb-M-KgpT7 → VeCvA8ZJHnHbQwP2X4xfs}/_clientMiddlewareManifest.js +0 -0
  242. /package/.next/static/{BXw6vds1QR_zb-M-KgpT7 → VeCvA8ZJHnHbQwP2X4xfs}/_ssgManifest.js +0 -0
package/.next/trace CHANGED
@@ -1,2 +1,2 @@
1
- [{"name":"generate-buildid","duration":304,"timestamp":6581987041743,"id":4,"parentId":1,"tags":{},"startTime":1785389959288,"traceId":"456f595ad3c40dfa"},{"name":"load-custom-routes","duration":474,"timestamp":6581987042201,"id":5,"parentId":1,"tags":{},"startTime":1785389959288,"traceId":"456f595ad3c40dfa"},{"name":"create-dist-dir","duration":816,"timestamp":6581987042719,"id":6,"parentId":1,"tags":{},"startTime":1785389959289,"traceId":"456f595ad3c40dfa"},{"name":"clean","duration":52139,"timestamp":6581987044558,"id":7,"parentId":1,"tags":{},"startTime":1785389959291,"traceId":"456f595ad3c40dfa"},{"name":"discover-routes","duration":15160,"timestamp":6581987209150,"id":8,"parentId":1,"tags":{},"startTime":1785389959455,"traceId":"456f595ad3c40dfa"},{"name":"create-root-mapping","duration":148,"timestamp":6581987224396,"id":9,"parentId":1,"tags":{},"startTime":1785389959471,"traceId":"456f595ad3c40dfa"},{"name":"generate-route-types","duration":52810,"timestamp":6581987228252,"id":10,"parentId":1,"tags":{},"startTime":1785389959475,"traceId":"456f595ad3c40dfa"},{"name":"public-dir-conflict-check","duration":105,"timestamp":6581987281249,"id":11,"parentId":1,"tags":{},"startTime":1785389959528,"traceId":"456f595ad3c40dfa"},{"name":"generate-routes-manifest","duration":5568,"timestamp":6581987281474,"id":12,"parentId":1,"tags":{},"startTime":1785389959528,"traceId":"456f595ad3c40dfa"},{"name":"run-turbopack","duration":9375161,"timestamp":6581987303276,"id":14,"parentId":1,"tags":{},"startTime":1785389959550,"traceId":"456f595ad3c40dfa"},{"name":"turbopack-build-events","duration":98,"timestamp":6581987666324,"id":15,"parentId":1,"tags":{},"startTime":1785389959913,"traceId":"456f595ad3c40dfa"},{"name":"run-typescript","duration":15277045,"timestamp":6581996690196,"id":16,"parentId":1,"tags":{},"startTime":1785389968936,"traceId":"456f595ad3c40dfa"},{"name":"generate-required-server-files","duration":3130,"timestamp":6582011969279,"id":18,"parentId":1,"tags":{},"startTime":1785389984216,"traceId":"456f595ad3c40dfa"},{"name":"check-static-error-page","duration":27412,"timestamp":6582012390870,"id":20,"parentId":19,"tags":{},"startTime":1785389984637,"traceId":"456f595ad3c40dfa"},{"name":"is-page-static","duration":709264,"timestamp":6582012422089,"id":82,"parentId":34,"tags":{},"startTime":1785389984668,"traceId":"456f595ad3c40dfa"},{"name":"check-page","duration":729400,"timestamp":6582012402118,"id":34,"parentId":19,"tags":{"page":"/api/auth/v3"},"startTime":1785389984648,"traceId":"456f595ad3c40dfa"},{"name":"is-page-static","duration":713927,"timestamp":6582012423506,"id":83,"parentId":35,"tags":{},"startTime":1785389984670,"traceId":"456f595ad3c40dfa"},{"name":"check-page","duration":735248,"timestamp":6582012402264,"id":35,"parentId":19,"tags":{"page":"/api/hub/audit-log"},"startTime":1785389984649,"traceId":"456f595ad3c40dfa"},{"name":"is-page-static","duration":761796,"timestamp":6582012423586,"id":84,"parentId":36,"tags":{},"startTime":1785389984670,"traceId":"456f595ad3c40dfa"},{"name":"check-page","duration":782599,"timestamp":6582012402863,"id":36,"parentId":19,"tags":{"page":"/api/hub/auth"},"startTime":1785389984649,"traceId":"456f595ad3c40dfa"},{"name":"is-page-static","duration":833303,"timestamp":6582012423811,"id":85,"parentId":37,"tags":{},"startTime":1785389984670,"traceId":"456f595ad3c40dfa"},{"name":"check-page","duration":854075,"timestamp":6582012403123,"id":37,"parentId":19,"tags":{"page":"/api/hub/broadcast"},"startTime":1785389984649,"traceId":"456f595ad3c40dfa"},{"name":"is-page-static","duration":845081,"timestamp":6582012423900,"id":86,"parentId":40,"tags":{},"startTime":1785389984670,"traceId":"456f595ad3c40dfa"},{"name":"check-page","duration":861226,"timestamp":6582012407871,"id":40,"parentId":19,"tags":{"page":"/api/hub/health"},"startTime":1785389984654,"traceId":"456f595ad3c40dfa"},{"name":"is-page-static","duration":853172,"timestamp":6582012423931,"id":87,"parentId":41,"tags":{},"startTime":1785389984670,"traceId":"456f595ad3c40dfa"},{"name":"check-page","duration":869146,"timestamp":6582012408044,"id":41,"parentId":19,"tags":{"page":"/api/hub/inbox"},"startTime":1785389984654,"traceId":"456f595ad3c40dfa"},{"name":"is-page-static","duration":855197,"timestamp":6582012423959,"id":88,"parentId":42,"tags":{},"startTime":1785389984670,"traceId":"456f595ad3c40dfa"},{"name":"check-page","duration":871010,"timestamp":6582012408215,"id":42,"parentId":19,"tags":{"page":"/api/hub/messages"},"startTime":1785389984654,"traceId":"456f595ad3c40dfa"},{"name":"is-page-static","duration":862455,"timestamp":6582012421411,"id":78,"parentId":29,"tags":{},"startTime":1785389984668,"traceId":"456f595ad3c40dfa"},{"name":"check-page","duration":883026,"timestamp":6582012400966,"id":29,"parentId":19,"tags":{"page":"/api/anet/providers/probe-results"},"startTime":1785389984647,"traceId":"456f595ad3c40dfa"},{"name":"is-page-static","duration":870556,"timestamp":6582012424028,"id":90,"parentId":45,"tags":{},"startTime":1785389984670,"traceId":"456f595ad3c40dfa"},{"name":"check-page","duration":885779,"timestamp":6582012408894,"id":45,"parentId":19,"tags":{"page":"/api/hub/nodes"},"startTime":1785389984655,"traceId":"456f595ad3c40dfa"},{"name":"is-page-static","duration":870904,"timestamp":6582012423990,"id":89,"parentId":43,"tags":{},"startTime":1785389984670,"traceId":"456f595ad3c40dfa"},{"name":"check-page","duration":886611,"timestamp":6582012408317,"id":43,"parentId":19,"tags":{"page":"/api/hub/networks"},"startTime":1785389984655,"traceId":"456f595ad3c40dfa"},{"name":"is-page-static","duration":885926,"timestamp":6582012424054,"id":92,"parentId":47,"tags":{},"startTime":1785389984670,"traceId":"456f595ad3c40dfa"},{"name":"check-page","duration":900907,"timestamp":6582012409169,"id":47,"parentId":19,"tags":{"page":"/api/hub/send"},"startTime":1785389984655,"traceId":"456f595ad3c40dfa"},{"name":"is-page-static","duration":892551,"timestamp":6582012420756,"id":76,"parentId":21,"tags":{},"startTime":1785389984667,"traceId":"456f595ad3c40dfa"},{"name":"check-page","duration":921270,"timestamp":6582012392096,"id":21,"parentId":19,"tags":{"page":"/_not-found"},"startTime":1785389984638,"traceId":"456f595ad3c40dfa"},{"name":"is-page-static","duration":891479,"timestamp":6582012424067,"id":93,"parentId":48,"tags":{},"startTime":1785389984670,"traceId":"456f595ad3c40dfa"},{"name":"check-page","duration":906325,"timestamp":6582012409278,"id":48,"parentId":19,"tags":{"page":"/api/hub/server-logs"},"startTime":1785389984656,"traceId":"456f595ad3c40dfa"},{"name":"is-page-static","duration":902247,"timestamp":6582012424090,"id":95,"parentId":52,"tags":{},"startTime":1785389984670,"traceId":"456f595ad3c40dfa"},{"name":"check-page","duration":916382,"timestamp":6582012410038,"id":52,"parentId":19,"tags":{"page":"/api/hub/session"},"startTime":1785389984656,"traceId":"456f595ad3c40dfa"},{"name":"is-page-static","duration":908489,"timestamp":6582012424103,"id":96,"parentId":53,"tags":{},"startTime":1785389984670,"traceId":"456f595ad3c40dfa"},{"name":"check-page","duration":922674,"timestamp":6582012410169,"id":53,"parentId":19,"tags":{"page":"/api/hub/stats"},"startTime":1785389984656,"traceId":"456f595ad3c40dfa"},{"name":"is-page-static","duration":915209,"timestamp":6582012424039,"id":91,"parentId":46,"tags":{},"startTime":1785389984670,"traceId":"456f595ad3c40dfa"},{"name":"check-page","duration":930254,"timestamp":6582012409055,"id":46,"parentId":19,"tags":{"page":"/api/hub/register"},"startTime":1785389984655,"traceId":"456f595ad3c40dfa"},{"name":"is-page-static","duration":922275,"timestamp":6582012424126,"id":98,"parentId":55,"tags":{},"startTime":1785389984670,"traceId":"456f595ad3c40dfa"},{"name":"check-page","duration":936112,"timestamp":6582012410370,"id":55,"parentId":19,"tags":{"page":"/api/hub/task-events"},"startTime":1785389984657,"traceId":"456f595ad3c40dfa"},{"name":"is-page-static","duration":924266,"timestamp":6582012424113,"id":97,"parentId":54,"tags":{},"startTime":1785389984670,"traceId":"456f595ad3c40dfa"},{"name":"check-page","duration":938152,"timestamp":6582012410272,"id":54,"parentId":19,"tags":{"page":"/api/hub/status"},"startTime":1785389984657,"traceId":"456f595ad3c40dfa"},{"name":"is-page-static","duration":927372,"timestamp":6582012424139,"id":99,"parentId":56,"tags":{},"startTime":1785389984670,"traceId":"456f595ad3c40dfa"},{"name":"check-page","duration":941097,"timestamp":6582012410461,"id":56,"parentId":19,"tags":{"page":"/api/hub/tasks"},"startTime":1785389984657,"traceId":"456f595ad3c40dfa"},{"name":"is-page-static","duration":939916,"timestamp":6582012424151,"id":100,"parentId":57,"tags":{},"startTime":1785389984670,"traceId":"456f595ad3c40dfa"},{"name":"check-page","duration":953576,"timestamp":6582012410576,"id":57,"parentId":19,"tags":{"page":"/api/hub/tmux"},"startTime":1785389984657,"traceId":"456f595ad3c40dfa"},{"name":"is-page-static","duration":940259,"timestamp":6582012424176,"id":102,"parentId":60,"tags":{},"startTime":1785389984670,"traceId":"456f595ad3c40dfa"},{"name":"check-page","duration":953371,"timestamp":6582012411122,"id":60,"parentId":19,"tags":{"page":"/favicon.ico"},"startTime":1785389984657,"traceId":"456f595ad3c40dfa"},{"name":"is-page-static","duration":940502,"timestamp":6582012424160,"id":101,"parentId":58,"tags":{},"startTime":1785389984670,"traceId":"456f595ad3c40dfa"},{"name":"check-page","duration":954026,"timestamp":6582012410671,"id":58,"parentId":19,"tags":{"page":"/api/hub/tokens"},"startTime":1785389984657,"traceId":"456f595ad3c40dfa"},{"name":"is-page-static","duration":953296,"timestamp":6582012421633,"id":80,"parentId":32,"tags":{},"startTime":1785389984668,"traceId":"456f595ad3c40dfa"},{"name":"check-page","duration":973182,"timestamp":6582012401807,"id":32,"parentId":19,"tags":{"page":"/api/auth/login"},"startTime":1785389984648,"traceId":"456f595ad3c40dfa"},{"name":"is-page-static","duration":953936,"timestamp":6582012421260,"id":77,"parentId":22,"tags":{},"startTime":1785389984668,"traceId":"456f595ad3c40dfa"},{"name":"check-page","duration":981844,"timestamp":6582012393388,"id":22,"parentId":19,"tags":{"page":"/_global-error"},"startTime":1785389984640,"traceId":"456f595ad3c40dfa"},{"name":"is-page-static","duration":959014,"timestamp":6582012424189,"id":103,"parentId":63,"tags":{},"startTime":1785389984670,"traceId":"456f595ad3c40dfa"},{"name":"check-page","duration":971358,"timestamp":6582012411907,"id":63,"parentId":19,"tags":{"page":"/manifest.webmanifest"},"startTime":1785389984658,"traceId":"456f595ad3c40dfa"},{"name":"is-page-static","duration":902400,"timestamp":6582012483364,"id":107,"parentId":26,"tags":{},"startTime":1785389984730,"traceId":"456f595ad3c40dfa"},{"name":"check-page","duration":986125,"timestamp":6582012399701,"id":26,"parentId":19,"tags":{"page":"/api/anet/node-config"},"startTime":1785389984646,"traceId":"456f595ad3c40dfa"},{"name":"is-page-static","duration":942709,"timestamp":6582012443287,"id":104,"parentId":24,"tags":{},"startTime":1785389984690,"traceId":"456f595ad3c40dfa"},{"name":"check-page","duration":992023,"timestamp":6582012394019,"id":24,"parentId":19,"tags":{"page":"/api/anet/config"},"startTime":1785389984640,"traceId":"456f595ad3c40dfa"},{"name":"is-page-static","duration":882817,"timestamp":6582012508941,"id":108,"parentId":31,"tags":{},"startTime":1785389984755,"traceId":"456f595ad3c40dfa"},{"name":"check-page","duration":990444,"timestamp":6582012401376,"id":31,"parentId":19,"tags":{"page":"/api/anet/providers"},"startTime":1785389984648,"traceId":"456f595ad3c40dfa"},{"name":"is-page-static","duration":880841,"timestamp":6582012515702,"id":110,"parentId":27,"tags":{},"startTime":1785389984762,"traceId":"456f595ad3c40dfa"},{"name":"check-page","duration":996444,"timestamp":6582012400160,"id":27,"parentId":19,"tags":{"page":"/api/anet/node-create"},"startTime":1785389984646,"traceId":"456f595ad3c40dfa"},{"name":"is-page-static","duration":884751,"timestamp":6582012512483,"id":109,"parentId":38,"tags":{},"startTime":1785389984759,"traceId":"456f595ad3c40dfa"},{"name":"check-page","duration":993783,"timestamp":6582012403506,"id":38,"parentId":19,"tags":{"page":"/api/hub/events"},"startTime":1785389984650,"traceId":"456f595ad3c40dfa"},{"name":"is-page-static","duration":873931,"timestamp":6582012533471,"id":111,"parentId":39,"tags":{},"startTime":1785389984780,"traceId":"456f595ad3c40dfa"},{"name":"check-page","duration":1003586,"timestamp":6582012403890,"id":39,"parentId":19,"tags":{"page":"/api/hub/files/[fileId]"},"startTime":1785389984650,"traceId":"456f595ad3c40dfa"},{"name":"is-page-static","duration":863923,"timestamp":6582012552037,"id":113,"parentId":49,"tags":{},"startTime":1785389984798,"traceId":"456f595ad3c40dfa"},{"name":"check-page","duration":1006688,"timestamp":6582012409372,"id":49,"parentId":19,"tags":{"page":"/api/hub/server/[hostname]/agents"},"startTime":1785389984656,"traceId":"456f595ad3c40dfa"},{"name":"is-page-static","duration":841465,"timestamp":6582012576343,"id":114,"parentId":51,"tags":{},"startTime":1785389984823,"traceId":"456f595ad3c40dfa"},{"name":"check-page","duration":1008137,"timestamp":6582012409753,"id":51,"parentId":19,"tags":{"page":"/api/hub/servers"},"startTime":1785389984656,"traceId":"456f595ad3c40dfa"},{"name":"is-page-static","duration":976432,"timestamp":6582012444850,"id":105,"parentId":25,"tags":{},"startTime":1785389984691,"traceId":"456f595ad3c40dfa"},{"name":"check-page","duration":1022813,"timestamp":6582012398528,"id":25,"parentId":19,"tags":{"page":"/api/anet/host-supervisors"},"startTime":1785389984645,"traceId":"456f595ad3c40dfa"},{"name":"is-page-static","duration":842953,"timestamp":6582012580156,"id":115,"parentId":59,"tags":{},"startTime":1785389984826,"traceId":"456f595ad3c40dfa"},{"name":"check-page","duration":1012407,"timestamp":6582012410759,"id":59,"parentId":19,"tags":{"page":"/api/hub/upload"},"startTime":1785389984657,"traceId":"456f595ad3c40dfa"},{"name":"is-page-static","duration":903430,"timestamp":6582012549123,"id":112,"parentId":44,"tags":{},"startTime":1785389984795,"traceId":"456f595ad3c40dfa"},{"name":"check-page","duration":1044223,"timestamp":6582012408407,"id":44,"parentId":19,"tags":{"page":"/api/hub/nodes/[ref]/attrs"},"startTime":1785389984655,"traceId":"456f595ad3c40dfa"},{"name":"is-page-static","duration":1028769,"timestamp":6582012424076,"id":94,"parentId":50,"tags":{},"startTime":1785389984670,"traceId":"456f595ad3c40dfa"},{"name":"check-page","duration":1043278,"timestamp":6582012409612,"id":50,"parentId":19,"tags":{"page":"/api/hub/server/[hostname]/health"},"startTime":1785389984656,"traceId":"456f595ad3c40dfa"},{"name":"is-page-static","duration":1031525,"timestamp":6582012421533,"id":79,"parentId":30,"tags":{},"startTime":1785389984668,"traceId":"456f595ad3c40dfa"},{"name":"check-page","duration":1051905,"timestamp":6582012401194,"id":30,"parentId":19,"tags":{"page":"/api/anet/providers/probe"},"startTime":1785389984647,"traceId":"456f595ad3c40dfa"},{"name":"is-page-static","duration":865202,"timestamp":6582012600098,"id":119,"parentId":65,"tags":{},"startTime":1785389984846,"traceId":"456f595ad3c40dfa"},{"name":"check-page","duration":1052134,"timestamp":6582012413251,"id":65,"parentId":19,"tags":{"page":"/node"},"startTime":1785389984660,"traceId":"456f595ad3c40dfa"},{"name":"is-page-static","duration":871823,"timestamp":6582012600119,"id":121,"parentId":68,"tags":{},"startTime":1785389984846,"traceId":"456f595ad3c40dfa"},{"name":"check-page","duration":1056212,"timestamp":6582012415813,"id":68,"parentId":19,"tags":{"page":"/providers"},"startTime":1785389984662,"traceId":"456f595ad3c40dfa"},{"name":"is-page-static","duration":884984,"timestamp":6582012600128,"id":122,"parentId":69,"tags":{},"startTime":1785389984846,"traceId":"456f595ad3c40dfa"},{"name":"check-page","duration":1069193,"timestamp":6582012415999,"id":69,"parentId":19,"tags":{"page":"/server-logs"},"startTime":1785389984662,"traceId":"456f595ad3c40dfa"},{"name":"is-page-static","duration":886786,"timestamp":6582012600075,"id":117,"parentId":61,"tags":{},"startTime":1785389984846,"traceId":"456f595ad3c40dfa"},{"name":"check-page","duration":1075393,"timestamp":6582012411533,"id":61,"parentId":19,"tags":{"page":"/login"},"startTime":1785389984658,"traceId":"456f595ad3c40dfa"},{"name":"is-page-static","duration":887112,"timestamp":6582012600022,"id":116,"parentId":23,"tags":{},"startTime":1785389984846,"traceId":"456f595ad3c40dfa"},{"name":"check-page","duration":1093446,"timestamp":6582012393725,"id":23,"parentId":19,"tags":{"page":"/admin"},"startTime":1785389984640,"traceId":"456f595ad3c40dfa"},{"name":"is-page-static","duration":891401,"timestamp":6582012600137,"id":123,"parentId":70,"tags":{},"startTime":1785389984846,"traceId":"456f595ad3c40dfa"}]
2
- [{"name":"check-page","duration":1075597,"timestamp":6582012416248,"id":70,"parentId":19,"tags":{"page":"/servers"},"startTime":1785389984663,"traceId":"456f595ad3c40dfa"},{"name":"is-page-static","duration":888654,"timestamp":6582012609446,"id":125,"parentId":73,"tags":{},"startTime":1785389984856,"traceId":"456f595ad3c40dfa"},{"name":"check-page","duration":1080745,"timestamp":6582012417422,"id":73,"parentId":19,"tags":{"page":"/settings/tokens"},"startTime":1785389984664,"traceId":"456f595ad3c40dfa"},{"name":"is-page-static","duration":900455,"timestamp":6582012609407,"id":124,"parentId":71,"tags":{},"startTime":1785389984856,"traceId":"456f595ad3c40dfa"},{"name":"check-page","duration":1093528,"timestamp":6582012416404,"id":71,"parentId":19,"tags":{"page":"/settings/networks"},"startTime":1785389984663,"traceId":"456f595ad3c40dfa"},{"name":"is-page-static","duration":900547,"timestamp":6582012609581,"id":126,"parentId":74,"tags":{},"startTime":1785389984856,"traceId":"456f595ad3c40dfa"},{"name":"check-page","duration":1092445,"timestamp":6582012417719,"id":74,"parentId":19,"tags":{"page":"/tasks/[id]"},"startTime":1785389984664,"traceId":"456f595ad3c40dfa"},{"name":"is-page-static","duration":911398,"timestamp":6582012609597,"id":127,"parentId":75,"tags":{},"startTime":1785389984856,"traceId":"456f595ad3c40dfa"},{"name":"check-page","duration":1103165,"timestamp":6582012417924,"id":75,"parentId":19,"tags":{"page":"/tasks"},"startTime":1785389984664,"traceId":"456f595ad3c40dfa"},{"name":"is-page-static","duration":1099331,"timestamp":6582012421891,"id":81,"parentId":33,"tags":{},"startTime":1785389984668,"traceId":"456f595ad3c40dfa"},{"name":"check-page","duration":1119287,"timestamp":6582012401973,"id":33,"parentId":19,"tags":{"page":"/api/auth/logout"},"startTime":1785389984648,"traceId":"456f595ad3c40dfa"},{"name":"is-page-static","duration":924065,"timestamp":6582012609607,"id":128,"parentId":64,"tags":{},"startTime":1785389984856,"traceId":"456f595ad3c40dfa"},{"name":"check-page","duration":1121719,"timestamp":6582012412031,"id":64,"parentId":19,"tags":{"page":"/messages"},"startTime":1785389984658,"traceId":"456f595ad3c40dfa"},{"name":"is-page-static","duration":926531,"timestamp":6582012609620,"id":129,"parentId":67,"tags":{},"startTime":1785389984856,"traceId":"456f595ad3c40dfa"},{"name":"check-page","duration":1120888,"timestamp":6582012415329,"id":67,"parentId":19,"tags":{"page":"/"},"startTime":1785389984662,"traceId":"456f595ad3c40dfa"},{"name":"is-page-static","duration":936223,"timestamp":6582012600088,"id":118,"parentId":62,"tags":{},"startTime":1785389984846,"traceId":"456f595ad3c40dfa"},{"name":"check-page","duration":1124603,"timestamp":6582012411733,"id":62,"parentId":19,"tags":{"page":"/logs"},"startTime":1785389984658,"traceId":"456f595ad3c40dfa"},{"name":"is-page-static","duration":922205,"timestamp":6582012619477,"id":130,"parentId":72,"tags":{},"startTime":1785389984866,"traceId":"456f595ad3c40dfa"},{"name":"check-page","duration":1125121,"timestamp":6582012416638,"id":72,"parentId":19,"tags":{"page":"/settings"},"startTime":1785389984663,"traceId":"456f595ad3c40dfa"},{"name":"is-page-static","duration":1096137,"timestamp":6582012464400,"id":106,"parentId":28,"tags":{},"startTime":1785389984711,"traceId":"456f595ad3c40dfa"},{"name":"check-page","duration":1160068,"timestamp":6582012400558,"id":28,"parentId":19,"tags":{"page":"/api/anet/node-lifecycle"},"startTime":1785389984647,"traceId":"456f595ad3c40dfa"},{"name":"is-page-static","duration":979397,"timestamp":6582012600109,"id":120,"parentId":66,"tags":{},"startTime":1785389984846,"traceId":"456f595ad3c40dfa"},{"name":"check-page","duration":1164711,"timestamp":6582012414878,"id":66,"parentId":19,"tags":{"page":"/nodes"},"startTime":1785389984661,"traceId":"456f595ad3c40dfa"},{"name":"static-check","duration":1189586,"timestamp":6582012390047,"id":19,"parentId":1,"tags":{},"startTime":1785389984636,"traceId":"456f595ad3c40dfa"},{"name":"write-routes-manifest","duration":6969,"timestamp":6582013600467,"id":132,"parentId":1,"tags":{},"startTime":1785389985847,"traceId":"456f595ad3c40dfa"},{"name":"load-dotenv","duration":76,"timestamp":6582013648039,"id":135,"parentId":134,"tags":{},"startTime":1785389985894,"traceId":"456f595ad3c40dfa"},{"name":"run-export-path-map","duration":967,"timestamp":6582013655982,"id":136,"parentId":134,"tags":{},"startTime":1785389985902,"traceId":"456f595ad3c40dfa"},{"name":"next-export","duration":827117,"timestamp":6582013646187,"id":134,"parentId":1,"tags":{},"startTime":1785389985892,"traceId":"456f595ad3c40dfa"},{"name":"move-exported-app-not-found-","duration":757,"timestamp":6582014477015,"id":137,"parentId":133,"tags":{},"startTime":1785389986723,"traceId":"456f595ad3c40dfa"},{"name":"move-exported-app-global-error-","duration":482,"timestamp":6582014477897,"id":138,"parentId":133,"tags":{},"startTime":1785389986724,"traceId":"456f595ad3c40dfa"},{"name":"static-generation","duration":855600,"timestamp":6582013624783,"id":133,"parentId":1,"tags":{},"startTime":1785389985871,"traceId":"456f595ad3c40dfa"},{"name":"write-routes-manifest","duration":664,"timestamp":6582014480665,"id":139,"parentId":1,"tags":{},"startTime":1785389986727,"traceId":"456f595ad3c40dfa"},{"name":"print-tree-view","duration":5618,"timestamp":6582014499135,"id":140,"parentId":1,"tags":{},"startTime":1785389986745,"traceId":"456f595ad3c40dfa"},{"name":"write-route-bundle-stats","duration":17058,"timestamp":6582014504795,"id":141,"parentId":1,"tags":{},"startTime":1785389986751,"traceId":"456f595ad3c40dfa"},{"name":"telemetry-flush","duration":22920,"timestamp":6582014521891,"id":142,"parentId":1,"tags":{},"startTime":1785389986768,"traceId":"456f595ad3c40dfa"},{"name":"next-build","duration":27588018,"timestamp":6581986956845,"id":1,"tags":{"buildMode":"default","version":"16.2.3","bundler":"turbopack","has-custom-webpack-config":"false","use-build-worker":"true"},"startTime":1785389959203,"traceId":"456f595ad3c40dfa"}]
1
+ [{"name":"generate-buildid","duration":354,"timestamp":6609792983763,"id":4,"parentId":1,"tags":{},"startTime":1785417765230,"traceId":"0cf6f55fba1dcbc8"},{"name":"load-custom-routes","duration":510,"timestamp":6609792984292,"id":5,"parentId":1,"tags":{},"startTime":1785417765231,"traceId":"0cf6f55fba1dcbc8"},{"name":"create-dist-dir","duration":843,"timestamp":6609792984849,"id":6,"parentId":1,"tags":{},"startTime":1785417765231,"traceId":"0cf6f55fba1dcbc8"},{"name":"clean","duration":60815,"timestamp":6609792986528,"id":7,"parentId":1,"tags":{},"startTime":1785417765233,"traceId":"0cf6f55fba1dcbc8"},{"name":"discover-routes","duration":36309,"timestamp":6609793162140,"id":8,"parentId":1,"tags":{},"startTime":1785417765408,"traceId":"0cf6f55fba1dcbc8"},{"name":"create-root-mapping","duration":173,"timestamp":6609793198536,"id":9,"parentId":1,"tags":{},"startTime":1785417765445,"traceId":"0cf6f55fba1dcbc8"},{"name":"generate-route-types","duration":41975,"timestamp":6609793204238,"id":10,"parentId":1,"tags":{},"startTime":1785417765451,"traceId":"0cf6f55fba1dcbc8"},{"name":"public-dir-conflict-check","duration":109,"timestamp":6609793246325,"id":11,"parentId":1,"tags":{},"startTime":1785417765493,"traceId":"0cf6f55fba1dcbc8"},{"name":"generate-routes-manifest","duration":6682,"timestamp":6609793246551,"id":12,"parentId":1,"tags":{},"startTime":1785417765493,"traceId":"0cf6f55fba1dcbc8"},{"name":"run-turbopack","duration":9558674,"timestamp":6609793263490,"id":14,"parentId":1,"tags":{},"startTime":1785417765510,"traceId":"0cf6f55fba1dcbc8"},{"name":"turbopack-build-events","duration":79,"timestamp":6609793660813,"id":15,"parentId":1,"tags":{},"startTime":1785417765907,"traceId":"0cf6f55fba1dcbc8"},{"name":"run-typescript","duration":15255925,"timestamp":6609802839110,"id":16,"parentId":1,"tags":{},"startTime":1785417775085,"traceId":"0cf6f55fba1dcbc8"},{"name":"generate-required-server-files","duration":2469,"timestamp":6609818096398,"id":18,"parentId":1,"tags":{},"startTime":1785417790343,"traceId":"0cf6f55fba1dcbc8"},{"name":"check-static-error-page","duration":26967,"timestamp":6609818323684,"id":20,"parentId":19,"tags":{},"startTime":1785417790570,"traceId":"0cf6f55fba1dcbc8"},{"name":"is-page-static","duration":642076,"timestamp":6609818354827,"id":77,"parentId":22,"tags":{},"startTime":1785417790601,"traceId":"0cf6f55fba1dcbc8"},{"name":"check-page","duration":668187,"timestamp":6609818328901,"id":22,"parentId":19,"tags":{"page":"/_global-error"},"startTime":1785417790575,"traceId":"0cf6f55fba1dcbc8"},{"name":"is-page-static","duration":738828,"timestamp":6609818355598,"id":82,"parentId":34,"tags":{},"startTime":1785417790602,"traceId":"0cf6f55fba1dcbc8"},{"name":"check-page","duration":759137,"timestamp":6609818335397,"id":34,"parentId":19,"tags":{"page":"/api/auth/v3"},"startTime":1785417790582,"traceId":"0cf6f55fba1dcbc8"},{"name":"is-page-static","duration":802304,"timestamp":6609818359687,"id":84,"parentId":36,"tags":{},"startTime":1785417790606,"traceId":"0cf6f55fba1dcbc8"},{"name":"check-page","duration":826120,"timestamp":6609818335975,"id":36,"parentId":19,"tags":{"page":"/api/hub/auth"},"startTime":1785417790582,"traceId":"0cf6f55fba1dcbc8"},{"name":"is-page-static","duration":819504,"timestamp":6609818354441,"id":76,"parentId":21,"tags":{},"startTime":1785417790601,"traceId":"0cf6f55fba1dcbc8"},{"name":"check-page","duration":849373,"timestamp":6609818325744,"id":21,"parentId":19,"tags":{"page":"/_not-found"},"startTime":1785417790572,"traceId":"0cf6f55fba1dcbc8"},{"name":"is-page-static","duration":849512,"timestamp":6609818359952,"id":85,"parentId":37,"tags":{},"startTime":1785417790606,"traceId":"0cf6f55fba1dcbc8"},{"name":"check-page","duration":873388,"timestamp":6609818336178,"id":37,"parentId":19,"tags":{"page":"/api/hub/broadcast"},"startTime":1785417790582,"traceId":"0cf6f55fba1dcbc8"},{"name":"is-page-static","duration":858595,"timestamp":6609818360103,"id":87,"parentId":41,"tags":{},"startTime":1785417790606,"traceId":"0cf6f55fba1dcbc8"},{"name":"check-page","duration":880504,"timestamp":6609818338272,"id":41,"parentId":19,"tags":{"page":"/api/hub/inbox"},"startTime":1785417790585,"traceId":"0cf6f55fba1dcbc8"},{"name":"is-page-static","duration":869543,"timestamp":6609818360126,"id":88,"parentId":42,"tags":{},"startTime":1785417790606,"traceId":"0cf6f55fba1dcbc8"},{"name":"check-page","duration":891420,"timestamp":6609818338347,"id":42,"parentId":19,"tags":{"page":"/api/hub/messages"},"startTime":1785417790585,"traceId":"0cf6f55fba1dcbc8"},{"name":"is-page-static","duration":883735,"timestamp":6609818360155,"id":89,"parentId":43,"tags":{},"startTime":1785417790606,"traceId":"0cf6f55fba1dcbc8"},{"name":"check-page","duration":905561,"timestamp":6609818338408,"id":43,"parentId":19,"tags":{"page":"/api/hub/networks"},"startTime":1785417790585,"traceId":"0cf6f55fba1dcbc8"},{"name":"is-page-static","duration":889250,"timestamp":6609818360174,"id":90,"parentId":45,"tags":{},"startTime":1785417790606,"traceId":"0cf6f55fba1dcbc8"},{"name":"check-page","duration":910761,"timestamp":6609818338813,"id":45,"parentId":19,"tags":{"page":"/api/hub/nodes"},"startTime":1785417790585,"traceId":"0cf6f55fba1dcbc8"},{"name":"is-page-static","duration":896609,"timestamp":6609818354921,"id":78,"parentId":29,"tags":{},"startTime":1785417790601,"traceId":"0cf6f55fba1dcbc8"},{"name":"check-page","duration":917441,"timestamp":6609818334156,"id":29,"parentId":19,"tags":{"page":"/api/anet/providers/probe-results"},"startTime":1785417790580,"traceId":"0cf6f55fba1dcbc8"},{"name":"is-page-static","duration":901923,"timestamp":6609818360189,"id":91,"parentId":46,"tags":{},"startTime":1785417790606,"traceId":"0cf6f55fba1dcbc8"},{"name":"check-page","duration":923269,"timestamp":6609818338918,"id":46,"parentId":19,"tags":{"page":"/api/hub/register"},"startTime":1785417790585,"traceId":"0cf6f55fba1dcbc8"},{"name":"is-page-static","duration":902327,"timestamp":6609818360211,"id":92,"parentId":47,"tags":{},"startTime":1785417790606,"traceId":"0cf6f55fba1dcbc8"},{"name":"check-page","duration":923588,"timestamp":6609818338994,"id":47,"parentId":19,"tags":{"page":"/api/hub/send"},"startTime":1785417790585,"traceId":"0cf6f55fba1dcbc8"},{"name":"is-page-static","duration":911484,"timestamp":6609818360221,"id":93,"parentId":48,"tags":{},"startTime":1785417790606,"traceId":"0cf6f55fba1dcbc8"},{"name":"check-page","duration":931513,"timestamp":6609818340261,"id":48,"parentId":19,"tags":{"page":"/api/hub/server-logs"},"startTime":1785417790587,"traceId":"0cf6f55fba1dcbc8"},{"name":"is-page-static","duration":918720,"timestamp":6609818360248,"id":95,"parentId":52,"tags":{},"startTime":1785417790607,"traceId":"0cf6f55fba1dcbc8"},{"name":"check-page","duration":937980,"timestamp":6609818341073,"id":52,"parentId":19,"tags":{"page":"/api/hub/session"},"startTime":1785417790587,"traceId":"0cf6f55fba1dcbc8"},{"name":"is-page-static","duration":923722,"timestamp":6609818360257,"id":96,"parentId":53,"tags":{},"startTime":1785417790607,"traceId":"0cf6f55fba1dcbc8"},{"name":"check-page","duration":942846,"timestamp":6609818341227,"id":53,"parentId":19,"tags":{"page":"/api/hub/stats"},"startTime":1785417790588,"traceId":"0cf6f55fba1dcbc8"},{"name":"is-page-static","duration":939142,"timestamp":6609818360270,"id":97,"parentId":54,"tags":{},"startTime":1785417790607,"traceId":"0cf6f55fba1dcbc8"},{"name":"check-page","duration":958148,"timestamp":6609818341346,"id":54,"parentId":19,"tags":{"page":"/api/hub/status"},"startTime":1785417790588,"traceId":"0cf6f55fba1dcbc8"},{"name":"is-page-static","duration":948871,"timestamp":6609818360283,"id":98,"parentId":55,"tags":{},"startTime":1785417790607,"traceId":"0cf6f55fba1dcbc8"},{"name":"check-page","duration":967790,"timestamp":6609818341464,"id":55,"parentId":19,"tags":{"page":"/api/hub/task-events"},"startTime":1785417790588,"traceId":"0cf6f55fba1dcbc8"},{"name":"is-page-static","duration":959900,"timestamp":6609818355044,"id":79,"parentId":30,"tags":{},"startTime":1785417790601,"traceId":"0cf6f55fba1dcbc8"},{"name":"check-page","duration":980672,"timestamp":6609818334361,"id":30,"parentId":19,"tags":{"page":"/api/anet/providers/probe"},"startTime":1785417790581,"traceId":"0cf6f55fba1dcbc8"},{"name":"is-page-static","duration":960961,"timestamp":6609818360306,"id":100,"parentId":57,"tags":{},"startTime":1785417790607,"traceId":"0cf6f55fba1dcbc8"},{"name":"check-page","duration":979591,"timestamp":6609818341743,"id":57,"parentId":19,"tags":{"page":"/api/hub/tmux"},"startTime":1785417790588,"traceId":"0cf6f55fba1dcbc8"},{"name":"is-page-static","duration":965544,"timestamp":6609818359584,"id":83,"parentId":35,"tags":{},"startTime":1785417790606,"traceId":"0cf6f55fba1dcbc8"},{"name":"check-page","duration":989690,"timestamp":6609818335509,"id":35,"parentId":19,"tags":{"page":"/api/hub/audit-log"},"startTime":1785417790582,"traceId":"0cf6f55fba1dcbc8"},{"name":"is-page-static","duration":977671,"timestamp":6609818360297,"id":99,"parentId":56,"tags":{},"startTime":1785417790607,"traceId":"0cf6f55fba1dcbc8"},{"name":"check-page","duration":996485,"timestamp":6609818341575,"id":56,"parentId":19,"tags":{"page":"/api/hub/tasks"},"startTime":1785417790588,"traceId":"0cf6f55fba1dcbc8"},{"name":"is-page-static","duration":978220,"timestamp":6609818360065,"id":86,"parentId":40,"tags":{},"startTime":1785417790606,"traceId":"0cf6f55fba1dcbc8"},{"name":"check-page","duration":1000202,"timestamp":6609818338119,"id":40,"parentId":19,"tags":{"page":"/api/hub/health"},"startTime":1785417790584,"traceId":"0cf6f55fba1dcbc8"},{"name":"is-page-static","duration":988709,"timestamp":6609818360342,"id":103,"parentId":63,"tags":{},"startTime":1785417790607,"traceId":"0cf6f55fba1dcbc8"},{"name":"check-page","duration":1005648,"timestamp":6609818343474,"id":63,"parentId":19,"tags":{"page":"/manifest.webmanifest"},"startTime":1785417790590,"traceId":"0cf6f55fba1dcbc8"},{"name":"is-page-static","duration":987856,"timestamp":6609818370589,"id":104,"parentId":24,"tags":{},"startTime":1785417790617,"traceId":"0cf6f55fba1dcbc8"},{"name":"check-page","duration":1028903,"timestamp":6609818329615,"id":24,"parentId":19,"tags":{"page":"/api/anet/config"},"startTime":1785417790576,"traceId":"0cf6f55fba1dcbc8"},{"name":"is-page-static","duration":998398,"timestamp":6609818360332,"id":102,"parentId":60,"tags":{},"startTime":1785417790607,"traceId":"0cf6f55fba1dcbc8"},{"name":"check-page","duration":1016192,"timestamp":6609818342583,"id":60,"parentId":19,"tags":{"page":"/favicon.ico"},"startTime":1785417790589,"traceId":"0cf6f55fba1dcbc8"},{"name":"is-page-static","duration":998603,"timestamp":6609818360319,"id":101,"parentId":58,"tags":{},"startTime":1785417790607,"traceId":"0cf6f55fba1dcbc8"},{"name":"check-page","duration":1017095,"timestamp":6609818341861,"id":58,"parentId":19,"tags":{"page":"/api/hub/tokens"},"startTime":1785417790588,"traceId":"0cf6f55fba1dcbc8"},{"name":"is-page-static","duration":999788,"timestamp":6609818360234,"id":94,"parentId":50,"tags":{},"startTime":1785417790607,"traceId":"0cf6f55fba1dcbc8"},{"name":"check-page","duration":1019430,"timestamp":6609818340653,"id":50,"parentId":19,"tags":{"page":"/api/hub/server/[hostname]/health"},"startTime":1785417790587,"traceId":"0cf6f55fba1dcbc8"},{"name":"is-page-static","duration":987031,"timestamp":6609818373214,"id":105,"parentId":25,"tags":{},"startTime":1785417790619,"traceId":"0cf6f55fba1dcbc8"},{"name":"check-page","duration":1027936,"timestamp":6609818332350,"id":25,"parentId":19,"tags":{"page":"/api/anet/host-supervisors"},"startTime":1785417790579,"traceId":"0cf6f55fba1dcbc8"},{"name":"is-page-static","duration":1012099,"timestamp":6609818355161,"id":80,"parentId":32,"tags":{},"startTime":1785417790601,"traceId":"0cf6f55fba1dcbc8"},{"name":"check-page","duration":1032152,"timestamp":6609818335167,"id":32,"parentId":19,"tags":{"page":"/api/auth/login"},"startTime":1785417790581,"traceId":"0cf6f55fba1dcbc8"},{"name":"is-page-static","duration":991718,"timestamp":6609818376403,"id":106,"parentId":26,"tags":{},"startTime":1785417790623,"traceId":"0cf6f55fba1dcbc8"},{"name":"check-page","duration":1035417,"timestamp":6609818332758,"id":26,"parentId":19,"tags":{"page":"/api/anet/node-config"},"startTime":1785417790579,"traceId":"0cf6f55fba1dcbc8"},{"name":"is-page-static","duration":993620,"timestamp":6609818380526,"id":107,"parentId":27,"tags":{},"startTime":1785417790627,"traceId":"0cf6f55fba1dcbc8"},{"name":"check-page","duration":1041017,"timestamp":6609818333188,"id":27,"parentId":19,"tags":{"page":"/api/anet/node-create"},"startTime":1785417790579,"traceId":"0cf6f55fba1dcbc8"},{"name":"is-page-static","duration":968242,"timestamp":6609818406095,"id":109,"parentId":38,"tags":{},"startTime":1785417790652,"traceId":"0cf6f55fba1dcbc8"},{"name":"check-page","duration":1038091,"timestamp":6609818336273,"id":38,"parentId":19,"tags":{"page":"/api/hub/events"},"startTime":1785417790583,"traceId":"0cf6f55fba1dcbc8"},{"name":"is-page-static","duration":991807,"timestamp":6609818394528,"id":108,"parentId":28,"tags":{},"startTime":1785417790641,"traceId":"0cf6f55fba1dcbc8"},{"name":"check-page","duration":1052863,"timestamp":6609818333580,"id":28,"parentId":19,"tags":{"page":"/api/anet/node-lifecycle"},"startTime":1785417790580,"traceId":"0cf6f55fba1dcbc8"},{"name":"is-page-static","duration":956461,"timestamp":6609818432504,"id":111,"parentId":31,"tags":{},"startTime":1785417790679,"traceId":"0cf6f55fba1dcbc8"},{"name":"check-page","duration":1054523,"timestamp":6609818334539,"id":31,"parentId":19,"tags":{"page":"/api/anet/providers"},"startTime":1785417790581,"traceId":"0cf6f55fba1dcbc8"},{"name":"is-page-static","duration":983259,"timestamp":6609818409344,"id":110,"parentId":39,"tags":{},"startTime":1785417790656,"traceId":"0cf6f55fba1dcbc8"},{"name":"check-page","duration":1056203,"timestamp":6609818336483,"id":39,"parentId":19,"tags":{"page":"/api/hub/files/[fileId]"},"startTime":1785417790583,"traceId":"0cf6f55fba1dcbc8"},{"name":"is-page-static","duration":956507,"timestamp":6609818439789,"id":113,"parentId":49,"tags":{},"startTime":1785417790686,"traceId":"0cf6f55fba1dcbc8"},{"name":"check-page","duration":1055977,"timestamp":6609818340384,"id":49,"parentId":19,"tags":{"page":"/api/hub/server/[hostname]/agents"},"startTime":1785417790587,"traceId":"0cf6f55fba1dcbc8"},{"name":"is-page-static","duration":955760,"timestamp":6609818440785,"id":114,"parentId":51,"tags":{},"startTime":1785417790687,"traceId":"0cf6f55fba1dcbc8"},{"name":"check-page","duration":1055787,"timestamp":6609818340792,"id":51,"parentId":19,"tags":{"page":"/api/hub/servers"},"startTime":1785417790587,"traceId":"0cf6f55fba1dcbc8"},{"name":"is-page-static","duration":964206,"timestamp":6609818434508,"id":112,"parentId":44,"tags":{},"startTime":1785417790681,"traceId":"0cf6f55fba1dcbc8"},{"name":"check-page","duration":1060294,"timestamp":6609818338468,"id":44,"parentId":19,"tags":{"page":"/api/hub/nodes/[ref]/attrs"},"startTime":1785417790585,"traceId":"0cf6f55fba1dcbc8"},{"name":"is-page-static","duration":980661,"timestamp":6609818443800,"id":115,"parentId":59,"tags":{},"startTime":1785417790690,"traceId":"0cf6f55fba1dcbc8"},{"name":"check-page","duration":1082578,"timestamp":6609818341967,"id":59,"parentId":19,"tags":{"page":"/api/hub/upload"},"startTime":1785417790588,"traceId":"0cf6f55fba1dcbc8"},{"name":"is-page-static","duration":958406,"timestamp":6609818469041,"id":120,"parentId":66,"tags":{},"startTime":1785417790715,"traceId":"0cf6f55fba1dcbc8"},{"name":"check-page","duration":1081678,"timestamp":6609818345836,"id":66,"parentId":19,"tags":{"page":"/nodes"},"startTime":1785417790592,"traceId":"0cf6f55fba1dcbc8"},{"name":"is-page-static","duration":966478,"timestamp":6609818469060,"id":122,"parentId":69,"tags":{},"startTime":1785417790715,"traceId":"0cf6f55fba1dcbc8"},{"name":"check-page","duration":1087340,"timestamp":6609818348267,"id":69,"parentId":19,"tags":{"page":"/server-logs"},"startTime":1785417790595,"traceId":"0cf6f55fba1dcbc8"},{"name":"is-page-static","duration":992805,"timestamp":6609818469069,"id":123,"parentId":70,"tags":{},"startTime":1785417790715,"traceId":"0cf6f55fba1dcbc8"},{"name":"check-page","duration":1113356,"timestamp":6609818348595,"id":70,"parentId":19,"tags":{"page":"/servers"},"startTime":1785417790595,"traceId":"0cf6f55fba1dcbc8"},{"name":"is-page-static","duration":1001666,"timestamp":6609818469079,"id":124,"parentId":71,"tags":{},"startTime":1785417790715,"traceId":"0cf6f55fba1dcbc8"},{"name":"check-page","duration":1122022,"timestamp":6609818348795,"id":71,"parentId":19,"tags":{"page":"/settings/networks"},"startTime":1785417790595,"traceId":"0cf6f55fba1dcbc8"},{"name":"is-page-static","duration":1123962,"timestamp":6609818355418,"id":81,"parentId":33,"tags":{},"startTime":1785417790602,"traceId":"0cf6f55fba1dcbc8"}]
2
+ [{"name":"check-page","duration":1144389,"timestamp":6609818335307,"id":33,"parentId":19,"tags":{"page":"/api/auth/logout"},"startTime":1785417790582,"traceId":"0cf6f55fba1dcbc8"},{"name":"is-page-static","duration":1012422,"timestamp":6609818468974,"id":117,"parentId":61,"tags":{},"startTime":1785417790715,"traceId":"0cf6f55fba1dcbc8"},{"name":"check-page","duration":1138391,"timestamp":6609818343070,"id":61,"parentId":19,"tags":{"page":"/login"},"startTime":1785417790589,"traceId":"0cf6f55fba1dcbc8"},{"name":"is-page-static","duration":1019125,"timestamp":6609818469107,"id":127,"parentId":75,"tags":{},"startTime":1785417790715,"traceId":"0cf6f55fba1dcbc8"},{"name":"check-page","duration":1137988,"timestamp":6609818350300,"id":75,"parentId":19,"tags":{"page":"/tasks"},"startTime":1785417790597,"traceId":"0cf6f55fba1dcbc8"},{"name":"is-page-static","duration":1026010,"timestamp":6609818469088,"id":125,"parentId":73,"tags":{},"startTime":1785417790715,"traceId":"0cf6f55fba1dcbc8"},{"name":"check-page","duration":1145315,"timestamp":6609818349853,"id":73,"parentId":19,"tags":{"page":"/settings/tokens"},"startTime":1785417790596,"traceId":"0cf6f55fba1dcbc8"},{"name":"is-page-static","duration":1026251,"timestamp":6609818469116,"id":128,"parentId":64,"tags":{},"startTime":1785417790715,"traceId":"0cf6f55fba1dcbc8"},{"name":"check-page","duration":1151818,"timestamp":6609818343590,"id":64,"parentId":19,"tags":{"page":"/messages"},"startTime":1785417790590,"traceId":"0cf6f55fba1dcbc8"},{"name":"is-page-static","duration":1031040,"timestamp":6609818469125,"id":129,"parentId":67,"tags":{},"startTime":1785417790715,"traceId":"0cf6f55fba1dcbc8"},{"name":"check-page","duration":1154002,"timestamp":6609818346238,"id":67,"parentId":19,"tags":{"page":"/"},"startTime":1785417790593,"traceId":"0cf6f55fba1dcbc8"},{"name":"is-page-static","duration":1025184,"timestamp":6609818477887,"id":130,"parentId":72,"tags":{},"startTime":1785417790724,"traceId":"0cf6f55fba1dcbc8"},{"name":"check-page","duration":1154060,"timestamp":6609818349070,"id":72,"parentId":19,"tags":{"page":"/settings"},"startTime":1785417790595,"traceId":"0cf6f55fba1dcbc8"},{"name":"is-page-static","duration":1059903,"timestamp":6609818468985,"id":118,"parentId":62,"tags":{},"startTime":1785417790715,"traceId":"0cf6f55fba1dcbc8"},{"name":"check-page","duration":1185690,"timestamp":6609818343279,"id":62,"parentId":19,"tags":{"page":"/logs"},"startTime":1785417790590,"traceId":"0cf6f55fba1dcbc8"},{"name":"is-page-static","duration":1060352,"timestamp":6609818468921,"id":116,"parentId":23,"tags":{},"startTime":1785417790715,"traceId":"0cf6f55fba1dcbc8"},{"name":"check-page","duration":1200008,"timestamp":6609818329321,"id":23,"parentId":19,"tags":{"page":"/admin"},"startTime":1785417790576,"traceId":"0cf6f55fba1dcbc8"},{"name":"is-page-static","duration":1066926,"timestamp":6609818468996,"id":119,"parentId":65,"tags":{},"startTime":1785417790715,"traceId":"0cf6f55fba1dcbc8"},{"name":"check-page","duration":1191650,"timestamp":6609818344346,"id":65,"parentId":19,"tags":{"page":"/node"},"startTime":1785417790591,"traceId":"0cf6f55fba1dcbc8"},{"name":"is-page-static","duration":1079521,"timestamp":6609818469051,"id":121,"parentId":68,"tags":{},"startTime":1785417790715,"traceId":"0cf6f55fba1dcbc8"},{"name":"check-page","duration":1201876,"timestamp":6609818346788,"id":68,"parentId":19,"tags":{"page":"/providers"},"startTime":1785417790593,"traceId":"0cf6f55fba1dcbc8"},{"name":"is-page-static","duration":1092550,"timestamp":6609818469097,"id":126,"parentId":74,"tags":{},"startTime":1785417790715,"traceId":"0cf6f55fba1dcbc8"},{"name":"check-page","duration":1211621,"timestamp":6609818350101,"id":74,"parentId":19,"tags":{"page":"/tasks/[id]"},"startTime":1785417790596,"traceId":"0cf6f55fba1dcbc8"},{"name":"static-check","duration":1239312,"timestamp":6609818322461,"id":19,"parentId":1,"tags":{},"startTime":1785417790569,"traceId":"0cf6f55fba1dcbc8"},{"name":"write-routes-manifest","duration":755,"timestamp":6609819568923,"id":132,"parentId":1,"tags":{},"startTime":1785417791815,"traceId":"0cf6f55fba1dcbc8"},{"name":"load-dotenv","duration":90,"timestamp":6609819585980,"id":135,"parentId":134,"tags":{},"startTime":1785417791832,"traceId":"0cf6f55fba1dcbc8"},{"name":"run-export-path-map","duration":862,"timestamp":6609819591901,"id":136,"parentId":134,"tags":{},"startTime":1785417791838,"traceId":"0cf6f55fba1dcbc8"},{"name":"next-export","duration":790520,"timestamp":6609819584023,"id":134,"parentId":1,"tags":{},"startTime":1785417791830,"traceId":"0cf6f55fba1dcbc8"},{"name":"move-exported-app-not-found-","duration":679,"timestamp":6609820378414,"id":137,"parentId":133,"tags":{},"startTime":1785417792625,"traceId":"0cf6f55fba1dcbc8"},{"name":"move-exported-app-global-error-","duration":560,"timestamp":6609820379221,"id":138,"parentId":133,"tags":{},"startTime":1785417792625,"traceId":"0cf6f55fba1dcbc8"},{"name":"static-generation","duration":807937,"timestamp":6609819574628,"id":133,"parentId":1,"tags":{},"startTime":1785417791821,"traceId":"0cf6f55fba1dcbc8"},{"name":"write-routes-manifest","duration":488,"timestamp":6609820382862,"id":139,"parentId":1,"tags":{},"startTime":1785417792629,"traceId":"0cf6f55fba1dcbc8"},{"name":"print-tree-view","duration":4411,"timestamp":6609820403794,"id":140,"parentId":1,"tags":{},"startTime":1785417792650,"traceId":"0cf6f55fba1dcbc8"},{"name":"write-route-bundle-stats","duration":16939,"timestamp":6609820408259,"id":141,"parentId":1,"tags":{},"startTime":1785417792655,"traceId":"0cf6f55fba1dcbc8"},{"name":"telemetry-flush","duration":17943,"timestamp":6609820425236,"id":142,"parentId":1,"tags":{},"startTime":1785417792672,"traceId":"0cf6f55fba1dcbc8"},{"name":"next-build","duration":27523029,"timestamp":6609792920199,"id":1,"tags":{"buildMode":"default","version":"16.2.3","bundler":"turbopack","has-custom-webpack-config":"false","use-build-worker":"true"},"startTime":1785417765166,"traceId":"0cf6f55fba1dcbc8"}]
package/.next/trace-build CHANGED
@@ -1 +1 @@
1
- [{"name":"run-turbopack","duration":9375161,"timestamp":6581987303276,"id":14,"parentId":1,"tags":{},"startTime":1785389959550,"traceId":"456f595ad3c40dfa"},{"name":"turbopack-build-events","duration":98,"timestamp":6581987666324,"id":15,"parentId":1,"tags":{},"startTime":1785389959913,"traceId":"456f595ad3c40dfa"},{"name":"run-typescript","duration":15277045,"timestamp":6581996690196,"id":16,"parentId":1,"tags":{},"startTime":1785389968936,"traceId":"456f595ad3c40dfa"},{"name":"static-check","duration":1189586,"timestamp":6582012390047,"id":19,"parentId":1,"tags":{},"startTime":1785389984636,"traceId":"456f595ad3c40dfa"},{"name":"static-generation","duration":855600,"timestamp":6582013624783,"id":133,"parentId":1,"tags":{},"startTime":1785389985871,"traceId":"456f595ad3c40dfa"},{"name":"telemetry-flush","duration":22920,"timestamp":6582014521891,"id":142,"parentId":1,"tags":{},"startTime":1785389986768,"traceId":"456f595ad3c40dfa"},{"name":"next-build","duration":27588018,"timestamp":6581986956845,"id":1,"tags":{"buildMode":"default","version":"16.2.3","bundler":"turbopack","has-custom-webpack-config":"false","use-build-worker":"true"},"startTime":1785389959203,"traceId":"456f595ad3c40dfa"}]
1
+ [{"name":"run-turbopack","duration":9558674,"timestamp":6609793263490,"id":14,"parentId":1,"tags":{},"startTime":1785417765510,"traceId":"0cf6f55fba1dcbc8"},{"name":"turbopack-build-events","duration":79,"timestamp":6609793660813,"id":15,"parentId":1,"tags":{},"startTime":1785417765907,"traceId":"0cf6f55fba1dcbc8"},{"name":"run-typescript","duration":15255925,"timestamp":6609802839110,"id":16,"parentId":1,"tags":{},"startTime":1785417775085,"traceId":"0cf6f55fba1dcbc8"},{"name":"static-check","duration":1239312,"timestamp":6609818322461,"id":19,"parentId":1,"tags":{},"startTime":1785417790569,"traceId":"0cf6f55fba1dcbc8"},{"name":"static-generation","duration":807937,"timestamp":6609819574628,"id":133,"parentId":1,"tags":{},"startTime":1785417791821,"traceId":"0cf6f55fba1dcbc8"},{"name":"telemetry-flush","duration":17943,"timestamp":6609820425236,"id":142,"parentId":1,"tags":{},"startTime":1785417792672,"traceId":"0cf6f55fba1dcbc8"},{"name":"next-build","duration":27523029,"timestamp":6609792920199,"id":1,"tags":{"buildMode":"default","version":"16.2.3","bundler":"turbopack","has-custom-webpack-config":"false","use-build-worker":"true"},"startTime":1785417765166,"traceId":"0cf6f55fba1dcbc8"}]
@@ -3,8 +3,9 @@
3
3
  import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
4
4
  import { AliasAvatar } from './AliasAvatar';
5
5
  import { TaskChatPanel } from './TaskChatPanel';
6
- import { useSessions } from '../lib/hooks';
6
+ import { useSessions, useHealth } from '../lib/hooks';
7
7
  import { relativeAgo } from '../lib/time';
8
+ import { isOnline as presenceIsOnline } from '../lib/presence';
8
9
 
9
10
  interface ChatPopoverProps {
10
11
  /** Node alias to chat with. Changing it switches the conversation. */
@@ -63,8 +64,14 @@ export function ChatPopover({ alias, onClose }: ChatPopoverProps) {
63
64
  // Round 37 / Loop: pull the target session out of the SWR cache that
64
65
  // TopoGraph already populates — same URL, so no extra network fetch.
65
66
  const { sessions } = useSessions();
67
+ const { health } = useHealth();
66
68
  const session = useMemo(() => sessions.find(s => s.alias === alias), [sessions, alias]);
67
- const isOnline = !!session && session.status !== 'offline';
69
+ // #515: presence via SSE-reachability, same source of truth as the
70
+ // stats card / sidebar / topology halos. Old predicate was pure
71
+ // `status !== 'offline'`, which for the chat popover directly
72
+ // contradicted #214 F2's stated reason ("a card you can't chat with
73
+ // shouldn't say 'online'"). SWR dedupes /api/hub/health with page.tsx.
74
+ const isOnline = !!session && presenceIsOnline(session, health?.sse_sessions);
68
75
  const lastSeenLine = !isOnline ? relativeAgo(session?.last_seen_at) : null;
69
76
 
70
77
  const clamp = useCallback((x: number, y: number, w: number, h: number) => {
@@ -6,6 +6,8 @@ import { usePathname } from 'next/navigation';
6
6
  import { useState, useEffect } from 'react';
7
7
  import useSWR from 'swr';
8
8
  import { useNetworkId } from '../lib/network-context';
9
+ import { isOnline as presenceIsOnline } from '../lib/presence';
10
+ import { useHealth } from '../lib/hooks';
9
11
 
10
12
  const networkFetcher = (url: string) => fetch(url).then(r => r.ok ? r.json() : { networks: [] });
11
13
 
@@ -281,8 +283,19 @@ function SidebarBrand({ collapsed }: { collapsed: boolean }) {
281
283
  refreshInterval: 10000,
282
284
  dedupingInterval: 4000,
283
285
  });
286
+ // #515: sse_sessions map lives on hub's /health (Health.sse_sessions),
287
+ // not on /api/status. Re-use useHealth so SWR dedupes with page.tsx
288
+ // rather than fetching twice, and the count agrees with the stats card
289
+ // and the topology legend by construction (all three consume the same
290
+ // presence.ts + same health.sse_sessions source).
291
+ const { health } = useHealth();
284
292
  const sessions = data?.sessions || [];
285
- const online = sessions.filter(s => s.status && s.status !== 'offline').length;
293
+ const sseSessions = health?.sse_sessions;
294
+ // The old `status !== 'offline'` predicate was systematically inflated
295
+ // because hub `status` doesn't age out on heartbeat loss (see #520 /
296
+ // presence.ts). SSE-reachability is the "can I talk to it right now"
297
+ // ground truth.
298
+ const online = sessions.filter(s => s.alias ? presenceIsOnline({ alias: s.alias, network_id: s.network_id }, sseSessions) : false).length;
286
299
  const total = sessions.length;
287
300
 
288
301
  if (collapsed) {
@@ -3,6 +3,7 @@
3
3
  import { useState, useEffect, useRef, useCallback, useMemo, memo, Fragment } from 'react';
4
4
  import { AliasAvatar } from './AliasAvatar';
5
5
  import { AttachmentBlock, extractAttachments } from './AttachmentBlock';
6
+ import { isOnline as presenceIsOnline } from '../lib/presence';
6
7
 
7
8
  interface ChatTask {
8
9
  task_id: string;
@@ -607,12 +608,19 @@ export function TaskChatPanel({ alias, onClose, inline, availableNodes, active }
607
608
  const aliasNetRef = useRef<Record<string, string>>({});
608
609
  useEffect(() => {
609
610
  if (availableNodes) { setMentionNodes(availableNodes); return; }
610
- fetch('/api/hub/status').then(r => r.json()).then(d => {
611
- const sessions = (d.sessions || []) as { alias: string; status: string; network_id?: string }[];
611
+ // #515: @-mention candidates must be actually reachable, not just
612
+ // "hub row hasn't flipped to offline yet". Fetch health alongside
613
+ // status so we can filter by presence.isOnline (SSE-reachable)
614
+ // rather than the retired `status !== 'offline'` predicate.
615
+ Promise.all([
616
+ fetch('/api/hub/status').then(r => r.ok ? r.json() : { sessions: [] }),
617
+ fetch('/api/hub/health').then(r => r.ok ? r.json() : {}),
618
+ ]).then(([d, health]: [{ sessions?: { alias: string; status: string; network_id?: string }[] }, { sse_sessions?: Record<string, number> }]) => {
619
+ const sessions = d.sessions || [];
612
620
  const map: Record<string, string> = {};
613
621
  for (const s of sessions) if (s.network_id) map[s.alias] = s.network_id;
614
622
  aliasNetRef.current = map;
615
- setMentionNodes(sessions.filter(s => s.status !== 'offline').map(s => s.alias));
623
+ setMentionNodes(sessions.filter(s => presenceIsOnline(s, health?.sse_sessions)).map(s => s.alias));
616
624
  }).catch(() => {});
617
625
  }, [availableNodes]);
618
626
 
@@ -11,6 +11,7 @@ import { vendorForModel, runtimeIdentity, identityLine } from '../lib/vendorIden
11
11
  import { parseHubTime, relativeAgo } from '../lib/time';
12
12
  import { DASHBOARD_VERSION } from '../lib/version';
13
13
  import { useChatUnread } from '../lib/chat-unread';
14
+ import { isOnline as presenceIsOnline, sseCountFor as presenceSseCountFor } from '../lib/presence';
14
15
 
15
16
  /** v0.10.0 Hero 1+2 / §3.F server-health hook — fetches the normalized
16
17
  * /api/hub/servers payload (preview.370 unblocked real-data via the
@@ -817,8 +818,8 @@ export function TopoGraph({ sessions, sseSessions, renameSignal }: TopoGraphProp
817
818
  treeConnectors,
818
819
  treeContentBox,
819
820
  } = useMemo(() => {
820
- const sseCount = (s: { alias: string; network_id?: string }) =>
821
- (s.network_id ? sseSessions[`${s.network_id}:${s.alias}`] : undefined) ?? sseSessions[s.alias];
821
+ // #515: unified with page.tsx / Sidebar.tsx via app/lib/presence.ts.
822
+ const sseCount = (s: { alias: string; network_id?: string }) => presenceSseCountFor(s, sseSessions);
822
823
  // Round 106 (issue #83): sort by alias so same-prefix agents
823
824
  // (通信龙 / 通信牛 / 通信工程马 …, or 研究员1号 / 研究员2号 …) end up
824
825
  // adjacent in the array — the tier layout below assigns angles by
@@ -837,6 +838,12 @@ export function TopoGraph({ sessions, sseSessions, renameSignal }: TopoGraphProp
837
838
  // come back while removing dead nodes well within an operator session.
838
839
  const GHOST_MS = 60 * 60 * 1000;
839
840
  const now = Date.now();
841
+ // #515 note: isGhost is deliberately NOT converted to presenceIsOnline —
842
+ // it's a different concept (age-based pruning of stale offline nodes) and
843
+ // its `status !== 'offline'` arm gives an intentional aliveness buffer:
844
+ // a node the hub still tags as `working` gets to stick around for the
845
+ // full GHOST_MS even if SSE dropped. Tightening that would silently
846
+ // shrink the visible topology on flaky-SSE hubs — separate change.
840
847
  const isGhost = (s: Session) => {
841
848
  if (s.status !== 'offline' || sseCount(s) || !s.last_seen_at) return false;
842
849
  // Round 35 / Loop: parseHubTime normalises SQL-style timestamps to UTC
@@ -845,8 +852,11 @@ export function TopoGraph({ sessions, sseSessions, renameSignal }: TopoGraphProp
845
852
  const t = parseHubTime(s.last_seen_at);
846
853
  return t !== null && now - t > GHOST_MS;
847
854
  };
848
- const online = sessions.filter(s => s.status !== 'offline' || sseCount(s)).sort(byAlias);
849
- const offline = sessions.filter(s => s.status === 'offline' && !sseCount(s) && !isGhost(s)).sort(byAlias);
855
+ // #515: online = SSE-reachable (shared with page.tsx / Sidebar via presence.ts).
856
+ // Old predicate (`status !== 'offline' || sseCount`) is retired — hub `status` is
857
+ // an unreliable signal on its own (see presence.ts and #520).
858
+ const online = sessions.filter(s => presenceIsOnline(s, sseSessions)).sort(byAlias);
859
+ const offline = sessions.filter(s => !presenceIsOnline(s, sseSessions) && !isGhost(s)).sort(byAlias);
850
860
  const positions: Record<string, Point> = {};
851
861
 
852
862
  if (layout === 'grid') {
@@ -974,7 +984,7 @@ export function TopoGraph({ sessions, sseSessions, renameSignal }: TopoGraphProp
974
984
  // preserving the node↔label overlap-test guarantee from R19.
975
985
  let w = 0, i = 0, o = 0;
976
986
  for (const s of band.members) {
977
- const isOn = s.status !== 'offline' || !!sseCount(s);
987
+ const isOn = presenceIsOnline(s, sseSessions);
978
988
  if (s.status === 'working') w++;
979
989
  else if (isOn) i++;
980
990
  else o++;
@@ -1214,7 +1224,7 @@ export function TopoGraph({ sessions, sseSessions, renameSignal }: TopoGraphProp
1214
1224
  const tally = (members: Session[]) => {
1215
1225
  let w = 0, i = 0, o = 0;
1216
1226
  for (const s of members) {
1217
- const isOn = s.status !== 'offline' || !!sseCount(s);
1227
+ const isOn = presenceIsOnline(s, sseSessions);
1218
1228
  if (s.status === 'working') w++;
1219
1229
  else if (isOn) i++;
1220
1230
  else o++;
@@ -4197,7 +4207,11 @@ export function TopoGraph({ sessions, sseSessions, renameSignal }: TopoGraphProp
4197
4207
  : null;
4198
4208
  const allSessions = [...onlineNodes, ...offlineNodes];
4199
4209
  const survivors = allSessions.filter(s => {
4200
- const isOnline = s.status !== 'offline';
4210
+ // #515: pinned-status filter shares the presence definition too.
4211
+ // Was `s.status !== 'offline'` (pure status), even more divergent
4212
+ // than the count sites — a `working`-but-SSE-disconnected node
4213
+ // would survive the `offline` pin filter and hide inside "online".
4214
+ const isOnline = presenceIsOnline(s, sseSessions);
4201
4215
  if (pinnedStatus === 'working' && s.status !== 'working') return false;
4202
4216
  if (pinnedStatus === 'idle' && !(isOnline && s.status !== 'working')) return false;
4203
4217
  if (pinnedStatus === 'offline' && isOnline) return false;
@@ -10493,8 +10507,9 @@ export function TopoGraph({ sessions, sseSessions, renameSignal }: TopoGraphProp
10493
10507
  const pos = nodePositions[session.alias];
10494
10508
  if (!pos) return null;
10495
10509
 
10496
- const sseCountFor = (session.network_id ? sseSessions[`${session.network_id}:${session.alias}`] : undefined) ?? sseSessions[session.alias];
10497
- const isOnline = session.status !== 'offline' || !!sseCountFor;
10510
+ // #515: main per-node render uses the shared presence definition.
10511
+ const sseCountFor = presenceSseCountFor(session, sseSessions);
10512
+ const isOnline = presenceIsOnline(session, sseSessions);
10498
10513
  const status = nodeStatus(session, isOnline, isLight);
10499
10514
  const isActive = activeAliases.has(session.alias);
10500
10515
  // #113: node size scales with the S/M/L control; halos, labels,
@@ -15290,8 +15305,7 @@ export function TopoGraph({ sessions, sseSessions, renameSignal }: TopoGraphProp
15290
15305
  {[...onlineNodes, ...offlineNodes].map(s => {
15291
15306
  const p = nodePositions[s.alias];
15292
15307
  if (!p) return null;
15293
- const sseN = (s.network_id ? sseSessions[`${s.network_id}:${s.alias}`] : undefined) ?? sseSessions[s.alias];
15294
- const isOn = s.status !== 'offline' || !!sseN;
15308
+ const isOn = presenceIsOnline(s, sseSessions);
15295
15309
  const st = nodeStatus(s, isOn, isLight);
15296
15310
  return (
15297
15311
  /* Round 372 / Loop: minimap offline-dot opacity
@@ -0,0 +1,43 @@
1
+ // #515: single source of truth for "is this node online?" across
2
+ // stats card / sidebar count / topology halos / chat popover / task
3
+ // panel @-mention picker. If you add a new place that decides "online"
4
+ // vs "offline", import isOnline() from here — don't roll your own.
5
+ //
6
+ // Definition: **SSE-reachable with at least one live connection**.
7
+ // Adopted by #214 F2 (originally in app/page.tsx). Consolidated here so
8
+ // consumers never disagree.
9
+ //
10
+ // Why `> 0` and not `!== undefined`:
11
+ // - Hub `getSSEStats()` writes `sessions[name] = arr.length` and the
12
+ // three removal paths (cancel, rekey, dead-pushEvent) each `delete`
13
+ // the key when the array empties. So on the current hub the value
14
+ // is never `0` — but this JSON comes from a hub whose version this
15
+ // dashboard doesn't control (see the legacy alias-only fallback
16
+ // below for the version we already know we support), so treating
17
+ // the map defensively costs nothing and keeps the definition
18
+ // pointing the same direction #214 F2 took: SSE-reachable = "can I
19
+ // talk to it right now", and a zero-count row is not that.
20
+ // - `!!sseLookup(s)` in the old page.tsx also treated 0 as false;
21
+ // preserving that keeps this a pure refactor for page.tsx.
22
+ //
23
+ // SSE keys in health.sse_sessions are `network_id:alias` since v0.7+
24
+ // (per-network scoping). Legacy fallback: bare alias.
25
+
26
+ export type SseSessionsMap = Record<string, unknown>;
27
+
28
+ export type PresenceSubject = {
29
+ alias: string;
30
+ network_id?: string;
31
+ };
32
+
33
+ export function sseCountFor(session: PresenceSubject, sseSessions: SseSessionsMap | undefined): number | undefined {
34
+ if (!sseSessions) return undefined;
35
+ const scoped = session.network_id ? sseSessions[`${session.network_id}:${session.alias}`] : undefined;
36
+ const value = (scoped ?? sseSessions[session.alias]) as number | undefined;
37
+ return typeof value === 'number' ? value : undefined;
38
+ }
39
+
40
+ export function isOnline(session: PresenceSubject, sseSessions: SseSessionsMap | undefined): boolean {
41
+ const n = sseCountFor(session, sseSessions);
42
+ return typeof n === 'number' && n > 0;
43
+ }
package/app/page.tsx CHANGED
@@ -18,6 +18,7 @@ import { useSessions, useHealth, useTasks, useStats } from './lib/hooks';
18
18
  import { useChatUnread } from './lib/chat-unread';
19
19
  import { isPinned, usePinVersion } from './lib/chat-pin';
20
20
  import { useSSE } from './lib/useSSE';
21
+ import { isOnline as presenceIsOnline, sseCountFor as presenceSseCountFor } from './lib/presence';
21
22
  import { useSWRConfig } from 'swr';
22
23
 
23
24
  export default function Dashboard() {
@@ -83,16 +84,11 @@ export default function Dashboard() {
83
84
  if (isLoading) return <LoadingSkeleton />;
84
85
 
85
86
  const sseSessions = health?.sse_sessions || {};
86
- // SSE keys are `network_id:alias` since v0.7+ (per-network scoping).
87
- // Fall back to alias-only for legacy hubs.
88
- const sseLookup = (s: { alias: string; network_id?: string }) =>
89
- (s.network_id ? sseSessions[`${s.network_id}:${s.alias}`] : undefined) ?? sseSessions[s.alias];
90
- // #214 F2: online = SSE-reachable ("can I talk to it right now").
91
- // The old definition (status !== 'offline' OR sse) inflated the count
92
- // with stale hub statuses and disagreed with /admin and /nodes, which
93
- // both count pure SSE — and a "online" card you can't chat with
94
- // contradicts the M2 tap-to-chat model. One definition everywhere.
95
- const isOnline = (s: { alias: string; status: string; network_id?: string }) => !!sseLookup(s);
87
+ // #515 / #214 F2: presence = SSE-reachable ("can I talk to it right now").
88
+ // Definition lives in app/lib/presence.ts so stats card / sidebar /
89
+ // topology halos always agree. See presence.ts for why hub `status` is
90
+ // an unreliable signal on its own (#520).
91
+ const isOnline = (s: { alias: string; network_id?: string }) => presenceIsOnline(s, sseSessions);
96
92
  const online = sessions.filter(isOnline).length;
97
93
  const total = sessions.length;
98
94
  const working = sessions.filter(s => s.status === 'working').length;
@@ -266,7 +262,7 @@ export default function Dashboard() {
266
262
  xl breakpoint auto-inherits lg=3 cols; 2xl bumps to 4. */}
267
263
  <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 2xl:grid-cols-4 gap-3 sm:gap-4">
268
264
  {filtered.map(s => (
269
- <AgentCard key={s.alias} session={s} hasSse={isOnline(s)} sseCount={sseLookup(s) || 0} onChat={cmd.openTab} unreadCount={unreadCount(s.alias)} />
265
+ <AgentCard key={s.alias} session={s} hasSse={isOnline(s)} sseCount={presenceSseCountFor(s, sseSessions) ?? 0} onChat={cmd.openTab} unreadCount={unreadCount(s.alias)} />
270
266
  ))}
271
267
  </div>
272
268
  {filtered.length === 0 && (
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sleep2agi/agent-network-dashboard",
3
- "version": "0.6.3-preview.43",
3
+ "version": "0.6.3-preview.44",
4
4
  "description": "Agent Network Dashboard — Web UI for managing AI Agent networks",
5
5
  "main": "apps/desktop/electron/main.cjs",
6
6
  "scripts": {
@@ -0,0 +1,75 @@
1
+ import { test, expect } from '@playwright/test';
2
+ import { isOnline, sseCountFor } from '../app/lib/presence';
3
+
4
+ // #515 predicate unit test — the "narrow" companion to
5
+ // tests/e2e-515-presence.spec.ts. That one proves the three DOM
6
+ // consumers agree (integration). This one nails down the specific
7
+ // invariant every consumer now inherits from app/lib/presence.ts:
8
+ //
9
+ // A node with `status='working'` but NO SSE entry MUST classify as
10
+ // NOT online — because hub `status` doesn't age out on heartbeat
11
+ // loss (see presence.ts and #520). Historically L4204's pinnedStatus
12
+ // filter used pure `s.status !== 'offline'`, so pinning "offline"
13
+ // dropped this zombie into "online" and it hid from the offline
14
+ // filter — exactly the bug 通信龙 flagged as needing its own
15
+ // assertion so a future refactor can't silently regress it.
16
+ //
17
+ // If any downstream consumer of `isOnline(...)` starts special-casing
18
+ // `status` again, THIS test goes red — matching the "unified predicate"
19
+ // contract more precisely than a UI-level test could without hitting
20
+ // the pin-intersection chip's two-dim activation requirement.
21
+
22
+ const NET = 'net_a';
23
+
24
+ test.describe('#515 predicate — SSE ground-truths presence, status alone lies', () => {
25
+ test('SSE-reachable with any status → online', () => {
26
+ const sse = { [`${NET}:working-sse`]: 1, [`${NET}:idle-sse`]: 1, [`${NET}:offline-sse`]: 2 };
27
+ expect(isOnline({ alias: 'working-sse', network_id: NET }, sse)).toBe(true);
28
+ expect(isOnline({ alias: 'idle-sse', network_id: NET }, sse)).toBe(true);
29
+ // Even a node the hub already flagged offline is "online" if SSE
30
+ // is talking — the hub row is stale, the socket is ground truth.
31
+ expect(isOnline({ alias: 'offline-sse', network_id: NET }, sse)).toBe(true);
32
+ });
33
+
34
+ test('SSE-less with status=working → NOT online (the L4204 zombie case)', () => {
35
+ const sse = { [`${NET}:someone-else`]: 1 };
36
+ // The regression bait — before #515 this same session slipped
37
+ // through the pinned-offline filter and hid inside "online".
38
+ expect(isOnline({ alias: 'working-no-sse', network_id: NET }, sse)).toBe(false);
39
+ });
40
+
41
+ test('SSE-less with any status → NOT online', () => {
42
+ const sse = {};
43
+ expect(isOnline({ alias: 'w', network_id: NET }, sse)).toBe(false);
44
+ expect(isOnline({ alias: 'i', network_id: NET }, sse)).toBe(false);
45
+ expect(isOnline({ alias: 'o', network_id: NET }, sse)).toBe(false);
46
+ });
47
+
48
+ test('legacy alias-only SSE key still resolves (no network_id scoping)', () => {
49
+ const sse = { 'legacy-node': 1 };
50
+ // Older hubs (< v0.7) key sse_sessions by bare alias. presence
51
+ // falls back to bare-alias when scoped lookup misses.
52
+ expect(isOnline({ alias: 'legacy-node' }, sse)).toBe(true);
53
+ expect(isOnline({ alias: 'legacy-node', network_id: NET }, sse)).toBe(true);
54
+ expect(sseCountFor({ alias: 'legacy-node' }, sse)).toBe(1);
55
+ });
56
+
57
+ test('undefined sseSessions map → NOT online (fail-closed)', () => {
58
+ // If health hasn't loaded yet the map is undefined. Presence
59
+ // MUST fail-closed — treating undefined as "everyone online"
60
+ // would inflate the count during boot.
61
+ expect(isOnline({ alias: 'x', network_id: NET }, undefined)).toBe(false);
62
+ });
63
+
64
+ test('SSE value === 0 → NOT online (PR #52 round-2 finding 1)', () => {
65
+ // Older hubs may leave a zero-count entry in sse_sessions when the
66
+ // last connection dropped without cleanup. `!== undefined` would
67
+ // count this as online — inflating in exactly the direction #214 F2
68
+ // set out to eliminate. `> 0` is the SSE-reachable ground truth.
69
+ // page.tsx's old `!!sseLookup(s)` also treated 0 as false — so
70
+ // preserving `> 0` keeps this a pure refactor for that call site.
71
+ const sse = { [`${NET}:dead-edge`]: 0 };
72
+ expect(sseCountFor({ alias: 'dead-edge', network_id: NET }, sse)).toBe(0);
73
+ expect(isOnline({ alias: 'dead-edge', network_id: NET }, sse)).toBe(false);
74
+ });
75
+ });