@sleep2agi/agent-network-dashboard 0.4.6-preview.227 → 0.4.6-preview.229

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 (144) 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 +4 -4
  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.html +1 -1
  14. package/.next/server/app/_not-found.rsc +1 -1
  15. package/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  16. package/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  17. package/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  18. package/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  19. package/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  20. package/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  21. package/.next/server/app/admin.html +1 -1
  22. package/.next/server/app/admin.rsc +1 -1
  23. package/.next/server/app/admin.segments/_full.segment.rsc +1 -1
  24. package/.next/server/app/admin.segments/_head.segment.rsc +1 -1
  25. package/.next/server/app/admin.segments/_index.segment.rsc +1 -1
  26. package/.next/server/app/admin.segments/_tree.segment.rsc +1 -1
  27. package/.next/server/app/admin.segments/admin/__PAGE__.segment.rsc +1 -1
  28. package/.next/server/app/admin.segments/admin.segment.rsc +1 -1
  29. package/.next/server/app/index.html +2 -2
  30. package/.next/server/app/index.rsc +2 -2
  31. package/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  32. package/.next/server/app/index.segments/_full.segment.rsc +2 -2
  33. package/.next/server/app/index.segments/_head.segment.rsc +1 -1
  34. package/.next/server/app/index.segments/_index.segment.rsc +1 -1
  35. package/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  36. package/.next/server/app/login/page_client-reference-manifest.js +1 -1
  37. package/.next/server/app/login.html +2 -2
  38. package/.next/server/app/login.rsc +2 -2
  39. package/.next/server/app/login.segments/_full.segment.rsc +2 -2
  40. package/.next/server/app/login.segments/_head.segment.rsc +1 -1
  41. package/.next/server/app/login.segments/_index.segment.rsc +1 -1
  42. package/.next/server/app/login.segments/_tree.segment.rsc +1 -1
  43. package/.next/server/app/login.segments/login/__PAGE__.segment.rsc +2 -2
  44. package/.next/server/app/login.segments/login.segment.rsc +1 -1
  45. package/.next/server/app/logs.html +1 -1
  46. package/.next/server/app/logs.rsc +1 -1
  47. package/.next/server/app/logs.segments/_full.segment.rsc +1 -1
  48. package/.next/server/app/logs.segments/_head.segment.rsc +1 -1
  49. package/.next/server/app/logs.segments/_index.segment.rsc +1 -1
  50. package/.next/server/app/logs.segments/_tree.segment.rsc +1 -1
  51. package/.next/server/app/logs.segments/logs/__PAGE__.segment.rsc +1 -1
  52. package/.next/server/app/logs.segments/logs.segment.rsc +1 -1
  53. package/.next/server/app/messages.html +1 -1
  54. package/.next/server/app/messages.rsc +1 -1
  55. package/.next/server/app/messages.segments/_full.segment.rsc +1 -1
  56. package/.next/server/app/messages.segments/_head.segment.rsc +1 -1
  57. package/.next/server/app/messages.segments/_index.segment.rsc +1 -1
  58. package/.next/server/app/messages.segments/_tree.segment.rsc +1 -1
  59. package/.next/server/app/messages.segments/messages/__PAGE__.segment.rsc +1 -1
  60. package/.next/server/app/messages.segments/messages.segment.rsc +1 -1
  61. package/.next/server/app/node.html +1 -1
  62. package/.next/server/app/node.rsc +1 -1
  63. package/.next/server/app/node.segments/_full.segment.rsc +1 -1
  64. package/.next/server/app/node.segments/_head.segment.rsc +1 -1
  65. package/.next/server/app/node.segments/_index.segment.rsc +1 -1
  66. package/.next/server/app/node.segments/_tree.segment.rsc +1 -1
  67. package/.next/server/app/node.segments/node/__PAGE__.segment.rsc +1 -1
  68. package/.next/server/app/node.segments/node.segment.rsc +1 -1
  69. package/.next/server/app/nodes.html +1 -1
  70. package/.next/server/app/nodes.rsc +1 -1
  71. package/.next/server/app/nodes.segments/_full.segment.rsc +1 -1
  72. package/.next/server/app/nodes.segments/_head.segment.rsc +1 -1
  73. package/.next/server/app/nodes.segments/_index.segment.rsc +1 -1
  74. package/.next/server/app/nodes.segments/_tree.segment.rsc +1 -1
  75. package/.next/server/app/nodes.segments/nodes/__PAGE__.segment.rsc +1 -1
  76. package/.next/server/app/nodes.segments/nodes.segment.rsc +1 -1
  77. package/.next/server/app/page_client-reference-manifest.js +1 -1
  78. package/.next/server/app/server-logs.html +1 -1
  79. package/.next/server/app/server-logs.rsc +1 -1
  80. package/.next/server/app/server-logs.segments/_full.segment.rsc +1 -1
  81. package/.next/server/app/server-logs.segments/_head.segment.rsc +1 -1
  82. package/.next/server/app/server-logs.segments/_index.segment.rsc +1 -1
  83. package/.next/server/app/server-logs.segments/_tree.segment.rsc +1 -1
  84. package/.next/server/app/server-logs.segments/server-logs/__PAGE__.segment.rsc +1 -1
  85. package/.next/server/app/server-logs.segments/server-logs.segment.rsc +1 -1
  86. package/.next/server/app/settings/networks.html +1 -1
  87. package/.next/server/app/settings/networks.rsc +1 -1
  88. package/.next/server/app/settings/networks.segments/_full.segment.rsc +1 -1
  89. package/.next/server/app/settings/networks.segments/_head.segment.rsc +1 -1
  90. package/.next/server/app/settings/networks.segments/_index.segment.rsc +1 -1
  91. package/.next/server/app/settings/networks.segments/_tree.segment.rsc +1 -1
  92. package/.next/server/app/settings/networks.segments/settings/networks/__PAGE__.segment.rsc +1 -1
  93. package/.next/server/app/settings/networks.segments/settings/networks.segment.rsc +1 -1
  94. package/.next/server/app/settings/networks.segments/settings.segment.rsc +1 -1
  95. package/.next/server/app/settings/page_client-reference-manifest.js +1 -1
  96. package/.next/server/app/settings/tokens.html +1 -1
  97. package/.next/server/app/settings/tokens.rsc +1 -1
  98. package/.next/server/app/settings/tokens.segments/_full.segment.rsc +1 -1
  99. package/.next/server/app/settings/tokens.segments/_head.segment.rsc +1 -1
  100. package/.next/server/app/settings/tokens.segments/_index.segment.rsc +1 -1
  101. package/.next/server/app/settings/tokens.segments/_tree.segment.rsc +1 -1
  102. package/.next/server/app/settings/tokens.segments/settings/tokens/__PAGE__.segment.rsc +1 -1
  103. package/.next/server/app/settings/tokens.segments/settings/tokens.segment.rsc +1 -1
  104. package/.next/server/app/settings/tokens.segments/settings.segment.rsc +1 -1
  105. package/.next/server/app/settings.html +2 -2
  106. package/.next/server/app/settings.rsc +2 -2
  107. package/.next/server/app/settings.segments/_full.segment.rsc +2 -2
  108. package/.next/server/app/settings.segments/_head.segment.rsc +1 -1
  109. package/.next/server/app/settings.segments/_index.segment.rsc +1 -1
  110. package/.next/server/app/settings.segments/_tree.segment.rsc +1 -1
  111. package/.next/server/app/settings.segments/settings/__PAGE__.segment.rsc +2 -2
  112. package/.next/server/app/settings.segments/settings.segment.rsc +1 -1
  113. package/.next/server/app/tasks.html +1 -1
  114. package/.next/server/app/tasks.rsc +1 -1
  115. package/.next/server/app/tasks.segments/_full.segment.rsc +1 -1
  116. package/.next/server/app/tasks.segments/_head.segment.rsc +1 -1
  117. package/.next/server/app/tasks.segments/_index.segment.rsc +1 -1
  118. package/.next/server/app/tasks.segments/_tree.segment.rsc +1 -1
  119. package/.next/server/app/tasks.segments/tasks/__PAGE__.segment.rsc +1 -1
  120. package/.next/server/app/tasks.segments/tasks.segment.rsc +1 -1
  121. package/.next/server/chunks/ssr/agent-network-dashboard_09kk21a._.js +3 -3
  122. package/.next/server/chunks/ssr/agent-network-dashboard_09kk21a._.js.map +1 -1
  123. package/.next/server/chunks/ssr/agent-network-dashboard_app_01jhlxz._.js +1 -1
  124. package/.next/server/chunks/ssr/agent-network-dashboard_app_01jhlxz._.js.map +1 -1
  125. package/.next/server/chunks/ssr/agent-network-dashboard_app_09d29my._.js +1 -1
  126. package/.next/server/chunks/ssr/agent-network-dashboard_app_09d29my._.js.map +1 -1
  127. package/.next/server/middleware-build-manifest.js +3 -3
  128. package/.next/server/pages/404.html +1 -1
  129. package/.next/server/pages/500.html +1 -1
  130. package/.next/server/server-reference-manifest.js +1 -1
  131. package/.next/server/server-reference-manifest.json +1 -1
  132. package/.next/static/chunks/{0dnv70-le.ynp.js → 04b8uw3m8z.o0.js} +1 -1
  133. package/.next/static/chunks/{14kmndlu0zr28.js → 0a-7rsjiuvxcb.js} +1 -1
  134. package/.next/static/chunks/0mar.1q2zcc0x.js +4 -0
  135. package/.next/trace +2 -2
  136. package/.next/trace-build +1 -1
  137. package/app/components/TopoGraph.tsx +100 -75
  138. package/package.json +1 -1
  139. package/scripts/topo-empty-state-crossfade-test.mjs +130 -0
  140. package/scripts/topo-recent-panel-more-crossfade-test.mjs +124 -0
  141. package/.next/static/chunks/0i1dmt55~_6px.js +0 -4
  142. /package/.next/static/{7clyJLhqwt2II9G4eWIaj → BSaC8HgzaPhvOieeDUgr4}/_buildManifest.js +0 -0
  143. /package/.next/static/{7clyJLhqwt2II9G4eWIaj → BSaC8HgzaPhvOieeDUgr4}/_clientMiddlewareManifest.js +0 -0
  144. /package/.next/static/{7clyJLhqwt2II9G4eWIaj → BSaC8HgzaPhvOieeDUgr4}/_ssgManifest.js +0 -0
package/.next/trace CHANGED
@@ -1,2 +1,2 @@
1
- [{"name":"generate-buildid","duration":268,"timestamp":81723655481,"id":4,"parentId":1,"tags":{},"startTime":1778889695902,"traceId":"55c8e09de051c111"},{"name":"load-custom-routes","duration":510,"timestamp":81723655885,"id":5,"parentId":1,"tags":{},"startTime":1778889695902,"traceId":"55c8e09de051c111"},{"name":"create-dist-dir","duration":695,"timestamp":81723656442,"id":6,"parentId":1,"tags":{},"startTime":1778889695903,"traceId":"55c8e09de051c111"},{"name":"clean","duration":504,"timestamp":81723657744,"id":7,"parentId":1,"tags":{},"startTime":1778889695904,"traceId":"55c8e09de051c111"},{"name":"discover-routes","duration":11598,"timestamp":81723751500,"id":8,"parentId":1,"tags":{},"startTime":1778889695998,"traceId":"55c8e09de051c111"},{"name":"create-root-mapping","duration":144,"timestamp":81723763185,"id":9,"parentId":1,"tags":{},"startTime":1778889696009,"traceId":"55c8e09de051c111"},{"name":"generate-route-types","duration":34322,"timestamp":81723766480,"id":10,"parentId":1,"tags":{},"startTime":1778889696013,"traceId":"55c8e09de051c111"},{"name":"public-dir-conflict-check","duration":139,"timestamp":81723800972,"id":11,"parentId":1,"tags":{},"startTime":1778889696047,"traceId":"55c8e09de051c111"},{"name":"generate-routes-manifest","duration":5408,"timestamp":81723801234,"id":12,"parentId":1,"tags":{},"startTime":1778889696048,"traceId":"55c8e09de051c111"},{"name":"run-turbopack","duration":6768813,"timestamp":81723812881,"id":14,"parentId":1,"tags":{},"startTime":1778889696059,"traceId":"55c8e09de051c111"},{"name":"turbopack-build-events","duration":75,"timestamp":81724155110,"id":15,"parentId":1,"tags":{},"startTime":1778889696401,"traceId":"55c8e09de051c111"},{"name":"run-typescript","duration":8648602,"timestamp":81730593516,"id":16,"parentId":1,"tags":{},"startTime":1778889702840,"traceId":"55c8e09de051c111"},{"name":"generate-required-server-files","duration":1921,"timestamp":81739242965,"id":18,"parentId":1,"tags":{},"startTime":1778889711489,"traceId":"55c8e09de051c111"},{"name":"check-static-error-page","duration":13640,"timestamp":81739396383,"id":20,"parentId":19,"tags":{},"startTime":1778889711643,"traceId":"55c8e09de051c111"},{"name":"is-page-static","duration":491592,"timestamp":81739417238,"id":63,"parentId":22,"tags":{},"startTime":1778889711664,"traceId":"55c8e09de051c111"},{"name":"check-page","duration":509818,"timestamp":81739399139,"id":22,"parentId":19,"tags":{"page":"/_global-error"},"startTime":1778889711645,"traceId":"55c8e09de051c111"},{"name":"is-page-static","duration":549763,"timestamp":81739417683,"id":66,"parentId":27,"tags":{},"startTime":1778889711664,"traceId":"55c8e09de051c111"},{"name":"check-page","duration":563870,"timestamp":81739403671,"id":27,"parentId":19,"tags":{"page":"/api/auth/v3"},"startTime":1778889711650,"traceId":"55c8e09de051c111"},{"name":"is-page-static","duration":559611,"timestamp":81739418233,"id":68,"parentId":29,"tags":{},"startTime":1778889711665,"traceId":"55c8e09de051c111"},{"name":"check-page","duration":573963,"timestamp":81739403949,"id":29,"parentId":19,"tags":{"page":"/api/hub/auth"},"startTime":1778889711650,"traceId":"55c8e09de051c111"},{"name":"is-page-static","duration":564578,"timestamp":81739418622,"id":71,"parentId":33,"tags":{},"startTime":1778889711665,"traceId":"55c8e09de051c111"},{"name":"check-page","duration":578704,"timestamp":81739404560,"id":33,"parentId":19,"tags":{"page":"/api/hub/inbox"},"startTime":1778889711651,"traceId":"55c8e09de051c111"},{"name":"is-page-static","duration":565773,"timestamp":81739418056,"id":67,"parentId":28,"tags":{},"startTime":1778889711664,"traceId":"55c8e09de051c111"},{"name":"check-page","duration":580071,"timestamp":81739403820,"id":28,"parentId":19,"tags":{"page":"/api/hub/audit-log"},"startTime":1778889711650,"traceId":"55c8e09de051c111"},{"name":"is-page-static","duration":574171,"timestamp":81739417536,"id":65,"parentId":26,"tags":{},"startTime":1778889711664,"traceId":"55c8e09de051c111"},{"name":"check-page","duration":588963,"timestamp":81739402905,"id":26,"parentId":19,"tags":{"page":"/api/auth/logout"},"startTime":1778889711649,"traceId":"55c8e09de051c111"},{"name":"is-page-static","duration":577835,"timestamp":81739418547,"id":70,"parentId":32,"tags":{},"startTime":1778889711665,"traceId":"55c8e09de051c111"},{"name":"check-page","duration":591974,"timestamp":81739404461,"id":32,"parentId":19,"tags":{"page":"/api/hub/health"},"startTime":1778889711651,"traceId":"55c8e09de051c111"},{"name":"is-page-static","duration":578058,"timestamp":81739418849,"id":74,"parentId":36,"tags":{},"startTime":1778889711665,"traceId":"55c8e09de051c111"},{"name":"check-page","duration":591856,"timestamp":81739405093,"id":36,"parentId":19,"tags":{"page":"/api/hub/networks"},"startTime":1778889711651,"traceId":"55c8e09de051c111"},{"name":"is-page-static","duration":583268,"timestamp":81739417402,"id":64,"parentId":25,"tags":{},"startTime":1778889711664,"traceId":"55c8e09de051c111"},{"name":"check-page","duration":601018,"timestamp":81739401837,"id":25,"parentId":19,"tags":{"page":"/api/auth/login"},"startTime":1778889711648,"traceId":"55c8e09de051c111"},{"name":"is-page-static","duration":590630,"timestamp":81739412473,"id":62,"parentId":21,"tags":{},"startTime":1778889711659,"traceId":"55c8e09de051c111"},{"name":"check-page","duration":605274,"timestamp":81739397879,"id":21,"parentId":19,"tags":{"page":"/_not-found"},"startTime":1778889711644,"traceId":"55c8e09de051c111"},{"name":"is-page-static","duration":587907,"timestamp":81739418910,"id":77,"parentId":39,"tags":{},"startTime":1778889711665,"traceId":"55c8e09de051c111"},{"name":"check-page","duration":601474,"timestamp":81739405384,"id":39,"parentId":19,"tags":{"page":"/api/hub/send"},"startTime":1778889711652,"traceId":"55c8e09de051c111"},{"name":"is-page-static","duration":609128,"timestamp":81739418709,"id":72,"parentId":34,"tags":{},"startTime":1778889711665,"traceId":"55c8e09de051c111"},{"name":"check-page","duration":623241,"timestamp":81739404657,"id":34,"parentId":19,"tags":{"page":"/api/hub/license"},"startTime":1778889711651,"traceId":"55c8e09de051c111"},{"name":"is-page-static","duration":609827,"timestamp":81739418372,"id":69,"parentId":30,"tags":{},"startTime":1778889711665,"traceId":"55c8e09de051c111"},{"name":"check-page","duration":624101,"timestamp":81739404140,"id":30,"parentId":19,"tags":{"page":"/api/hub/broadcast"},"startTime":1778889711650,"traceId":"55c8e09de051c111"},{"name":"is-page-static","duration":609642,"timestamp":81739418737,"id":73,"parentId":35,"tags":{},"startTime":1778889711665,"traceId":"55c8e09de051c111"},{"name":"check-page","duration":623662,"timestamp":81739404743,"id":35,"parentId":19,"tags":{"page":"/api/hub/messages"},"startTime":1778889711651,"traceId":"55c8e09de051c111"},{"name":"is-page-static","duration":621007,"timestamp":81739418934,"id":79,"parentId":41,"tags":{},"startTime":1778889711665,"traceId":"55c8e09de051c111"},{"name":"check-page","duration":634462,"timestamp":81739405528,"id":41,"parentId":19,"tags":{"page":"/api/hub/servers"},"startTime":1778889711652,"traceId":"55c8e09de051c111"},{"name":"is-page-static","duration":621283,"timestamp":81739418898,"id":76,"parentId":38,"tags":{},"startTime":1778889711665,"traceId":"55c8e09de051c111"},{"name":"check-page","duration":634894,"timestamp":81739405318,"id":38,"parentId":19,"tags":{"page":"/api/hub/register"},"startTime":1778889711652,"traceId":"55c8e09de051c111"},{"name":"is-page-static","duration":624122,"timestamp":81739418946,"id":80,"parentId":42,"tags":{},"startTime":1778889711665,"traceId":"55c8e09de051c111"},{"name":"check-page","duration":637506,"timestamp":81739405615,"id":42,"parentId":19,"tags":{"page":"/api/hub/session"},"startTime":1778889711652,"traceId":"55c8e09de051c111"},{"name":"is-page-static","duration":627390,"timestamp":81739418883,"id":75,"parentId":37,"tags":{},"startTime":1778889711665,"traceId":"55c8e09de051c111"},{"name":"check-page","duration":641090,"timestamp":81739405220,"id":37,"parentId":19,"tags":{"page":"/api/hub/nodes"},"startTime":1778889711651,"traceId":"55c8e09de051c111"},{"name":"is-page-static","duration":628618,"timestamp":81739418957,"id":81,"parentId":43,"tags":{},"startTime":1778889711665,"traceId":"55c8e09de051c111"},{"name":"check-page","duration":641946,"timestamp":81739405686,"id":43,"parentId":19,"tags":{"page":"/api/hub/stats"},"startTime":1778889711652,"traceId":"55c8e09de051c111"},{"name":"is-page-static","duration":637362,"timestamp":81739419047,"id":86,"parentId":48,"tags":{},"startTime":1778889711665,"traceId":"55c8e09de051c111"},{"name":"check-page","duration":650328,"timestamp":81739406121,"id":48,"parentId":19,"tags":{"page":"/api/hub/tokens"},"startTime":1778889711652,"traceId":"55c8e09de051c111"},{"name":"is-page-static","duration":638328,"timestamp":81739418995,"id":84,"parentId":46,"tags":{},"startTime":1778889711665,"traceId":"55c8e09de051c111"},{"name":"check-page","duration":651474,"timestamp":81739405890,"id":46,"parentId":19,"tags":{"page":"/api/hub/tasks"},"startTime":1778889711652,"traceId":"55c8e09de051c111"},{"name":"is-page-static","duration":638885,"timestamp":81739418982,"id":83,"parentId":45,"tags":{},"startTime":1778889711665,"traceId":"55c8e09de051c111"},{"name":"check-page","duration":652084,"timestamp":81739405825,"id":45,"parentId":19,"tags":{"page":"/api/hub/task-events"},"startTime":1778889711652,"traceId":"55c8e09de051c111"},{"name":"is-page-static","duration":642485,"timestamp":81739419033,"id":85,"parentId":47,"tags":{},"startTime":1778889711665,"traceId":"55c8e09de051c111"},{"name":"check-page","duration":655578,"timestamp":81739405983,"id":47,"parentId":19,"tags":{"page":"/api/hub/tmux"},"startTime":1778889711652,"traceId":"55c8e09de051c111"},{"name":"is-page-static","duration":640011,"timestamp":81739422548,"id":88,"parentId":24,"tags":{},"startTime":1778889711669,"traceId":"55c8e09de051c111"},{"name":"check-page","duration":663061,"timestamp":81739399537,"id":24,"parentId":19,"tags":{"page":"/api/anet/config"},"startTime":1778889711646,"traceId":"55c8e09de051c111"},{"name":"is-page-static","duration":646630,"timestamp":81739418970,"id":82,"parentId":44,"tags":{},"startTime":1778889711665,"traceId":"55c8e09de051c111"},{"name":"check-page","duration":659899,"timestamp":81739405753,"id":44,"parentId":19,"tags":{"page":"/api/hub/status"},"startTime":1778889711652,"traceId":"55c8e09de051c111"},{"name":"is-page-static","duration":650417,"timestamp":81739423816,"id":89,"parentId":31,"tags":{},"startTime":1778889711670,"traceId":"55c8e09de051c111"},{"name":"check-page","duration":670034,"timestamp":81739404246,"id":31,"parentId":19,"tags":{"page":"/api/hub/events"},"startTime":1778889711651,"traceId":"55c8e09de051c111"},{"name":"is-page-static","duration":658621,"timestamp":81739418922,"id":78,"parentId":40,"tags":{},"startTime":1778889711665,"traceId":"55c8e09de051c111"},{"name":"check-page","duration":672128,"timestamp":81739405454,"id":40,"parentId":19,"tags":{"page":"/api/hub/server-logs"},"startTime":1778889711652,"traceId":"55c8e09de051c111"},{"name":"is-page-static","duration":660018,"timestamp":81739426691,"id":95,"parentId":54,"tags":{},"startTime":1778889711673,"traceId":"55c8e09de051c111"},{"name":"check-page","duration":679186,"timestamp":81739407567,"id":54,"parentId":19,"tags":{"page":"/nodes"},"startTime":1778889711654,"traceId":"55c8e09de051c111"},{"name":"is-page-static","duration":668502,"timestamp":81739419060,"id":87,"parentId":49,"tags":{},"startTime":1778889711665,"traceId":"55c8e09de051c111"},{"name":"check-page","duration":681388,"timestamp":81739406232,"id":49,"parentId":19,"tags":{"page":"/favicon.ico"},"startTime":1778889711653,"traceId":"55c8e09de051c111"},{"name":"is-page-static","duration":665041,"timestamp":81739426705,"id":96,"parentId":56,"tags":{},"startTime":1778889711673,"traceId":"55c8e09de051c111"},{"name":"check-page","duration":683300,"timestamp":81739408485,"id":56,"parentId":19,"tags":{"page":"/server-logs"},"startTime":1778889711655,"traceId":"55c8e09de051c111"},{"name":"is-page-static","duration":670036,"timestamp":81739426731,"id":98,"parentId":59,"tags":{},"startTime":1778889711673,"traceId":"55c8e09de051c111"},{"name":"check-page","duration":687342,"timestamp":81739409473,"id":59,"parentId":19,"tags":{"page":"/settings/tokens"},"startTime":1778889711656,"traceId":"55c8e09de051c111"},{"name":"is-page-static","duration":680418,"timestamp":81739426751,"id":99,"parentId":60,"tags":{},"startTime":1778889711673,"traceId":"55c8e09de051c111"},{"name":"check-page","duration":697578,"timestamp":81739409644,"id":60,"parentId":19,"tags":{"page":"/tasks/[id]"},"startTime":1778889711656,"traceId":"55c8e09de051c111"},{"name":"is-page-static","duration":692972,"timestamp":81739426769,"id":100,"parentId":61,"tags":{},"startTime":1778889711673,"traceId":"55c8e09de051c111"},{"name":"check-page","duration":710043,"timestamp":81739409778,"id":61,"parentId":19,"tags":{"page":"/tasks"},"startTime":1778889711656,"traceId":"55c8e09de051c111"},{"name":"is-page-static","duration":697741,"timestamp":81739426633,"id":91,"parentId":50,"tags":{},"startTime":1778889711673,"traceId":"55c8e09de051c111"},{"name":"check-page","duration":717783,"timestamp":81739406653,"id":50,"parentId":19,"tags":{"page":"/login"},"startTime":1778889711653,"traceId":"55c8e09de051c111"},{"name":"is-page-static","duration":702649,"timestamp":81739426588,"id":90,"parentId":23,"tags":{},"startTime":1778889711673,"traceId":"55c8e09de051c111"},{"name":"check-page","duration":729936,"timestamp":81739399348,"id":23,"parentId":19,"tags":{"page":"/admin"},"startTime":1778889711646,"traceId":"55c8e09de051c111"},{"name":"is-page-static","duration":703844,"timestamp":81739426677,"id":94,"parentId":53,"tags":{},"startTime":1778889711673,"traceId":"55c8e09de051c111"},{"name":"check-page","duration":723239,"timestamp":81739407315,"id":53,"parentId":19,"tags":{"page":"/node"},"startTime":1778889711654,"traceId":"55c8e09de051c111"},{"name":"is-page-static","duration":699362,"timestamp":81739433764,"id":101,"parentId":58,"tags":{},"startTime":1778889711680,"traceId":"55c8e09de051c111"},{"name":"check-page","duration":724152,"timestamp":81739409015,"id":58,"parentId":19,"tags":{"page":"/settings"},"startTime":1778889711655,"traceId":"55c8e09de051c111"},{"name":"is-page-static","duration":685412,"timestamp":81739450399,"id":102,"parentId":55,"tags":{},"startTime":1778889711697,"traceId":"55c8e09de051c111"},{"name":"check-page","duration":728018,"timestamp":81739407837,"id":55,"parentId":19,"tags":{"page":"/"},"startTime":1778889711654,"traceId":"55c8e09de051c111"},{"name":"is-page-static","duration":710682,"timestamp":81739426648,"id":92,"parentId":51,"tags":{},"startTime":1778889711673,"traceId":"55c8e09de051c111"},{"name":"check-page","duration":730515,"timestamp":81739406846,"id":51,"parentId":19,"tags":{"page":"/logs"},"startTime":1778889711653,"traceId":"55c8e09de051c111"},{"name":"is-page-static","duration":718189,"timestamp":81739426663,"id":93,"parentId":52,"tags":{},"startTime":1778889711673,"traceId":"55c8e09de051c111"},{"name":"check-page","duration":737837,"timestamp":81739407057,"id":52,"parentId":19,"tags":{"page":"/messages"},"startTime":1778889711653,"traceId":"55c8e09de051c111"},{"name":"is-page-static","duration":720640,"timestamp":81739426718,"id":97,"parentId":57,"tags":{},"startTime":1778889711673,"traceId":"55c8e09de051c111"},{"name":"check-page","duration":738642,"timestamp":81739408752,"id":57,"parentId":19,"tags":{"page":"/settings/networks"},"startTime":1778889711655,"traceId":"55c8e09de051c111"},{"name":"static-check","duration":751708,"timestamp":81739395716,"id":19,"parentId":1,"tags":{},"startTime":1778889711642,"traceId":"55c8e09de051c111"},{"name":"write-routes-manifest","duration":429,"timestamp":81740153824,"id":104,"parentId":1,"tags":{},"startTime":1778889712400,"traceId":"55c8e09de051c111"},{"name":"load-dotenv","duration":56,"timestamp":81740166467,"id":107,"parentId":106,"tags":{},"startTime":1778889712413,"traceId":"55c8e09de051c111"},{"name":"run-export-path-map","duration":911,"timestamp":81740170428,"id":108,"parentId":106,"tags":{},"startTime":1778889712417,"traceId":"55c8e09de051c111"},{"name":"next-export","duration":562463,"timestamp":81740165126,"id":106,"parentId":1,"tags":{},"startTime":1778889712411,"traceId":"55c8e09de051c111"}]
2
- [{"name":"move-exported-app-not-found-","duration":2539,"timestamp":81740731879,"id":109,"parentId":105,"tags":{},"startTime":1778889712978,"traceId":"55c8e09de051c111"},{"name":"move-exported-app-global-error-","duration":966,"timestamp":81740734496,"id":110,"parentId":105,"tags":{},"startTime":1778889712981,"traceId":"55c8e09de051c111"},{"name":"static-generation","duration":578468,"timestamp":81740158707,"id":105,"parentId":1,"tags":{},"startTime":1778889712405,"traceId":"55c8e09de051c111"},{"name":"write-routes-manifest","duration":393,"timestamp":81740737320,"id":111,"parentId":1,"tags":{},"startTime":1778889712984,"traceId":"55c8e09de051c111"},{"name":"print-tree-view","duration":4785,"timestamp":81740754977,"id":112,"parentId":1,"tags":{},"startTime":1778889713001,"traceId":"55c8e09de051c111"},{"name":"write-route-bundle-stats","duration":13012,"timestamp":81740759797,"id":113,"parentId":1,"tags":{},"startTime":1778889713006,"traceId":"55c8e09de051c111"},{"name":"telemetry-flush","duration":18436,"timestamp":81740772833,"id":114,"parentId":1,"tags":{},"startTime":1778889713019,"traceId":"55c8e09de051c111"},{"name":"next-build","duration":17192545,"timestamp":81723598748,"id":1,"tags":{"buildMode":"default","version":"16.2.3","bundler":"turbopack","has-custom-webpack-config":"false","use-build-worker":"true"},"startTime":1778889695845,"traceId":"55c8e09de051c111"}]
1
+ [{"name":"generate-buildid","duration":268,"timestamp":82540417158,"id":4,"parentId":1,"tags":{},"startTime":1778890512663,"traceId":"09580bb2fe232cd4"},{"name":"load-custom-routes","duration":482,"timestamp":82540417569,"id":5,"parentId":1,"tags":{},"startTime":1778890512664,"traceId":"09580bb2fe232cd4"},{"name":"create-dist-dir","duration":596,"timestamp":82540418095,"id":6,"parentId":1,"tags":{},"startTime":1778890512664,"traceId":"09580bb2fe232cd4"},{"name":"clean","duration":430,"timestamp":82540419325,"id":7,"parentId":1,"tags":{},"startTime":1778890512666,"traceId":"09580bb2fe232cd4"},{"name":"discover-routes","duration":8772,"timestamp":82540501399,"id":8,"parentId":1,"tags":{},"startTime":1778890512748,"traceId":"09580bb2fe232cd4"},{"name":"create-root-mapping","duration":105,"timestamp":82540510227,"id":9,"parentId":1,"tags":{},"startTime":1778890512757,"traceId":"09580bb2fe232cd4"},{"name":"generate-route-types","duration":38609,"timestamp":82540512479,"id":10,"parentId":1,"tags":{},"startTime":1778890512759,"traceId":"09580bb2fe232cd4"},{"name":"public-dir-conflict-check","duration":134,"timestamp":82540551292,"id":11,"parentId":1,"tags":{},"startTime":1778890512798,"traceId":"09580bb2fe232cd4"},{"name":"generate-routes-manifest","duration":4854,"timestamp":82540551552,"id":12,"parentId":1,"tags":{},"startTime":1778890512798,"traceId":"09580bb2fe232cd4"},{"name":"run-turbopack","duration":5980560,"timestamp":82540562427,"id":14,"parentId":1,"tags":{},"startTime":1778890512809,"traceId":"09580bb2fe232cd4"},{"name":"turbopack-build-events","duration":105,"timestamp":82540852384,"id":15,"parentId":1,"tags":{},"startTime":1778890513099,"traceId":"09580bb2fe232cd4"},{"name":"run-typescript","duration":10674884,"timestamp":82546558375,"id":16,"parentId":1,"tags":{},"startTime":1778890518805,"traceId":"09580bb2fe232cd4"},{"name":"generate-required-server-files","duration":3153,"timestamp":82557234683,"id":18,"parentId":1,"tags":{},"startTime":1778890529481,"traceId":"09580bb2fe232cd4"},{"name":"check-static-error-page","duration":16127,"timestamp":82557458284,"id":20,"parentId":19,"tags":{},"startTime":1778890529705,"traceId":"09580bb2fe232cd4"},{"name":"is-page-static","duration":659798,"timestamp":82557478660,"id":63,"parentId":22,"tags":{},"startTime":1778890529725,"traceId":"09580bb2fe232cd4"},{"name":"check-page","duration":677081,"timestamp":82557461546,"id":22,"parentId":19,"tags":{"page":"/_global-error"},"startTime":1778890529708,"traceId":"09580bb2fe232cd4"},{"name":"is-page-static","duration":749501,"timestamp":82557478374,"id":62,"parentId":21,"tags":{},"startTime":1778890529725,"traceId":"09580bb2fe232cd4"},{"name":"check-page","duration":768063,"timestamp":82557459913,"id":21,"parentId":19,"tags":{"page":"/_not-found"},"startTime":1778890529706,"traceId":"09580bb2fe232cd4"},{"name":"is-page-static","duration":823242,"timestamp":82557484487,"id":70,"parentId":32,"tags":{},"startTime":1778890529731,"traceId":"09580bb2fe232cd4"},{"name":"check-page","duration":841571,"timestamp":82557466237,"id":32,"parentId":19,"tags":{"page":"/api/hub/health"},"startTime":1778890529713,"traceId":"09580bb2fe232cd4"},{"name":"is-page-static","duration":826357,"timestamp":82557483528,"id":69,"parentId":30,"tags":{},"startTime":1778890529730,"traceId":"09580bb2fe232cd4"},{"name":"check-page","duration":844174,"timestamp":82557465767,"id":30,"parentId":19,"tags":{"page":"/api/hub/broadcast"},"startTime":1778890529712,"traceId":"09580bb2fe232cd4"},{"name":"is-page-static","duration":832168,"timestamp":82557484717,"id":72,"parentId":34,"tags":{},"startTime":1778890529731,"traceId":"09580bb2fe232cd4"},{"name":"check-page","duration":850410,"timestamp":82557466537,"id":34,"parentId":19,"tags":{"page":"/api/hub/license"},"startTime":1778890529713,"traceId":"09580bb2fe232cd4"},{"name":"is-page-static","duration":836611,"timestamp":82557484579,"id":71,"parentId":33,"tags":{},"startTime":1778890529731,"traceId":"09580bb2fe232cd4"},{"name":"check-page","duration":854848,"timestamp":82557466394,"id":33,"parentId":19,"tags":{"page":"/api/hub/inbox"},"startTime":1778890529713,"traceId":"09580bb2fe232cd4"},{"name":"is-page-static","duration":841390,"timestamp":82557484890,"id":74,"parentId":36,"tags":{},"startTime":1778890529731,"traceId":"09580bb2fe232cd4"},{"name":"check-page","duration":859101,"timestamp":82557467234,"id":36,"parentId":19,"tags":{"page":"/api/hub/networks"},"startTime":1778890529714,"traceId":"09580bb2fe232cd4"},{"name":"is-page-static","duration":847467,"timestamp":82557484930,"id":75,"parentId":37,"tags":{},"startTime":1778890529731,"traceId":"09580bb2fe232cd4"},{"name":"check-page","duration":865014,"timestamp":82557467431,"id":37,"parentId":19,"tags":{"page":"/api/hub/nodes"},"startTime":1778890529714,"traceId":"09580bb2fe232cd4"},{"name":"is-page-static","duration":850495,"timestamp":82557484949,"id":76,"parentId":38,"tags":{},"startTime":1778890529731,"traceId":"09580bb2fe232cd4"},{"name":"check-page","duration":867905,"timestamp":82557467596,"id":38,"parentId":19,"tags":{"page":"/api/hub/register"},"startTime":1778890529714,"traceId":"09580bb2fe232cd4"},{"name":"is-page-static","duration":852337,"timestamp":82557484755,"id":73,"parentId":35,"tags":{},"startTime":1778890529731,"traceId":"09580bb2fe232cd4"},{"name":"check-page","duration":870454,"timestamp":82557466685,"id":35,"parentId":19,"tags":{"page":"/api/hub/messages"},"startTime":1778890529713,"traceId":"09580bb2fe232cd4"},{"name":"is-page-static","duration":854807,"timestamp":82557484959,"id":77,"parentId":39,"tags":{},"startTime":1778890529731,"traceId":"09580bb2fe232cd4"},{"name":"check-page","duration":872096,"timestamp":82557467715,"id":39,"parentId":19,"tags":{"page":"/api/hub/send"},"startTime":1778890529714,"traceId":"09580bb2fe232cd4"},{"name":"is-page-static","duration":858151,"timestamp":82557484973,"id":78,"parentId":40,"tags":{},"startTime":1778890529731,"traceId":"09580bb2fe232cd4"},{"name":"check-page","duration":876463,"timestamp":82557467827,"id":40,"parentId":19,"tags":{"page":"/api/hub/server-logs"},"startTime":1778890529714,"traceId":"09580bb2fe232cd4"},{"name":"is-page-static","duration":859509,"timestamp":82557484985,"id":79,"parentId":41,"tags":{},"startTime":1778890529731,"traceId":"09580bb2fe232cd4"},{"name":"check-page","duration":876585,"timestamp":82557467955,"id":41,"parentId":19,"tags":{"page":"/api/hub/servers"},"startTime":1778890529714,"traceId":"09580bb2fe232cd4"},{"name":"is-page-static","duration":869879,"timestamp":82557479329,"id":66,"parentId":27,"tags":{},"startTime":1778890529726,"traceId":"09580bb2fe232cd4"},{"name":"check-page","duration":883989,"timestamp":82557465260,"id":27,"parentId":19,"tags":{"page":"/api/auth/v3"},"startTime":1778890529712,"traceId":"09580bb2fe232cd4"},{"name":"is-page-static","duration":864703,"timestamp":82557484998,"id":80,"parentId":42,"tags":{},"startTime":1778890529731,"traceId":"09580bb2fe232cd4"},{"name":"check-page","duration":881631,"timestamp":82557468108,"id":42,"parentId":19,"tags":{"page":"/api/hub/session"},"startTime":1778890529714,"traceId":"09580bb2fe232cd4"},{"name":"is-page-static","duration":864888,"timestamp":82557485024,"id":81,"parentId":43,"tags":{},"startTime":1778890529731,"traceId":"09580bb2fe232cd4"},{"name":"check-page","duration":881713,"timestamp":82557468233,"id":43,"parentId":19,"tags":{"page":"/api/hub/stats"},"startTime":1778890529715,"traceId":"09580bb2fe232cd4"},{"name":"is-page-static","duration":870650,"timestamp":82557485038,"id":82,"parentId":44,"tags":{},"startTime":1778890529731,"traceId":"09580bb2fe232cd4"},{"name":"check-page","duration":887392,"timestamp":82557468341,"id":44,"parentId":19,"tags":{"page":"/api/hub/status"},"startTime":1778890529715,"traceId":"09580bb2fe232cd4"},{"name":"is-page-static","duration":871559,"timestamp":82557485063,"id":84,"parentId":46,"tags":{},"startTime":1778890529731,"traceId":"09580bb2fe232cd4"},{"name":"check-page","duration":886181,"timestamp":82557470482,"id":46,"parentId":19,"tags":{"page":"/api/hub/tasks"},"startTime":1778890529717,"traceId":"09580bb2fe232cd4"},{"name":"is-page-static","duration":873263,"timestamp":82557485053,"id":83,"parentId":45,"tags":{},"startTime":1778890529731,"traceId":"09580bb2fe232cd4"},{"name":"check-page","duration":889903,"timestamp":82557468453,"id":45,"parentId":19,"tags":{"page":"/api/hub/task-events"},"startTime":1778890529715,"traceId":"09580bb2fe232cd4"},{"name":"is-page-static","duration":876017,"timestamp":82557485090,"id":86,"parentId":48,"tags":{},"startTime":1778890529731,"traceId":"09580bb2fe232cd4"},{"name":"check-page","duration":890338,"timestamp":82557470814,"id":48,"parentId":19,"tags":{"page":"/api/hub/tokens"},"startTime":1778890529717,"traceId":"09580bb2fe232cd4"},{"name":"is-page-static","duration":872184,"timestamp":82557497877,"id":88,"parentId":24,"tags":{},"startTime":1778890529744,"traceId":"09580bb2fe232cd4"},{"name":"check-page","duration":907978,"timestamp":82557462134,"id":24,"parentId":19,"tags":{"page":"/api/anet/config"},"startTime":1778890529708,"traceId":"09580bb2fe232cd4"},{"name":"is-page-static","duration":871760,"timestamp":82557499115,"id":89,"parentId":31,"tags":{},"startTime":1778890529745,"traceId":"09580bb2fe232cd4"},{"name":"check-page","duration":904987,"timestamp":82557465932,"id":31,"parentId":19,"tags":{"page":"/api/hub/events"},"startTime":1778890529712,"traceId":"09580bb2fe232cd4"},{"name":"is-page-static","duration":892470,"timestamp":82557478741,"id":64,"parentId":25,"tags":{},"startTime":1778890529725,"traceId":"09580bb2fe232cd4"},{"name":"check-page","duration":906328,"timestamp":82557464925,"id":25,"parentId":19,"tags":{"page":"/api/auth/login"},"startTime":1778890529711,"traceId":"09580bb2fe232cd4"},{"name":"is-page-static","duration":867976,"timestamp":82557510785,"id":90,"parentId":23,"tags":{},"startTime":1778890529757,"traceId":"09580bb2fe232cd4"},{"name":"check-page","duration":916980,"timestamp":82557461835,"id":23,"parentId":19,"tags":{"page":"/admin"},"startTime":1778890529708,"traceId":"09580bb2fe232cd4"},{"name":"is-page-static","duration":874955,"timestamp":82557510858,"id":92,"parentId":51,"tags":{},"startTime":1778890529757,"traceId":"09580bb2fe232cd4"},{"name":"check-page","duration":914294,"timestamp":82557471584,"id":51,"parentId":19,"tags":{"page":"/logs"},"startTime":1778890529718,"traceId":"09580bb2fe232cd4"},{"name":"is-page-static","duration":885821,"timestamp":82557510873,"id":93,"parentId":52,"tags":{},"startTime":1778890529757,"traceId":"09580bb2fe232cd4"},{"name":"check-page","duration":924986,"timestamp":82557471763,"id":52,"parentId":19,"tags":{"page":"/messages"},"startTime":1778890529718,"traceId":"09580bb2fe232cd4"},{"name":"is-page-static","duration":920043,"timestamp":82557485103,"id":87,"parentId":49,"tags":{},"startTime":1778890529731,"traceId":"09580bb2fe232cd4"},{"name":"check-page","duration":934273,"timestamp":82557470938,"id":49,"parentId":19,"tags":{"page":"/favicon.ico"},"startTime":1778890529717,"traceId":"09580bb2fe232cd4"},{"name":"is-page-static","duration":920276,"timestamp":82557485077,"id":85,"parentId":47,"tags":{},"startTime":1778890529731,"traceId":"09580bb2fe232cd4"},{"name":"check-page","duration":934697,"timestamp":82557470689,"id":47,"parentId":19,"tags":{"page":"/api/hub/tmux"},"startTime":1778890529717,"traceId":"09580bb2fe232cd4"},{"name":"is-page-static","duration":930942,"timestamp":82557479166,"id":65,"parentId":26,"tags":{},"startTime":1778890529725,"traceId":"09580bb2fe232cd4"},{"name":"check-page","duration":945040,"timestamp":82557465117,"id":26,"parentId":19,"tags":{"page":"/api/auth/logout"},"startTime":1778890529711,"traceId":"09580bb2fe232cd4"},{"name":"is-page-static","duration":913187,"timestamp":82557510886,"id":94,"parentId":53,"tags":{},"startTime":1778890529757,"traceId":"09580bb2fe232cd4"},{"name":"check-page","duration":952138,"timestamp":82557471998,"id":53,"parentId":19,"tags":{"page":"/node"},"startTime":1778890529718,"traceId":"09580bb2fe232cd4"},{"name":"is-page-static","duration":929152,"timestamp":82557510935,"id":98,"parentId":59,"tags":{},"startTime":1778890529757,"traceId":"09580bb2fe232cd4"},{"name":"check-page","duration":966317,"timestamp":82557473836,"id":59,"parentId":19,"tags":{"page":"/settings/tokens"},"startTime":1778890529720,"traceId":"09580bb2fe232cd4"},{"name":"is-page-static","duration":943674,"timestamp":82557510949,"id":99,"parentId":60,"tags":{},"startTime":1778890529757,"traceId":"09580bb2fe232cd4"},{"name":"check-page","duration":980702,"timestamp":82557473994,"id":60,"parentId":19,"tags":{"page":"/tasks/[id]"},"startTime":1778890529720,"traceId":"09580bb2fe232cd4"},{"name":"is-page-static","duration":951153,"timestamp":82557510967,"id":100,"parentId":61,"tags":{},"startTime":1778890529757,"traceId":"09580bb2fe232cd4"},{"name":"check-page","duration":988037,"timestamp":82557474161,"id":61,"parentId":19,"tags":{"page":"/tasks"},"startTime":1778890529720,"traceId":"09580bb2fe232cd4"},{"name":"is-page-static","duration":914944,"timestamp":82557554232,"id":101,"parentId":55,"tags":{},"startTime":1778890529801,"traceId":"09580bb2fe232cd4"},{"name":"check-page","duration":996743,"timestamp":82557472494,"id":55,"parentId":19,"tags":{"page":"/"},"startTime":1778890529719,"traceId":"09580bb2fe232cd4"},{"name":"is-page-static","duration":960970,"timestamp":82557510895,"id":95,"parentId":54,"tags":{},"startTime":1778890529757,"traceId":"09580bb2fe232cd4"},{"name":"check-page","duration":999670,"timestamp":82557472247,"id":54,"parentId":19,"tags":{"page":"/nodes"},"startTime":1778890529719,"traceId":"09580bb2fe232cd4"},{"name":"is-page-static","duration":906791,"timestamp":82557569431,"id":102,"parentId":58,"tags":{},"startTime":1778890529816,"traceId":"09580bb2fe232cd4"},{"name":"check-page","duration":1002804,"timestamp":82557473477,"id":58,"parentId":19,"tags":{"page":"/settings"},"startTime":1778890529720,"traceId":"09580bb2fe232cd4"},{"name":"is-page-static","duration":1002729,"timestamp":82557483185,"id":67,"parentId":28,"tags":{},"startTime":1778890529729,"traceId":"09580bb2fe232cd4"},{"name":"check-page","duration":1020562,"timestamp":82557465411,"id":28,"parentId":19,"tags":{"page":"/api/hub/audit-log"},"startTime":1778890529712,"traceId":"09580bb2fe232cd4"},{"name":"is-page-static","duration":994488,"timestamp":82557510909,"id":96,"parentId":56,"tags":{},"startTime":1778890529757,"traceId":"09580bb2fe232cd4"},{"name":"check-page","duration":1032407,"timestamp":82557473060,"id":56,"parentId":19,"tags":{"page":"/server-logs"},"startTime":1778890529719,"traceId":"09580bb2fe232cd4"},{"name":"is-page-static","duration":997371,"timestamp":82557510832,"id":91,"parentId":50,"tags":{},"startTime":1778890529757,"traceId":"09580bb2fe232cd4"},{"name":"check-page","duration":1036873,"timestamp":82557471394,"id":50,"parentId":19,"tags":{"page":"/login"},"startTime":1778890529718,"traceId":"09580bb2fe232cd4"},{"name":"is-page-static","duration":1027043,"timestamp":82557483374,"id":68,"parentId":29,"tags":{},"startTime":1778890529730,"traceId":"09580bb2fe232cd4"},{"name":"check-page","duration":1044945,"timestamp":82557465588,"id":29,"parentId":19,"tags":{"page":"/api/hub/auth"},"startTime":1778890529712,"traceId":"09580bb2fe232cd4"},{"name":"is-page-static","duration":1014472,"timestamp":82557510922,"id":97,"parentId":57,"tags":{},"startTime":1778890529757,"traceId":"09580bb2fe232cd4"},{"name":"check-page","duration":1052173,"timestamp":82557473277,"id":57,"parentId":19,"tags":{"page":"/settings/networks"},"startTime":1778890529720,"traceId":"09580bb2fe232cd4"},{"name":"static-check","duration":1068405,"timestamp":82557457102,"id":19,"parentId":1,"tags":{},"startTime":1778890529703,"traceId":"09580bb2fe232cd4"},{"name":"write-routes-manifest","duration":694,"timestamp":82558538223,"id":104,"parentId":1,"tags":{},"startTime":1778890530785,"traceId":"09580bb2fe232cd4"},{"name":"load-dotenv","duration":65,"timestamp":82558551716,"id":107,"parentId":106,"tags":{},"startTime":1778890530798,"traceId":"09580bb2fe232cd4"},{"name":"run-export-path-map","duration":573,"timestamp":82558554384,"id":108,"parentId":106,"tags":{},"startTime":1778890530801,"traceId":"09580bb2fe232cd4"},{"name":"next-export","duration":670661,"timestamp":82558550314,"id":106,"parentId":1,"tags":{},"startTime":1778890530797,"traceId":"09580bb2fe232cd4"}]
2
+ [{"name":"move-exported-app-not-found-","duration":3250,"timestamp":82559225394,"id":109,"parentId":105,"tags":{},"startTime":1778890531472,"traceId":"09580bb2fe232cd4"},{"name":"move-exported-app-global-error-","duration":854,"timestamp":82559228743,"id":110,"parentId":105,"tags":{},"startTime":1778890531475,"traceId":"09580bb2fe232cd4"},{"name":"static-generation","duration":687717,"timestamp":82558543790,"id":105,"parentId":1,"tags":{},"startTime":1778890530790,"traceId":"09580bb2fe232cd4"},{"name":"write-routes-manifest","duration":553,"timestamp":82559231677,"id":111,"parentId":1,"tags":{},"startTime":1778890531478,"traceId":"09580bb2fe232cd4"},{"name":"print-tree-view","duration":5266,"timestamp":82559252120,"id":112,"parentId":1,"tags":{},"startTime":1778890531498,"traceId":"09580bb2fe232cd4"},{"name":"write-route-bundle-stats","duration":18638,"timestamp":82559257425,"id":113,"parentId":1,"tags":{},"startTime":1778890531504,"traceId":"09580bb2fe232cd4"},{"name":"telemetry-flush","duration":15245,"timestamp":82559276102,"id":114,"parentId":1,"tags":{},"startTime":1778890531522,"traceId":"09580bb2fe232cd4"},{"name":"next-build","duration":18925819,"timestamp":82540365563,"id":1,"tags":{"buildMode":"default","version":"16.2.3","bundler":"turbopack","has-custom-webpack-config":"false","use-build-worker":"true"},"startTime":1778890512612,"traceId":"09580bb2fe232cd4"}]
package/.next/trace-build CHANGED
@@ -1 +1 @@
1
- [{"name":"run-turbopack","duration":6768813,"timestamp":81723812881,"id":14,"parentId":1,"tags":{},"startTime":1778889696059,"traceId":"55c8e09de051c111"},{"name":"turbopack-build-events","duration":75,"timestamp":81724155110,"id":15,"parentId":1,"tags":{},"startTime":1778889696401,"traceId":"55c8e09de051c111"},{"name":"run-typescript","duration":8648602,"timestamp":81730593516,"id":16,"parentId":1,"tags":{},"startTime":1778889702840,"traceId":"55c8e09de051c111"},{"name":"static-check","duration":751708,"timestamp":81739395716,"id":19,"parentId":1,"tags":{},"startTime":1778889711642,"traceId":"55c8e09de051c111"},{"name":"static-generation","duration":578468,"timestamp":81740158707,"id":105,"parentId":1,"tags":{},"startTime":1778889712405,"traceId":"55c8e09de051c111"},{"name":"telemetry-flush","duration":18436,"timestamp":81740772833,"id":114,"parentId":1,"tags":{},"startTime":1778889713019,"traceId":"55c8e09de051c111"},{"name":"next-build","duration":17192545,"timestamp":81723598748,"id":1,"tags":{"buildMode":"default","version":"16.2.3","bundler":"turbopack","has-custom-webpack-config":"false","use-build-worker":"true"},"startTime":1778889695845,"traceId":"55c8e09de051c111"}]
1
+ [{"name":"run-turbopack","duration":5980560,"timestamp":82540562427,"id":14,"parentId":1,"tags":{},"startTime":1778890512809,"traceId":"09580bb2fe232cd4"},{"name":"turbopack-build-events","duration":105,"timestamp":82540852384,"id":15,"parentId":1,"tags":{},"startTime":1778890513099,"traceId":"09580bb2fe232cd4"},{"name":"run-typescript","duration":10674884,"timestamp":82546558375,"id":16,"parentId":1,"tags":{},"startTime":1778890518805,"traceId":"09580bb2fe232cd4"},{"name":"static-check","duration":1068405,"timestamp":82557457102,"id":19,"parentId":1,"tags":{},"startTime":1778890529703,"traceId":"09580bb2fe232cd4"},{"name":"static-generation","duration":687717,"timestamp":82558543790,"id":105,"parentId":1,"tags":{},"startTime":1778890530790,"traceId":"09580bb2fe232cd4"},{"name":"telemetry-flush","duration":15245,"timestamp":82559276102,"id":114,"parentId":1,"tags":{},"startTime":1778890531522,"traceId":"09580bb2fe232cd4"},{"name":"next-build","duration":18925819,"timestamp":82540365563,"id":1,"tags":{"buildMode":"default","version":"16.2.3","bundler":"turbopack","has-custom-webpack-config":"false","use-build-worker":"true"},"startTime":1778890512612,"traceId":"09580bb2fe232cd4"}]
@@ -4793,72 +4793,74 @@ export function TopoGraph({ sessions, sseSessions, renameSignal }: TopoGraphProp
4793
4793
  deliberate. Messages count CAN diverge from flowLinks
4794
4794
  count (raw count vs. deduped pairs), so the placeholder
4795
4795
  fires on flowLinks.length=0 specifically. */}
4796
- {flowLinks.length === 0 ? (
4797
- /* R45 placeholder. R110: add a sub-text hint so the
4798
- empty state explains what it's empty OF — operators
4799
- looking at "no flow yet" sometimes mistook it for
4800
- a connection error. The sub-line reads as a quiet
4801
- invitation, not an error. Two-line layout uses
4802
- standard SVG <text>+<text> rather than tspan so the
4803
- y-coordinates are explicit and the data-attr selector
4804
- still finds the primary line.
4796
+ {/* Round 222 / Loop: empty state always-mounts; visibility
4797
+ crossfades via wrapper <g> opacity instead of conditional
4798
+ mount/unmount on flowLinks.length === 0. Pre-R222 the
4799
+ first flow arriving snap-removed the empty state in one
4800
+ frame while R203 rows simultaneously faded IN — half-
4801
+ smooth, half-snap on this "first data" first-impression
4802
+ moment. R222 closes the snap so empty fades OUT while
4803
+ rows fade IN — a proper crossfade for the user's most
4804
+ emotionally-loaded moment (the empty-to-populated flip).
4805
4805
 
4806
- Round 200 / Loop · milestone: empty-state lines now
4807
- breathe in opacity. Pre-R200 the two texts sat at
4808
- fixed 0.65 / 0.45 — visually identical to "frozen"
4809
- or "broken". A slow 4.4s in-out breath (peak just
4810
- above resting, trough just below) says "waiting,
4811
- listening". Pacing matches R84 idle-hub breath at
4812
- the slow end of its workingCount=0 cycle, so the
4813
- two empty-state surfaces (hub centre + panel
4814
- placeholder) share rhythm; when the first message
4815
- arrives, both surfaces become non-empty in sync.
4816
- Reduced-motion users see the resting opacity only
4817
- (SMIL is gated to !reducedMotion, same idiom every
4818
- other ambient animation uses). Negative `begin`
4819
- phase-shifts the sub-line 1.5s behind the main
4820
- line so the two read as a gentle inhale-exhale
4821
- instead of a single double-loud pulse. */
4822
- <>
4823
- <text
4824
- x="115" y="54" textAnchor="middle"
4825
- fill={pal.legendText}
4826
- fontSize="10" fontFamily="monospace" fontStyle="italic"
4827
- opacity={0.65}
4828
- data-recent-signal-empty
4829
- data-recent-signal-empty-breathes={reducedMotion ? 'false' : 'true'}
4830
- >
4831
- no flow yet
4832
- {!reducedMotion && (
4833
- <animate
4834
- attributeName="opacity"
4835
- values="0.55;0.78;0.55"
4836
- dur="4.4s"
4837
- repeatCount="indefinite"
4838
- />
4839
- )}
4840
- </text>
4841
- <text
4842
- x="115" y="68" textAnchor="middle"
4843
- fill={pal.legendText}
4844
- fontSize="8" fontFamily="monospace"
4845
- opacity={0.45}
4846
- data-recent-signal-empty-hint
4847
- data-recent-signal-empty-hint-breathes={reducedMotion ? 'false' : 'true'}
4848
- >
4849
- send a message between agents
4850
- {!reducedMotion && (
4851
- <animate
4852
- attributeName="opacity"
4853
- values="0.36;0.58;0.36"
4854
- dur="4.4s"
4855
- begin="-1.5s"
4856
- repeatCount="indefinite"
4857
- />
4858
- )}
4859
- </text>
4860
- </>
4861
- ) : (
4806
+ R200 SMIL breath on each text continues running
4807
+ regardless of parent opacity (SVG opacity is
4808
+ multiplicative — same R214 pulse-dot composition idiom).
4809
+ When parent opacity is 0, SMIL still animates child
4810
+ opacity but the result composes to invisible. CSS and
4811
+ SMIL don't fight, they layer.
4812
+
4813
+ 300ms transition matches R203 row fade-in pace so the
4814
+ empty-fade-out + rows-fade-in pair share rhythm during
4815
+ the crossfade. */}
4816
+ <g
4817
+ data-recent-signal-empty-wrapper
4818
+ data-recent-signal-empty-visible={flowLinks.length === 0 ? 'true' : 'false'}
4819
+ style={{
4820
+ opacity: flowLinks.length === 0 ? 1 : 0,
4821
+ transition: 'opacity 300ms ease-out',
4822
+ pointerEvents: 'none',
4823
+ }}
4824
+ >
4825
+ <text
4826
+ x="115" y="54" textAnchor="middle"
4827
+ fill={pal.legendText}
4828
+ fontSize="10" fontFamily="monospace" fontStyle="italic"
4829
+ opacity={0.65}
4830
+ data-recent-signal-empty
4831
+ data-recent-signal-empty-breathes={reducedMotion ? 'false' : 'true'}
4832
+ >
4833
+ no flow yet
4834
+ {!reducedMotion && (
4835
+ <animate
4836
+ attributeName="opacity"
4837
+ values="0.55;0.78;0.55"
4838
+ dur="4.4s"
4839
+ repeatCount="indefinite"
4840
+ />
4841
+ )}
4842
+ </text>
4843
+ <text
4844
+ x="115" y="68" textAnchor="middle"
4845
+ fill={pal.legendText}
4846
+ fontSize="8" fontFamily="monospace"
4847
+ opacity={0.45}
4848
+ data-recent-signal-empty-hint
4849
+ data-recent-signal-empty-hint-breathes={reducedMotion ? 'false' : 'true'}
4850
+ >
4851
+ send a message between agents
4852
+ {!reducedMotion && (
4853
+ <animate
4854
+ attributeName="opacity"
4855
+ values="0.36;0.58;0.36"
4856
+ dur="4.4s"
4857
+ begin="-1.5s"
4858
+ repeatCount="indefinite"
4859
+ />
4860
+ )}
4861
+ </text>
4862
+ </g>
4863
+ {flowLinks.length === 0 ? null : (
4862
4864
  // Round 56 / Loop: each row is a navigator into the canvas.
4863
4865
  // Hover a row → set hoveredEdgeKey, which the existing R50
4864
4866
  // edge-focus + R49 endpoint-highlight ladders consume. The
@@ -5164,8 +5166,22 @@ export function TopoGraph({ sessions, sseSessions, renameSignal }: TopoGraphProp
5164
5166
  + opacity 0.55 reads as muted metadata, not an
5165
5167
  actionable row — matches the R110 empty-state hint
5166
5168
  idiom. */}
5167
- {flowLinks.length > 3 && (() => {
5168
- const moreCount = flowLinks.length - 3;
5169
+ {(() => {
5170
+ // Round 221 / Loop: footer always-mounts; visibility
5171
+ // crossfades via wrapper <g> opacity instead of React
5172
+ // conditional mount/unmount on flowLinks.length > 3.
5173
+ // Pre-R221 a fleet's 4th flow appearing snap-popped the
5174
+ // footer in; tapering back to 3 flows snap-removed it.
5175
+ // Same threshold-crossing snap R215 closed for edge
5176
+ // midpoint badges, now applied to the recent-panel
5177
+ // footer surface. moreCount clamps at 0 so when invisible
5178
+ // (length ≤ 3) the data attribute and text don't show
5179
+ // garbage negative numbers. a11y trio (role / tabIndex /
5180
+ // aria-hidden) and pointerEvents follow visibility so
5181
+ // the hidden footer doesn't appear in tab order or
5182
+ // intercept clicks at its midpoint coordinates.
5183
+ const visible = flowLinks.length > 3;
5184
+ const moreCount = Math.max(0, flowLinks.length - 3);
5169
5185
  const label = `+ ${moreCount} more flow${moreCount === 1 ? '' : 's'}`;
5170
5186
  // R133: the truncation hint becomes a clickable nav to
5171
5187
  // /messages. R128 introduced the footer as pure metadata
@@ -5176,21 +5192,30 @@ export function TopoGraph({ sessions, sseSessions, renameSignal }: TopoGraphProp
5176
5192
  // visual cue tells users this is interactive. The hover
5177
5193
  // state is React-controlled (no CSS :hover on SVG <g>
5178
5194
  // descendant text would feel reliable across Chrome's
5179
- // SVG quirks). pointerEvents:all so the text receives
5180
- // the click; onPointerDown stop-propagation so the
5181
- // R103 zoom/pan capture doesn't intercept first.
5195
+ // SVG quirks). pointerEvents follows visibility (R215
5196
+ // pattern) so the hidden footer can't intercept clicks
5197
+ // at its midpoint when it's invisible (sub-threshold
5198
+ // fleets).
5182
5199
  return (
5183
5200
  <g
5184
5201
  data-recent-panel-more-nav
5185
- role="link"
5186
- tabIndex={0}
5202
+ data-recent-panel-more-visible={visible ? 'true' : 'false'}
5203
+ role={visible ? 'link' : undefined}
5204
+ tabIndex={visible ? 0 : -1}
5205
+ aria-hidden={visible ? undefined : true}
5187
5206
  className="anet-topo-svg-focus"
5188
- style={{ cursor: 'pointer', pointerEvents: 'all' }}
5207
+ style={{
5208
+ cursor: visible ? 'pointer' : undefined,
5209
+ pointerEvents: visible ? 'all' : 'none',
5210
+ opacity: visible ? 1 : 0,
5211
+ transition: 'opacity 300ms ease-out',
5212
+ }}
5189
5213
  onPointerDown={(e) => e.stopPropagation()}
5190
- onMouseEnter={() => setHoveredRecentMore(true)}
5214
+ onMouseEnter={() => { if (visible) setHoveredRecentMore(true); }}
5191
5215
  onMouseLeave={() => setHoveredRecentMore(false)}
5192
- onClick={() => router.push('/messages')}
5216
+ onClick={() => { if (visible) router.push('/messages'); }}
5193
5217
  onKeyDown={(e) => {
5218
+ if (!visible) return;
5194
5219
  if (e.key === 'Enter' || e.key === ' ') {
5195
5220
  e.preventDefault();
5196
5221
  router.push('/messages');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sleep2agi/agent-network-dashboard",
3
- "version": "0.4.6-preview.227",
3
+ "version": "0.4.6-preview.229",
4
4
  "description": "Agent Network Dashboard — Web UI for managing AI Agent networks",
5
5
  "scripts": {
6
6
  "dev": "next dev",
@@ -0,0 +1,130 @@
1
+ /* Round 222 verification: recent-signal panel empty state always-
2
+ * mounts; visibility crossfades via wrapper <g> opacity instead of
3
+ * conditional mount/unmount on flowLinks.length === 0.
4
+ *
5
+ * Pre-R222 the first flow arriving snap-removed the empty state
6
+ * (R45 + R200) in one frame while R203 rows simultaneously faded
7
+ * IN — half-smooth, half-snap. R222 closes the snap so the empty-
8
+ * to-populated transition crossfades both directions cleanly.
9
+ *
10
+ * Test scenarios:
11
+ * A. 0 flows (empty):
12
+ * · wrapper visible='true', opacity=1
13
+ * · both empty texts present, R200 SMIL <animate> still on
14
+ * · rows NOT mounted (rows path returns null)
15
+ * B. 3 flows (populated):
16
+ * · wrapper visible='false', opacity=0
17
+ * · both empty texts STILL in DOM (always-mount)
18
+ * · R200 SMIL <animate> still in place (just invisible due
19
+ * to parent opacity 0)
20
+ * · rows present
21
+ * Both: inline transition includes 'opacity 300ms'
22
+ */
23
+ import { chromium } from 'playwright';
24
+ import { readFileSync } from 'node:fs';
25
+
26
+ const TOKEN = JSON.parse(readFileSync('/home/vansin/.anet/config.json', 'utf8')).token;
27
+ const browser = await chromium.launch({ headless: true });
28
+
29
+ async function setup(messages) {
30
+ const ctx = await browser.newContext({ viewport: { width: 1500, height: 1500 } });
31
+ await ctx.addCookies([{ name: 'anet_dashboard_session', value: `v3:${TOKEN}`, domain: '127.0.0.1', path: '/' }]);
32
+ await ctx.addInitScript(() => {
33
+ try { localStorage.setItem('anet-theme', 'cyber'); sessionStorage.setItem('anet_v3_auth', '1'); } catch {}
34
+ });
35
+ const fresh = new Date(Date.now() - 60 * 1000).toISOString();
36
+ await ctx.route('**/api/hub/status*', async (route) => {
37
+ const r = await route.fetch();
38
+ const b = await r.json();
39
+ const nid = (b.sessions || [])[0]?.network_id || 'default';
40
+ const mk = (alias) => ({
41
+ alias, status: 'working', model: 'claude-opus-4', runtime: 'claude-code-cli',
42
+ network_id: nid, project_dir: null,
43
+ created_at: fresh, updated_at: fresh, last_seen_at: fresh,
44
+ });
45
+ await route.fulfill({ response: r, json: { ...b, sessions: [
46
+ mk('alpha'), mk('beta'), mk('gamma'), mk('delta'),
47
+ ] } });
48
+ });
49
+ await ctx.route('**/api/hub/messages*', (r2) => r2.fulfill({ json: { messages } }));
50
+ await ctx.route('**/api/hub/tasks*', (r2) => r2.fulfill({ json: { tasks: [] } }));
51
+ const page = await ctx.newPage();
52
+ await page.goto('http://127.0.0.1:3000/', { waitUntil: 'domcontentloaded' });
53
+ await page.waitForFunction(() => document.querySelectorAll('g[data-node]').length === 4, { timeout: 30000 });
54
+ await page.waitForSelector('[data-recent-signal-empty-wrapper]', { timeout: 10000, state: 'attached' });
55
+ await page.waitForTimeout(400);
56
+ return page;
57
+ }
58
+
59
+ const probe = async (page) => page.evaluate(() => {
60
+ const wrapper = document.querySelector('[data-recent-signal-empty-wrapper]');
61
+ if (!wrapper) return null;
62
+ const cs = getComputedStyle(wrapper);
63
+ const main = wrapper.querySelector('[data-recent-signal-empty]');
64
+ const hint = wrapper.querySelector('[data-recent-signal-empty-hint]');
65
+ const mainAnim = main?.querySelector('animate');
66
+ const hintAnim = hint?.querySelector('animate');
67
+ const rowCount = document.querySelectorAll('[data-recent-row]').length;
68
+ return {
69
+ visible: wrapper.getAttribute('data-recent-signal-empty-visible'),
70
+ opacity: parseFloat(cs.opacity),
71
+ transition: wrapper.style.transition,
72
+ mainPresent: !!main,
73
+ hintPresent: !!hint,
74
+ mainText: main?.textContent?.trim().split(/\s+/)[0] + ' ' + main?.textContent?.trim().split(/\s+/)[1]
75
+ + ' ' + main?.textContent?.trim().split(/\s+/)[2],
76
+ mainAnimAttr: mainAnim?.getAttribute('attributeName'),
77
+ hintAnimAttr: hintAnim?.getAttribute('attributeName'),
78
+ rowCount,
79
+ };
80
+ });
81
+
82
+ // Scenario A: 0 flows (empty)
83
+ const pageA = await setup([]);
84
+ const probeA = await probe(pageA);
85
+ await pageA.close();
86
+
87
+ // Scenario B: 3 flows (populated)
88
+ const now = Date.now();
89
+ const pageB = await setup([
90
+ { id: '1', from_alias: 'alpha', to_alias: 'beta', content: 'hi',
91
+ network_id: 'default', created_at: new Date(now - 1000).toISOString() },
92
+ { id: '2', from_alias: 'beta', to_alias: 'gamma', content: 'hi',
93
+ network_id: 'default', created_at: new Date(now - 2000).toISOString() },
94
+ { id: '3', from_alias: 'gamma', to_alias: 'delta', content: 'hi',
95
+ network_id: 'default', created_at: new Date(now - 3000).toISOString() },
96
+ ]);
97
+ const probeB = await probe(pageB);
98
+ await pageB.close();
99
+ await browser.close();
100
+
101
+ const results = {
102
+ // Scenario A — empty
103
+ A_present_in_dom: !!probeA,
104
+ A_visible_true: probeA?.visible === 'true',
105
+ A_opacity_1: probeA?.opacity === 1,
106
+ A_main_present: probeA?.mainPresent === true,
107
+ A_hint_present: probeA?.hintPresent === true,
108
+ A_main_anim_opacity: probeA?.mainAnimAttr === 'opacity',
109
+ A_hint_anim_opacity: probeA?.hintAnimAttr === 'opacity',
110
+ A_no_rows: probeA?.rowCount === 0,
111
+
112
+ // Scenario B — populated (empty still in DOM)
113
+ B_present_in_dom: !!probeB,
114
+ B_visible_false: probeB?.visible === 'false',
115
+ B_opacity_0: probeB?.opacity === 0,
116
+ B_main_still_in_dom: probeB?.mainPresent === true,
117
+ B_hint_still_in_dom: probeB?.hintPresent === true,
118
+ B_main_anim_still_on: probeB?.mainAnimAttr === 'opacity',
119
+ B_hint_anim_still_on: probeB?.hintAnimAttr === 'opacity',
120
+ B_three_rows: probeB?.rowCount === 3,
121
+
122
+ // Transitions present in both
123
+ A_has_transition: /opacity\s+(?:300ms|0\.3s)/.test(probeA?.transition || ''),
124
+ B_has_transition: /opacity\s+(?:300ms|0\.3s)/.test(probeB?.transition || ''),
125
+ };
126
+ const ok = Object.values(results).every(Boolean);
127
+ console.log(`${ok ? '✅' : '❌'} empty-state crossfade:`, JSON.stringify(results),
128
+ `\n probeA (0 flows empty):`, probeA,
129
+ `\n probeB (3 flows populated):`, probeB);
130
+ process.exit(ok ? 0 : 1);
@@ -0,0 +1,124 @@
1
+ /* Round 221 verification: recent-signal panel "+N more" footer
2
+ * always-mounts; visibility crossfades via wrapper <g> opacity
3
+ * instead of React conditional mount/unmount on flowLinks > 3.
4
+ *
5
+ * Pre-R221 a fleet's 4th flow appearing snap-popped the footer
6
+ * into the canvas; tapering back to 3 flows snap-removed it.
7
+ * Same threshold-crossing snap R215 closed for edge midpoint
8
+ * badges, now applied to the recent-panel footer surface.
9
+ *
10
+ * Test scenarios:
11
+ * A. 2 flows (below threshold) → footer in DOM, visible='false',
12
+ * opacity=0, pointerEvents='none',
13
+ * aria-hidden='true', role unset,
14
+ * tabIndex=-1
15
+ * B. 5 flows (visible threshold) → footer visible='true',
16
+ * opacity>0, role='link', tabIndex=0
17
+ * Both: inline transition includes 'opacity 300ms'.
18
+ * moreCount text content clamps at 0 / 2 respectively.
19
+ */
20
+ import { chromium } from 'playwright';
21
+ import { readFileSync } from 'node:fs';
22
+
23
+ const TOKEN = JSON.parse(readFileSync('/home/vansin/.anet/config.json', 'utf8')).token;
24
+ const browser = await chromium.launch({ headless: true });
25
+
26
+ async function setup(n) {
27
+ const ctx = await browser.newContext({ viewport: { width: 1500, height: 1500 } });
28
+ await ctx.addCookies([{ name: 'anet_dashboard_session', value: `v3:${TOKEN}`, domain: '127.0.0.1', path: '/' }]);
29
+ await ctx.addInitScript(() => {
30
+ try { localStorage.setItem('anet-theme', 'cyber'); sessionStorage.setItem('anet_v3_auth', '1'); } catch {}
31
+ });
32
+ const fresh = new Date(Date.now() - 60 * 1000).toISOString();
33
+ await ctx.route('**/api/hub/status*', async (route) => {
34
+ const r = await route.fetch();
35
+ const b = await r.json();
36
+ const nid = (b.sessions || [])[0]?.network_id || 'default';
37
+ const mk = (alias) => ({
38
+ alias, status: 'working', model: 'claude-opus-4', runtime: 'claude-code-cli',
39
+ network_id: nid, project_dir: null,
40
+ created_at: fresh, updated_at: fresh, last_seen_at: fresh,
41
+ });
42
+ await route.fulfill({ response: r, json: { ...b, sessions: [
43
+ mk('alpha'), mk('beta'), mk('gamma'), mk('delta'),
44
+ ] } });
45
+ });
46
+ const now = Date.now();
47
+ // Need N distinct flow pairs → mock N messages with distinct alias pairs
48
+ const pairs = [
49
+ ['alpha', 'beta'], ['beta', 'gamma'], ['gamma', 'delta'],
50
+ ['delta', 'alpha'], ['alpha', 'gamma'], ['beta', 'delta'],
51
+ ];
52
+ const msgs = pairs.slice(0, n).map((p, i) => ({
53
+ id: `m${i}`, from_alias: p[0], to_alias: p[1], content: 'hi',
54
+ network_id: 'default', created_at: new Date(now - (1000 + i * 500)).toISOString(),
55
+ }));
56
+ await ctx.route('**/api/hub/messages*', (r2) => r2.fulfill({ json: { messages: msgs } }));
57
+ await ctx.route('**/api/hub/tasks*', (r2) => r2.fulfill({ json: { tasks: [] } }));
58
+ const page = await ctx.newPage();
59
+ await page.goto('http://127.0.0.1:3000/', { waitUntil: 'domcontentloaded' });
60
+ await page.waitForFunction(() => document.querySelectorAll('g[data-node]').length === 4, { timeout: 30000 });
61
+ await page.waitForSelector('[data-recent-panel-more-nav]', { timeout: 10000, state: 'attached' });
62
+ await page.waitForTimeout(400);
63
+ return page;
64
+ }
65
+
66
+ const probe = async (page) => page.evaluate(() => {
67
+ const el = document.querySelector('[data-recent-panel-more-nav]');
68
+ if (!el) return null;
69
+ const cs = getComputedStyle(el);
70
+ const txt = el.querySelector('[data-recent-panel-more]');
71
+ return {
72
+ visible: el.getAttribute('data-recent-panel-more-visible'),
73
+ role: el.getAttribute('role'),
74
+ tabIndex: el.getAttribute('tabindex'),
75
+ ariaHidden: el.getAttribute('aria-hidden'),
76
+ opacity: parseFloat(cs.opacity),
77
+ computedPointer:cs.pointerEvents,
78
+ transition: el.style.transition,
79
+ moreText: txt?.textContent,
80
+ moreCount: txt?.getAttribute('data-recent-panel-more'),
81
+ };
82
+ });
83
+
84
+ // Scenario A: 2 flows (below threshold)
85
+ const pageA = await setup(2);
86
+ const probeA = await probe(pageA);
87
+ await pageA.close();
88
+
89
+ // Scenario B: 5 flows (above threshold)
90
+ const pageB = await setup(5);
91
+ const probeB = await probe(pageB);
92
+ await pageB.close();
93
+ await browser.close();
94
+
95
+ const results = {
96
+ // Scenario A (2 flows, hidden)
97
+ A_present_in_dom: !!probeA,
98
+ A_visible_false: probeA?.visible === 'false',
99
+ A_opacity_0: probeA?.opacity === 0,
100
+ A_pointer_none: probeA?.computedPointer === 'none',
101
+ A_aria_hidden: probeA?.ariaHidden === 'true',
102
+ A_role_unset: probeA?.role === null || probeA?.role === '',
103
+ A_tabindex_neg: probeA?.tabIndex === '-1',
104
+ A_more_count_0: probeA?.moreCount === '0', // clamped at 0
105
+
106
+ // Scenario B (5 flows, visible)
107
+ B_present_in_dom: !!probeB,
108
+ B_visible_true: probeB?.visible === 'true',
109
+ B_opacity_positive: (probeB?.opacity ?? 0) > 0,
110
+ B_pointer_all: probeB?.computedPointer === 'all',
111
+ B_role_link: probeB?.role === 'link',
112
+ B_tabindex_0: probeB?.tabIndex === '0',
113
+ B_more_count_2: probeB?.moreCount === '2',
114
+ B_text_says_2: /^\+\s*2\s*more flow/.test(probeB?.moreText || ''),
115
+
116
+ // Both scenarios have opacity 300ms transition
117
+ A_has_transition: /opacity\s+(?:300ms|0\.3s)/.test(probeA?.transition || ''),
118
+ B_has_transition: /opacity\s+(?:300ms|0\.3s)/.test(probeB?.transition || ''),
119
+ };
120
+ const ok = Object.values(results).every(Boolean);
121
+ console.log(`${ok ? '✅' : '❌'} recent-panel more crossfade:`, JSON.stringify(results),
122
+ `\n probeA (2 flows hidden):`, probeA,
123
+ `\n probeB (5 flows visible):`, probeB);
124
+ process.exit(ok ? 0 : 1);