@sleep2agi/agent-network-dashboard 0.5.3-preview.256 → 0.5.3-preview.259
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.
- package/.next/BUILD_ID +1 -1
- package/.next/build-manifest.json +3 -3
- package/.next/diagnostics/route-bundle-stats.json +5 -5
- package/.next/fallback-build-manifest.json +3 -3
- package/.next/server/app/_global-error.html +1 -1
- package/.next/server/app/_global-error.rsc +1 -1
- package/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/.next/server/app/_not-found.html +2 -2
- package/.next/server/app/_not-found.rsc +2 -2
- package/.next/server/app/_not-found.segments/_full.segment.rsc +2 -2
- package/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/.next/server/app/_not-found.segments/_index.segment.rsc +2 -2
- package/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/admin/page_client-reference-manifest.js +1 -1
- package/.next/server/app/admin.html +2 -2
- package/.next/server/app/admin.rsc +2 -2
- package/.next/server/app/admin.segments/_full.segment.rsc +2 -2
- package/.next/server/app/admin.segments/_head.segment.rsc +1 -1
- package/.next/server/app/admin.segments/_index.segment.rsc +2 -2
- package/.next/server/app/admin.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/admin.segments/admin/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/admin.segments/admin.segment.rsc +1 -1
- package/.next/server/app/index.html +2 -2
- package/.next/server/app/index.rsc +3 -3
- package/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
- package/.next/server/app/index.segments/_full.segment.rsc +3 -3
- package/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/.next/server/app/index.segments/_index.segment.rsc +2 -2
- package/.next/server/app/index.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/login/page_client-reference-manifest.js +1 -1
- package/.next/server/app/login.html +2 -2
- package/.next/server/app/login.rsc +3 -3
- package/.next/server/app/login.segments/_full.segment.rsc +3 -3
- package/.next/server/app/login.segments/_head.segment.rsc +1 -1
- package/.next/server/app/login.segments/_index.segment.rsc +2 -2
- package/.next/server/app/login.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/login.segments/login/__PAGE__.segment.rsc +2 -2
- package/.next/server/app/login.segments/login.segment.rsc +1 -1
- package/.next/server/app/logs/page_client-reference-manifest.js +1 -1
- package/.next/server/app/logs.html +2 -2
- package/.next/server/app/logs.rsc +2 -2
- package/.next/server/app/logs.segments/_full.segment.rsc +2 -2
- package/.next/server/app/logs.segments/_head.segment.rsc +1 -1
- package/.next/server/app/logs.segments/_index.segment.rsc +2 -2
- package/.next/server/app/logs.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/logs.segments/logs/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/logs.segments/logs.segment.rsc +1 -1
- package/.next/server/app/messages/page_client-reference-manifest.js +1 -1
- package/.next/server/app/messages.html +2 -2
- package/.next/server/app/messages.rsc +2 -2
- package/.next/server/app/messages.segments/_full.segment.rsc +2 -2
- package/.next/server/app/messages.segments/_head.segment.rsc +1 -1
- package/.next/server/app/messages.segments/_index.segment.rsc +2 -2
- package/.next/server/app/messages.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/messages.segments/messages/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/messages.segments/messages.segment.rsc +1 -1
- package/.next/server/app/node/page_client-reference-manifest.js +1 -1
- package/.next/server/app/node.html +2 -2
- package/.next/server/app/node.rsc +2 -2
- package/.next/server/app/node.segments/_full.segment.rsc +2 -2
- package/.next/server/app/node.segments/_head.segment.rsc +1 -1
- package/.next/server/app/node.segments/_index.segment.rsc +2 -2
- package/.next/server/app/node.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/node.segments/node/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/node.segments/node.segment.rsc +1 -1
- package/.next/server/app/nodes/page_client-reference-manifest.js +1 -1
- package/.next/server/app/nodes.html +2 -2
- package/.next/server/app/nodes.rsc +2 -2
- package/.next/server/app/nodes.segments/_full.segment.rsc +2 -2
- package/.next/server/app/nodes.segments/_head.segment.rsc +1 -1
- package/.next/server/app/nodes.segments/_index.segment.rsc +2 -2
- package/.next/server/app/nodes.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/nodes.segments/nodes/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/nodes.segments/nodes.segment.rsc +1 -1
- package/.next/server/app/page_client-reference-manifest.js +1 -1
- package/.next/server/app/server-logs/page_client-reference-manifest.js +1 -1
- package/.next/server/app/server-logs.html +2 -2
- package/.next/server/app/server-logs.rsc +2 -2
- package/.next/server/app/server-logs.segments/_full.segment.rsc +2 -2
- package/.next/server/app/server-logs.segments/_head.segment.rsc +1 -1
- package/.next/server/app/server-logs.segments/_index.segment.rsc +2 -2
- package/.next/server/app/server-logs.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/server-logs.segments/server-logs/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/server-logs.segments/server-logs.segment.rsc +1 -1
- package/.next/server/app/settings/networks/page_client-reference-manifest.js +1 -1
- package/.next/server/app/settings/networks.html +2 -2
- package/.next/server/app/settings/networks.rsc +2 -2
- package/.next/server/app/settings/networks.segments/_full.segment.rsc +2 -2
- package/.next/server/app/settings/networks.segments/_head.segment.rsc +1 -1
- package/.next/server/app/settings/networks.segments/_index.segment.rsc +2 -2
- package/.next/server/app/settings/networks.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/settings/networks.segments/settings/networks/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/settings/networks.segments/settings/networks.segment.rsc +1 -1
- package/.next/server/app/settings/networks.segments/settings.segment.rsc +1 -1
- package/.next/server/app/settings/page_client-reference-manifest.js +1 -1
- package/.next/server/app/settings/tokens/page_client-reference-manifest.js +1 -1
- package/.next/server/app/settings/tokens.html +2 -2
- package/.next/server/app/settings/tokens.rsc +2 -2
- package/.next/server/app/settings/tokens.segments/_full.segment.rsc +2 -2
- package/.next/server/app/settings/tokens.segments/_head.segment.rsc +1 -1
- package/.next/server/app/settings/tokens.segments/_index.segment.rsc +2 -2
- package/.next/server/app/settings/tokens.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/settings/tokens.segments/settings/tokens/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/settings/tokens.segments/settings/tokens.segment.rsc +1 -1
- package/.next/server/app/settings/tokens.segments/settings.segment.rsc +1 -1
- package/.next/server/app/settings.html +2 -2
- package/.next/server/app/settings.rsc +3 -3
- package/.next/server/app/settings.segments/_full.segment.rsc +3 -3
- package/.next/server/app/settings.segments/_head.segment.rsc +1 -1
- package/.next/server/app/settings.segments/_index.segment.rsc +2 -2
- package/.next/server/app/settings.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/settings.segments/settings/__PAGE__.segment.rsc +2 -2
- package/.next/server/app/settings.segments/settings.segment.rsc +1 -1
- package/.next/server/app/tasks/[id]/page_client-reference-manifest.js +1 -1
- package/.next/server/app/tasks/page_client-reference-manifest.js +1 -1
- package/.next/server/app/tasks.html +2 -2
- package/.next/server/app/tasks.rsc +2 -2
- package/.next/server/app/tasks.segments/_full.segment.rsc +2 -2
- package/.next/server/app/tasks.segments/_head.segment.rsc +1 -1
- package/.next/server/app/tasks.segments/_index.segment.rsc +2 -2
- package/.next/server/app/tasks.segments/_tree.segment.rsc +2 -2
- package/.next/server/app/tasks.segments/tasks/__PAGE__.segment.rsc +1 -1
- package/.next/server/app/tasks.segments/tasks.segment.rsc +1 -1
- package/.next/server/chunks/[root-of-the-server]__0tx8s8i._.js +1 -1
- package/.next/server/chunks/[root-of-the-server]__0tx8s8i._.js.map +1 -1
- package/.next/server/chunks/ssr/[root-of-the-server]__0sv~g.o._.js +1 -1
- package/.next/server/chunks/ssr/[root-of-the-server]__0sv~g.o._.js.map +1 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_09kk21a._.js +2 -2
- package/.next/server/chunks/ssr/agent-network-dashboard_09kk21a._.js.map +1 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_app_01jhlxz._.js +1 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_app_01jhlxz._.js.map +1 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_app_09d29my._.js +1 -1
- package/.next/server/chunks/ssr/agent-network-dashboard_app_09d29my._.js.map +1 -1
- package/.next/server/middleware-build-manifest.js +3 -3
- package/.next/server/pages/404.html +2 -2
- package/.next/server/pages/500.html +1 -1
- package/.next/static/chunks/{0mbz6_9.awtny.js → 0-j8-e_dqejm7.js} +2 -2
- package/.next/static/chunks/{0ypxu9tjas5ii.js → 0rfv0i6s6p5w..js} +1 -1
- package/.next/static/chunks/{0lz0d3xp-akmx.js → 0ysm~dy.6klf4.js} +1 -1
- package/.next/static/chunks/{0xu6mniq9hov9.js → 0y~ndc96dgfdi.js} +1 -1
- package/.next/static/chunks/{0-7ma47rnbr6l.css → 16-7qr7qx9zrz.css} +1 -1
- package/.next/trace +2 -2
- package/.next/trace-build +1 -1
- package/app/api/hub/servers/route.ts +3 -29
- package/app/components/TopoGraph.tsx +20 -2
- package/app/globals.css +25 -0
- package/app/lib/serverDedupe.ts +122 -0
- package/package.json +1 -1
- package/scripts/p157-rc2-dedup-test.mjs +110 -0
- package/scripts/topo-animation-temporal-modes-catalog-test.mjs +4 -5
- package/scripts/topo-chrome-strip-entrance-animation-test.mjs +115 -0
- /package/.next/static/{iXL-5CIRUR5NRzD1e0XT- → OLU9smG22aFJt6Y2nEBbV}/_buildManifest.js +0 -0
- /package/.next/static/{iXL-5CIRUR5NRzD1e0XT- → OLU9smG22aFJt6Y2nEBbV}/_clientMiddlewareManifest.js +0 -0
- /package/.next/static/{iXL-5CIRUR5NRzD1e0XT- → OLU9smG22aFJt6Y2nEBbV}/_ssgManifest.js +0 -0
package/.next/trace
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
[{"name":"generate-buildid","duration":266,"timestamp":418083711657,"id":4,"parentId":1,"tags":{},"startTime":1779226055958,"traceId":"81a58f90c730f8ed"},{"name":"load-custom-routes","duration":676,"timestamp":418083712155,"id":5,"parentId":1,"tags":{},"startTime":1779226055958,"traceId":"81a58f90c730f8ed"},{"name":"create-dist-dir","duration":925,"timestamp":418083712881,"id":6,"parentId":1,"tags":{},"startTime":1779226055959,"traceId":"81a58f90c730f8ed"},{"name":"clean","duration":37290,"timestamp":418083714700,"id":7,"parentId":1,"tags":{},"startTime":1779226055961,"traceId":"81a58f90c730f8ed"},{"name":"discover-routes","duration":23540,"timestamp":418083836376,"id":8,"parentId":1,"tags":{},"startTime":1779226056083,"traceId":"81a58f90c730f8ed"},{"name":"create-root-mapping","duration":151,"timestamp":418083859981,"id":9,"parentId":1,"tags":{},"startTime":1779226056106,"traceId":"81a58f90c730f8ed"},{"name":"generate-route-types","duration":25881,"timestamp":418083862886,"id":10,"parentId":1,"tags":{},"startTime":1779226056109,"traceId":"81a58f90c730f8ed"},{"name":"public-dir-conflict-check","duration":97,"timestamp":418083888855,"id":11,"parentId":1,"tags":{},"startTime":1779226056135,"traceId":"81a58f90c730f8ed"},{"name":"generate-routes-manifest","duration":5230,"timestamp":418083889114,"id":12,"parentId":1,"tags":{},"startTime":1779226056135,"traceId":"81a58f90c730f8ed"},{"name":"run-turbopack","duration":6652953,"timestamp":418083901259,"id":14,"parentId":1,"tags":{},"startTime":1779226056148,"traceId":"81a58f90c730f8ed"},{"name":"turbopack-build-events","duration":106,"timestamp":418084218074,"id":15,"parentId":1,"tags":{},"startTime":1779226056464,"traceId":"81a58f90c730f8ed"},{"name":"run-typescript","duration":10647715,"timestamp":418090563521,"id":16,"parentId":1,"tags":{},"startTime":1779226062810,"traceId":"81a58f90c730f8ed"},{"name":"generate-required-server-files","duration":3110,"timestamp":418101212607,"id":18,"parentId":1,"tags":{},"startTime":1779226073459,"traceId":"81a58f90c730f8ed"},{"name":"check-static-error-page","duration":14188,"timestamp":418101452325,"id":20,"parentId":19,"tags":{},"startTime":1779226073699,"traceId":"81a58f90c730f8ed"},{"name":"is-page-static","duration":648589,"timestamp":418101470151,"id":65,"parentId":22,"tags":{},"startTime":1779226073716,"traceId":"81a58f90c730f8ed"},{"name":"check-page","duration":664235,"timestamp":418101454696,"id":22,"parentId":19,"tags":{"page":"/_global-error"},"startTime":1779226073701,"traceId":"81a58f90c730f8ed"},{"name":"is-page-static","duration":686281,"timestamp":418101470941,"id":70,"parentId":29,"tags":{},"startTime":1779226073717,"traceId":"81a58f90c730f8ed"},{"name":"check-page","duration":699163,"timestamp":418101458172,"id":29,"parentId":19,"tags":{"page":"/api/hub/auth"},"startTime":1779226073704,"traceId":"81a58f90c730f8ed"},{"name":"is-page-static","duration":688015,"timestamp":418101470325,"id":66,"parentId":25,"tags":{},"startTime":1779226073717,"traceId":"81a58f90c730f8ed"},{"name":"check-page","duration":700849,"timestamp":418101457568,"id":25,"parentId":19,"tags":{"page":"/api/auth/login"},"startTime":1779226073704,"traceId":"81a58f90c730f8ed"},{"name":"is-page-static","duration":693174,"timestamp":418101471368,"id":73,"parentId":33,"tags":{},"startTime":1779226073718,"traceId":"81a58f90c730f8ed"},{"name":"check-page","duration":705707,"timestamp":418101458904,"id":33,"parentId":19,"tags":{"page":"/api/hub/inbox"},"startTime":1779226073705,"traceId":"81a58f90c730f8ed"},{"name":"is-page-static","duration":731249,"timestamp":418101471187,"id":72,"parentId":32,"tags":{},"startTime":1779226073717,"traceId":"81a58f90c730f8ed"},{"name":"check-page","duration":743751,"timestamp":418101458778,"id":32,"parentId":19,"tags":{"page":"/api/hub/health"},"startTime":1779226073705,"traceId":"81a58f90c730f8ed"},{"name":"is-page-static","duration":731311,"timestamp":418101471451,"id":74,"parentId":34,"tags":{},"startTime":1779226073718,"traceId":"81a58f90c730f8ed"},{"name":"check-page","duration":743769,"timestamp":418101459041,"id":34,"parentId":19,"tags":{"page":"/api/hub/license"},"startTime":1779226073705,"traceId":"81a58f90c730f8ed"},{"name":"is-page-static","duration":741366,"timestamp":418101471494,"id":76,"parentId":36,"tags":{},"startTime":1779226073718,"traceId":"81a58f90c730f8ed"},{"name":"check-page","duration":753448,"timestamp":418101459502,"id":36,"parentId":19,"tags":{"page":"/api/hub/networks"},"startTime":1779226073706,"traceId":"81a58f90c730f8ed"},{"name":"is-page-static","duration":752656,"timestamp":418101471475,"id":75,"parentId":35,"tags":{},"startTime":1779226073718,"traceId":"81a58f90c730f8ed"},{"name":"check-page","duration":765056,"timestamp":418101459147,"id":35,"parentId":19,"tags":{"page":"/api/hub/messages"},"startTime":1779226073705,"traceId":"81a58f90c730f8ed"},{"name":"is-page-static","duration":752931,"timestamp":418101471520,"id":77,"parentId":37,"tags":{},"startTime":1779226073718,"traceId":"81a58f90c730f8ed"},{"name":"check-page","duration":764874,"timestamp":418101459619,"id":37,"parentId":19,"tags":{"page":"/api/hub/nodes"},"startTime":1779226073706,"traceId":"81a58f90c730f8ed"},{"name":"is-page-static","duration":758733,"timestamp":418101471538,"id":78,"parentId":38,"tags":{},"startTime":1779226073718,"traceId":"81a58f90c730f8ed"},{"name":"check-page","duration":770630,"timestamp":418101459712,"id":38,"parentId":19,"tags":{"page":"/api/hub/register"},"startTime":1779226073706,"traceId":"81a58f90c730f8ed"},{"name":"is-page-static","duration":760114,"timestamp":418101470442,"id":67,"parentId":26,"tags":{},"startTime":1779226073717,"traceId":"81a58f90c730f8ed"},{"name":"check-page","duration":772830,"timestamp":418101457764,"id":26,"parentId":19,"tags":{"page":"/api/auth/logout"},"startTime":1779226073704,"traceId":"81a58f90c730f8ed"},{"name":"is-page-static","duration":762186,"timestamp":418101471548,"id":79,"parentId":39,"tags":{},"startTime":1779226073718,"traceId":"81a58f90c730f8ed"},{"name":"check-page","duration":774009,"timestamp":418101459773,"id":39,"parentId":19,"tags":{"page":"/api/hub/send"},"startTime":1779226073706,"traceId":"81a58f90c730f8ed"},{"name":"is-page-static","duration":766809,"timestamp":418101471584,"id":82,"parentId":44,"tags":{},"startTime":1779226073718,"traceId":"81a58f90c730f8ed"},{"name":"check-page","duration":777844,"timestamp":418101460596,"id":44,"parentId":19,"tags":{"page":"/api/hub/session"},"startTime":1779226073707,"traceId":"81a58f90c730f8ed"},{"name":"is-page-static","duration":771609,"timestamp":418101470563,"id":68,"parentId":27,"tags":{},"startTime":1779226073717,"traceId":"81a58f90c730f8ed"},{"name":"check-page","duration":784332,"timestamp":418101457888,"id":27,"parentId":19,"tags":{"page":"/api/auth/v3"},"startTime":1779226073704,"traceId":"81a58f90c730f8ed"},{"name":"is-page-static","duration":775483,"timestamp":418101471597,"id":83,"parentId":45,"tags":{},"startTime":1779226073718,"traceId":"81a58f90c730f8ed"},{"name":"check-page","duration":786421,"timestamp":418101460717,"id":45,"parentId":19,"tags":{"page":"/api/hub/stats"},"startTime":1779226073707,"traceId":"81a58f90c730f8ed"},{"name":"is-page-static","duration":776412,"timestamp":418101471624,"id":85,"parentId":47,"tags":{},"startTime":1779226073718,"traceId":"81a58f90c730f8ed"},{"name":"check-page","duration":787154,"timestamp":418101460929,"id":47,"parentId":19,"tags":{"page":"/api/hub/task-events"},"startTime":1779226073707,"traceId":"81a58f90c730f8ed"},{"name":"is-page-static","duration":778545,"timestamp":418101471562,"id":80,"parentId":40,"tags":{},"startTime":1779226073718,"traceId":"81a58f90c730f8ed"},{"name":"check-page","duration":790185,"timestamp":418101459980,"id":40,"parentId":19,"tags":{"page":"/api/hub/server-logs"},"startTime":1779226073706,"traceId":"81a58f90c730f8ed"},{"name":"is-page-static","duration":785506,"timestamp":418101471633,"id":86,"parentId":48,"tags":{},"startTime":1779226073718,"traceId":"81a58f90c730f8ed"},{"name":"check-page","duration":794407,"timestamp":418101462779,"id":48,"parentId":19,"tags":{"page":"/api/hub/tasks"},"startTime":1779226073709,"traceId":"81a58f90c730f8ed"},{"name":"is-page-static","duration":786323,"timestamp":418101471645,"id":87,"parentId":49,"tags":{},"startTime":1779226073718,"traceId":"81a58f90c730f8ed"},{"name":"check-page","duration":794995,"timestamp":418101463033,"id":49,"parentId":19,"tags":{"page":"/api/hub/tmux"},"startTime":1779226073709,"traceId":"81a58f90c730f8ed"},{"name":"is-page-static","duration":789696,"timestamp":418101470677,"id":69,"parentId":28,"tags":{},"startTime":1779226073717,"traceId":"81a58f90c730f8ed"},{"name":"check-page","duration":802379,"timestamp":418101458037,"id":28,"parentId":19,"tags":{"page":"/api/hub/audit-log"},"startTime":1779226073704,"traceId":"81a58f90c730f8ed"},{"name":"is-page-static","duration":789338,"timestamp":418101471610,"id":84,"parentId":46,"tags":{},"startTime":1779226073718,"traceId":"81a58f90c730f8ed"},{"name":"check-page","duration":800172,"timestamp":418101460818,"id":46,"parentId":19,"tags":{"page":"/api/hub/status"},"startTime":1779226073707,"traceId":"81a58f90c730f8ed"},{"name":"is-page-static","duration":794684,"timestamp":418101469810,"id":64,"parentId":21,"tags":{},"startTime":1779226073716,"traceId":"81a58f90c730f8ed"},{"name":"check-page","duration":810996,"timestamp":418101453542,"id":21,"parentId":19,"tags":{"page":"/_not-found"},"startTime":1779226073700,"traceId":"81a58f90c730f8ed"},{"name":"is-page-static","duration":794608,"timestamp":418101471665,"id":89,"parentId":51,"tags":{},"startTime":1779226073718,"traceId":"81a58f90c730f8ed"},{"name":"check-page","duration":803084,"timestamp":418101463250,"id":51,"parentId":19,"tags":{"page":"/favicon.ico"},"startTime":1779226073710,"traceId":"81a58f90c730f8ed"},{"name":"is-page-static","duration":798007,"timestamp":418101471657,"id":88,"parentId":50,"tags":{},"startTime":1779226073718,"traceId":"81a58f90c730f8ed"},{"name":"check-page","duration":806547,"timestamp":418101463158,"id":50,"parentId":19,"tags":{"page":"/api/hub/tokens"},"startTime":1779226073709,"traceId":"81a58f90c730f8ed"},{"name":"is-page-static","duration":801503,"timestamp":418101471575,"id":81,"parentId":42,"tags":{},"startTime":1779226073718,"traceId":"81a58f90c730f8ed"},{"name":"check-page","duration":812855,"timestamp":418101460283,"id":42,"parentId":19,"tags":{"page":"/api/hub/server/[hostname]/health"},"startTime":1779226073707,"traceId":"81a58f90c730f8ed"},{"name":"is-page-static","duration":787599,"timestamp":418101485680,"id":91,"parentId":31,"tags":{},"startTime":1779226073732,"traceId":"81a58f90c730f8ed"},{"name":"check-page","duration":814833,"timestamp":418101458492,"id":31,"parentId":19,"tags":{"page":"/api/hub/events"},"startTime":1779226073705,"traceId":"81a58f90c730f8ed"},{"name":"is-page-static","duration":796687,"timestamp":418101478485,"id":90,"parentId":24,"tags":{},"startTime":1779226073725,"traceId":"81a58f90c730f8ed"},{"name":"check-page","duration":820007,"timestamp":418101455211,"id":24,"parentId":19,"tags":{"page":"/api/anet/config"},"startTime":1779226073701,"traceId":"81a58f90c730f8ed"},{"name":"is-page-static","duration":780263,"timestamp":418101495090,"id":93,"parentId":43,"tags":{},"startTime":1779226073741,"traceId":"81a58f90c730f8ed"},{"name":"check-page","duration":815001,"timestamp":418101460384,"id":43,"parentId":19,"tags":{"page":"/api/hub/servers"},"startTime":1779226073707,"traceId":"81a58f90c730f8ed"},{"name":"is-page-static","duration":818213,"timestamp":418101471119,"id":71,"parentId":30,"tags":{},"startTime":1779226073717,"traceId":"81a58f90c730f8ed"},{"name":"check-page","duration":831064,"timestamp":418101458353,"id":30,"parentId":19,"tags":{"page":"/api/hub/broadcast"},"startTime":1779226073705,"traceId":"81a58f90c730f8ed"},{"name":"is-page-static","duration":844571,"timestamp":418101497684,"id":98,"parentId":55,"tags":{},"startTime":1779226073744,"traceId":"81a58f90c730f8ed"},{"name":"check-page","duration":878140,"timestamp":418101464211,"id":55,"parentId":19,"tags":{"page":"/node"},"startTime":1779226073710,"traceId":"81a58f90c730f8ed"},{"name":"is-page-static","duration":853018,"timestamp":418101497708,"id":100,"parentId":58,"tags":{},"startTime":1779226073744,"traceId":"81a58f90c730f8ed"},{"name":"check-page","duration":885577,"timestamp":418101465221,"id":58,"parentId":19,"tags":{"page":"/server-logs"},"startTime":1779226073711,"traceId":"81a58f90c730f8ed"},{"name":"is-page-static","duration":860397,"timestamp":418101497696,"id":99,"parentId":56,"tags":{},"startTime":1779226073744,"traceId":"81a58f90c730f8ed"},{"name":"check-page","duration":893738,"timestamp":418101464432,"id":56,"parentId":19,"tags":{"page":"/nodes"},"startTime":1779226073711,"traceId":"81a58f90c730f8ed"},{"name":"is-page-static","duration":861128,"timestamp":418101497817,"id":101,"parentId":59,"tags":{},"startTime":1779226073744,"traceId":"81a58f90c730f8ed"},{"name":"check-page","duration":893596,"timestamp":418101465440,"id":59,"parentId":19,"tags":{"page":"/settings/networks"},"startTime":1779226073712,"traceId":"81a58f90c730f8ed"},{"name":"is-page-static","duration":870187,"timestamp":418101497837,"id":102,"parentId":61,"tags":{},"startTime":1779226073744,"traceId":"81a58f90c730f8ed"},{"name":"check-page","duration":905962,"timestamp":418101466116,"id":61,"parentId":19,"tags":{"page":"/settings/tokens"},"startTime":1779226073712,"traceId":"81a58f90c730f8ed"},{"name":"is-page-static","duration":876293,"timestamp":418101497849,"id":103,"parentId":62,"tags":{},"startTime":1779226073744,"traceId":"81a58f90c730f8ed"},{"name":"check-page","duration":910180,"timestamp":418101466230,"id":62,"parentId":19,"tags":{"page":"/tasks/[id]"},"startTime":1779226073713,"traceId":"81a58f90c730f8ed"},{"name":"is-page-static","duration":878962,"timestamp":418101497663,"id":96,"parentId":53,"tags":{},"startTime":1779226073744,"traceId":"81a58f90c730f8ed"},{"name":"check-page","duration":912859,"timestamp":418101463811,"id":53,"parentId":19,"tags":{"page":"/logs"},"startTime":1779226073710,"traceId":"81a58f90c730f8ed"},{"name":"is-page-static","duration":878900,"timestamp":418101497857,"id":104,"parentId":63,"tags":{},"startTime":1779226073744,"traceId":"81a58f90c730f8ed"},{"name":"check-page","duration":910442,"timestamp":418101466341,"id":63,"parentId":19,"tags":{"page":"/tasks"},"startTime":1779226073713,"traceId":"81a58f90c730f8ed"},{"name":"is-page-static","duration":893786,"timestamp":418101486683,"id":92,"parentId":41,"tags":{},"startTime":1779226073733,"traceId":"81a58f90c730f8ed"},{"name":"check-page","duration":920435,"timestamp":418101460084,"id":41,"parentId":19,"tags":{"page":"/api/hub/server/[hostname]/agents"},"startTime":1779226073706,"traceId":"81a58f90c730f8ed"},{"name":"is-page-static","duration":854755,"timestamp":418101527759,"id":105,"parentId":57,"tags":{},"startTime":1779226073774,"traceId":"81a58f90c730f8ed"},{"name":"check-page","duration":917898,"timestamp":418101464663,"id":57,"parentId":19,"tags":{"page":"/"},"startTime":1779226073711,"traceId":"81a58f90c730f8ed"},{"name":"is-page-static","duration":846271,"timestamp":418101538388,"id":106,"parentId":60,"tags":{},"startTime":1779226073785,"traceId":"81a58f90c730f8ed"},{"name":"check-page","duration":919061,"timestamp":418101465645,"id":60,"parentId":19,"tags":{"page":"/settings"},"startTime":1779226073712,"traceId":"81a58f90c730f8ed"},{"name":"is-page-static","duration":888241,"timestamp":418101497608,"id":94,"parentId":23,"tags":{},"startTime":1779226073744,"traceId":"81a58f90c730f8ed"},{"name":"check-page","duration":930988,"timestamp":418101454905,"id":23,"parentId":19,"tags":{"page":"/admin"},"startTime":1779226073701,"traceId":"81a58f90c730f8ed"},{"name":"is-page-static","duration":891101,"timestamp":418101497671,"id":97,"parentId":54,"tags":{},"startTime":1779226073744,"traceId":"81a58f90c730f8ed"},{"name":"check-page","duration":924829,"timestamp":418101463988,"id":54,"parentId":19,"tags":{"page":"/messages"},"startTime":1779226073710,"traceId":"81a58f90c730f8ed"},{"name":"is-page-static","duration":899950,"timestamp":418101497649,"id":95,"parentId":52,"tags":{},"startTime":1779226073744,"traceId":"81a58f90c730f8ed"},{"name":"check-page","duration":934020,"timestamp":418101463641,"id":52,"parentId":19,"tags":{"page":"/login"},"startTime":1779226073710,"traceId":"81a58f90c730f8ed"},{"name":"static-check","duration":946599,"timestamp":418101451105,"id":19,"parentId":1,"tags":{},"startTime":1779226073697,"traceId":"81a58f90c730f8ed"}]
|
|
2
|
-
[{"name":"write-routes-manifest","duration":
|
|
1
|
+
[{"name":"generate-buildid","duration":340,"timestamp":518868817545,"id":4,"parentId":1,"tags":{},"startTime":1779326841064,"traceId":"6f84d0e609888c2a"},{"name":"load-custom-routes","duration":561,"timestamp":518868818072,"id":5,"parentId":1,"tags":{},"startTime":1779326841064,"traceId":"6f84d0e609888c2a"},{"name":"create-dist-dir","duration":1034,"timestamp":518868818709,"id":6,"parentId":1,"tags":{},"startTime":1779326841065,"traceId":"6f84d0e609888c2a"},{"name":"clean","duration":43132,"timestamp":518868820545,"id":7,"parentId":1,"tags":{},"startTime":1779326841067,"traceId":"6f84d0e609888c2a"},{"name":"discover-routes","duration":11959,"timestamp":518868959736,"id":8,"parentId":1,"tags":{},"startTime":1779326841206,"traceId":"6f84d0e609888c2a"},{"name":"create-root-mapping","duration":141,"timestamp":518868971766,"id":9,"parentId":1,"tags":{},"startTime":1779326841218,"traceId":"6f84d0e609888c2a"},{"name":"generate-route-types","duration":39732,"timestamp":518868974560,"id":10,"parentId":1,"tags":{},"startTime":1779326841221,"traceId":"6f84d0e609888c2a"},{"name":"public-dir-conflict-check","duration":108,"timestamp":518869014405,"id":11,"parentId":1,"tags":{},"startTime":1779326841261,"traceId":"6f84d0e609888c2a"},{"name":"generate-routes-manifest","duration":5510,"timestamp":518869014639,"id":12,"parentId":1,"tags":{},"startTime":1779326841261,"traceId":"6f84d0e609888c2a"},{"name":"run-turbopack","duration":8909891,"timestamp":518869029106,"id":14,"parentId":1,"tags":{},"startTime":1779326841275,"traceId":"6f84d0e609888c2a"},{"name":"turbopack-build-events","duration":100,"timestamp":518869385427,"id":15,"parentId":1,"tags":{},"startTime":1779326841632,"traceId":"6f84d0e609888c2a"},{"name":"run-typescript","duration":11637384,"timestamp":518877952747,"id":16,"parentId":1,"tags":{},"startTime":1779326850199,"traceId":"6f84d0e609888c2a"},{"name":"generate-required-server-files","duration":3138,"timestamp":518889591539,"id":18,"parentId":1,"tags":{},"startTime":1779326861838,"traceId":"6f84d0e609888c2a"},{"name":"check-static-error-page","duration":15188,"timestamp":518889803490,"id":20,"parentId":19,"tags":{},"startTime":1779326862050,"traceId":"6f84d0e609888c2a"},{"name":"is-page-static","duration":580953,"timestamp":518889822504,"id":65,"parentId":22,"tags":{},"startTime":1779326862069,"traceId":"6f84d0e609888c2a"},{"name":"check-page","duration":596823,"timestamp":518889806848,"id":22,"parentId":19,"tags":{"page":"/_global-error"},"startTime":1779326862053,"traceId":"6f84d0e609888c2a"},{"name":"is-page-static","duration":736391,"timestamp":518889822600,"id":66,"parentId":25,"tags":{},"startTime":1779326862069,"traceId":"6f84d0e609888c2a"},{"name":"check-page","duration":748916,"timestamp":518889810208,"id":25,"parentId":19,"tags":{"page":"/api/auth/login"},"startTime":1779326862056,"traceId":"6f84d0e609888c2a"},{"name":"is-page-static","duration":763733,"timestamp":518889822200,"id":64,"parentId":21,"tags":{},"startTime":1779326862068,"traceId":"6f84d0e609888c2a"},{"name":"check-page","duration":781635,"timestamp":518889805235,"id":21,"parentId":19,"tags":{"page":"/_not-found"},"startTime":1779326862052,"traceId":"6f84d0e609888c2a"},{"name":"is-page-static","duration":764011,"timestamp":518889823116,"id":71,"parentId":30,"tags":{},"startTime":1779326862069,"traceId":"6f84d0e609888c2a"},{"name":"check-page","duration":776229,"timestamp":518889810941,"id":30,"parentId":19,"tags":{"page":"/api/hub/broadcast"},"startTime":1779326862057,"traceId":"6f84d0e609888c2a"},{"name":"is-page-static","duration":772508,"timestamp":518889823178,"id":72,"parentId":32,"tags":{},"startTime":1779326862069,"traceId":"6f84d0e609888c2a"},{"name":"check-page","duration":784401,"timestamp":518889811363,"id":32,"parentId":19,"tags":{"page":"/api/hub/health"},"startTime":1779326862058,"traceId":"6f84d0e609888c2a"},{"name":"is-page-static","duration":788341,"timestamp":518889823432,"id":74,"parentId":34,"tags":{},"startTime":1779326862070,"traceId":"6f84d0e609888c2a"},{"name":"check-page","duration":800198,"timestamp":518889811658,"id":34,"parentId":19,"tags":{"page":"/api/hub/license"},"startTime":1779326862058,"traceId":"6f84d0e609888c2a"},{"name":"is-page-static","duration":796291,"timestamp":518889823463,"id":75,"parentId":35,"tags":{},"startTime":1779326862070,"traceId":"6f84d0e609888c2a"},{"name":"check-page","duration":808025,"timestamp":518889811800,"id":35,"parentId":19,"tags":{"page":"/api/hub/messages"},"startTime":1779326862058,"traceId":"6f84d0e609888c2a"},{"name":"is-page-static","duration":800829,"timestamp":518889823512,"id":77,"parentId":37,"tags":{},"startTime":1779326862070,"traceId":"6f84d0e609888c2a"},{"name":"check-page","duration":811956,"timestamp":518889812448,"id":37,"parentId":19,"tags":{"page":"/api/hub/nodes"},"startTime":1779326862059,"traceId":"6f84d0e609888c2a"},{"name":"is-page-static","duration":805875,"timestamp":518889823526,"id":78,"parentId":38,"tags":{},"startTime":1779326862070,"traceId":"6f84d0e609888c2a"},{"name":"check-page","duration":816915,"timestamp":518889812542,"id":38,"parentId":19,"tags":{"page":"/api/hub/register"},"startTime":1779326862059,"traceId":"6f84d0e609888c2a"},{"name":"is-page-static","duration":810153,"timestamp":518889823541,"id":79,"parentId":39,"tags":{},"startTime":1779326862070,"traceId":"6f84d0e609888c2a"},{"name":"check-page","duration":821135,"timestamp":518889812615,"id":39,"parentId":19,"tags":{"page":"/api/hub/send"},"startTime":1779326862059,"traceId":"6f84d0e609888c2a"},{"name":"is-page-static","duration":813388,"timestamp":518889823484,"id":76,"parentId":36,"tags":{},"startTime":1779326862070,"traceId":"6f84d0e609888c2a"},{"name":"check-page","duration":824631,"timestamp":518889812296,"id":36,"parentId":19,"tags":{"page":"/api/hub/networks"},"startTime":1779326862059,"traceId":"6f84d0e609888c2a"},{"name":"is-page-static","duration":818674,"timestamp":518889823555,"id":80,"parentId":40,"tags":{},"startTime":1779326862070,"traceId":"6f84d0e609888c2a"},{"name":"check-page","duration":829605,"timestamp":518889812679,"id":40,"parentId":19,"tags":{"page":"/api/hub/server-logs"},"startTime":1779326862059,"traceId":"6f84d0e609888c2a"},{"name":"is-page-static","duration":819779,"timestamp":518889823576,"id":82,"parentId":44,"tags":{},"startTime":1779326862070,"traceId":"6f84d0e609888c2a"},{"name":"check-page","duration":830016,"timestamp":518889813384,"id":44,"parentId":19,"tags":{"page":"/api/hub/session"},"startTime":1779326862060,"traceId":"6f84d0e609888c2a"},{"name":"is-page-static","duration":824596,"timestamp":518889823588,"id":83,"parentId":45,"tags":{},"startTime":1779326862070,"traceId":"6f84d0e609888c2a"},{"name":"check-page","duration":834700,"timestamp":518889813528,"id":45,"parentId":19,"tags":{"page":"/api/hub/stats"},"startTime":1779326862060,"traceId":"6f84d0e609888c2a"},{"name":"is-page-static","duration":829548,"timestamp":518889823599,"id":84,"parentId":46,"tags":{},"startTime":1779326862070,"traceId":"6f84d0e609888c2a"},{"name":"check-page","duration":839581,"timestamp":518889813620,"id":46,"parentId":19,"tags":{"page":"/api/hub/status"},"startTime":1779326862060,"traceId":"6f84d0e609888c2a"},{"name":"is-page-static","duration":834090,"timestamp":518889823607,"id":85,"parentId":47,"tags":{},"startTime":1779326862070,"traceId":"6f84d0e609888c2a"},{"name":"check-page","duration":844053,"timestamp":518889813696,"id":47,"parentId":19,"tags":{"page":"/api/hub/task-events"},"startTime":1779326862060,"traceId":"6f84d0e609888c2a"},{"name":"is-page-static","duration":838547,"timestamp":518889823639,"id":86,"parentId":48,"tags":{},"startTime":1779326862070,"traceId":"6f84d0e609888c2a"},{"name":"check-page","duration":848486,"timestamp":518889813765,"id":48,"parentId":19,"tags":{"page":"/api/hub/tasks"},"startTime":1779326862060,"traceId":"6f84d0e609888c2a"},{"name":"is-page-static","duration":844880,"timestamp":518889823652,"id":87,"parentId":49,"tags":{},"startTime":1779326862070,"traceId":"6f84d0e609888c2a"},{"name":"check-page","duration":853162,"timestamp":518889815410,"id":49,"parentId":19,"tags":{"page":"/api/hub/tmux"},"startTime":1779326862062,"traceId":"6f84d0e609888c2a"},{"name":"is-page-static","duration":848962,"timestamp":518889823567,"id":81,"parentId":42,"tags":{},"startTime":1779326862070,"traceId":"6f84d0e609888c2a"},{"name":"check-page","duration":859654,"timestamp":518889812936,"id":42,"parentId":19,"tags":{"page":"/api/hub/server/[hostname]/health"},"startTime":1779326862059,"traceId":"6f84d0e609888c2a"},{"name":"is-page-static","duration":849073,"timestamp":518889823665,"id":88,"parentId":50,"tags":{},"startTime":1779326862070,"traceId":"6f84d0e609888c2a"},{"name":"check-page","duration":857244,"timestamp":518889815532,"id":50,"parentId":19,"tags":{"page":"/api/hub/tokens"},"startTime":1779326862062,"traceId":"6f84d0e609888c2a"},{"name":"is-page-static","duration":852776,"timestamp":518889827589,"id":90,"parentId":24,"tags":{},"startTime":1779326862074,"traceId":"6f84d0e609888c2a"},{"name":"check-page","duration":872864,"timestamp":518889807559,"id":24,"parentId":19,"tags":{"page":"/api/anet/config"},"startTime":1779326862054,"traceId":"6f84d0e609888c2a"},{"name":"is-page-static","duration":854676,"timestamp":518889828748,"id":91,"parentId":31,"tags":{},"startTime":1779326862075,"traceId":"6f84d0e609888c2a"},{"name":"check-page","duration":872385,"timestamp":518889811086,"id":31,"parentId":19,"tags":{"page":"/api/hub/events"},"startTime":1779326862057,"traceId":"6f84d0e609888c2a"},{"name":"is-page-static","duration":865511,"timestamp":518889823675,"id":89,"parentId":51,"tags":{},"startTime":1779326862070,"traceId":"6f84d0e609888c2a"},{"name":"check-page","duration":873633,"timestamp":518889815609,"id":51,"parentId":19,"tags":{"page":"/favicon.ico"},"startTime":1779326862062,"traceId":"6f84d0e609888c2a"},{"name":"is-page-static","duration":864235,"timestamp":518889829616,"id":92,"parentId":41,"tags":{},"startTime":1779326862076,"traceId":"6f84d0e609888c2a"},{"name":"check-page","duration":881159,"timestamp":518889812741,"id":41,"parentId":19,"tags":{"page":"/api/hub/server/[hostname]/agents"},"startTime":1779326862059,"traceId":"6f84d0e609888c2a"},{"name":"is-page-static","duration":866192,"timestamp":518889830738,"id":93,"parentId":43,"tags":{},"startTime":1779326862077,"traceId":"6f84d0e609888c2a"},{"name":"check-page","duration":883886,"timestamp":518889813090,"id":43,"parentId":19,"tags":{"page":"/api/hub/servers"},"startTime":1779326862059,"traceId":"6f84d0e609888c2a"},{"name":"is-page-static","duration":899959,"timestamp":518889822971,"id":70,"parentId":29,"tags":{},"startTime":1779326862069,"traceId":"6f84d0e609888c2a"},{"name":"check-page","duration":912252,"timestamp":518889810793,"id":29,"parentId":19,"tags":{"page":"/api/hub/auth"},"startTime":1779326862057,"traceId":"6f84d0e609888c2a"},{"name":"is-page-static","duration":915547,"timestamp":518889822801,"id":69,"parentId":28,"tags":{},"startTime":1779326862069,"traceId":"6f84d0e609888c2a"},{"name":"check-page","duration":927762,"timestamp":518889810665,"id":28,"parentId":19,"tags":{"page":"/api/hub/audit-log"},"startTime":1779326862057,"traceId":"6f84d0e609888c2a"},{"name":"is-page-static","duration":958481,"timestamp":518889822669,"id":67,"parentId":26,"tags":{},"startTime":1779326862069,"traceId":"6f84d0e609888c2a"},{"name":"check-page","duration":970836,"timestamp":518889810402,"id":26,"parentId":19,"tags":{"page":"/api/auth/logout"},"startTime":1779326862057,"traceId":"6f84d0e609888c2a"},{"name":"is-page-static","duration":966322,"timestamp":518889832924,"id":94,"parentId":23,"tags":{},"startTime":1779326862079,"traceId":"6f84d0e609888c2a"},{"name":"check-page","duration":992197,"timestamp":518889807157,"id":23,"parentId":19,"tags":{"page":"/admin"},"startTime":1779326862053,"traceId":"6f84d0e609888c2a"},{"name":"is-page-static","duration":980663,"timestamp":518889823356,"id":73,"parentId":33,"tags":{},"startTime":1779326862070,"traceId":"6f84d0e609888c2a"},{"name":"check-page","duration":992574,"timestamp":518889811516,"id":33,"parentId":19,"tags":{"page":"/api/hub/inbox"},"startTime":1779326862058,"traceId":"6f84d0e609888c2a"},{"name":"is-page-static","duration":970044,"timestamp":518889837148,"id":99,"parentId":56,"tags":{},"startTime":1779326862083,"traceId":"6f84d0e609888c2a"},{"name":"check-page","duration":990751,"timestamp":518889816492,"id":56,"parentId":19,"tags":{"page":"/nodes"},"startTime":1779326862063,"traceId":"6f84d0e609888c2a"},{"name":"is-page-static","duration":984073,"timestamp":518889837336,"id":101,"parentId":59,"tags":{},"startTime":1779326862084,"traceId":"6f84d0e609888c2a"},{"name":"check-page","duration":1004033,"timestamp":518889817448,"id":59,"parentId":19,"tags":{"page":"/settings/networks"},"startTime":1779326862064,"traceId":"6f84d0e609888c2a"},{"name":"is-page-static","duration":989599,"timestamp":518889832953,"id":95,"parentId":52,"tags":{},"startTime":1779326862079,"traceId":"6f84d0e609888c2a"},{"name":"check-page","duration":1006741,"timestamp":518889815894,"id":52,"parentId":19,"tags":{"page":"/login"},"startTime":1779326862062,"traceId":"6f84d0e609888c2a"},{"name":"is-page-static","duration":988022,"timestamp":518889837199,"id":100,"parentId":58,"tags":{},"startTime":1779326862083,"traceId":"6f84d0e609888c2a"},{"name":"check-page","duration":1008232,"timestamp":518889817039,"id":58,"parentId":19,"tags":{"page":"/server-logs"},"startTime":1779326862063,"traceId":"6f84d0e609888c2a"},{"name":"is-page-static","duration":994075,"timestamp":518889837359,"id":102,"parentId":61,"tags":{},"startTime":1779326862084,"traceId":"6f84d0e609888c2a"},{"name":"check-page","duration":1013408,"timestamp":518889818101,"id":61,"parentId":19,"tags":{"page":"/settings/tokens"},"startTime":1779326862064,"traceId":"6f84d0e609888c2a"},{"name":"is-page-static","duration":987162,"timestamp":518889851237,"id":105,"parentId":60,"tags":{},"startTime":1779326862098,"traceId":"6f84d0e609888c2a"},{"name":"check-page","duration":1020797,"timestamp":518889817653,"id":60,"parentId":19,"tags":{"page":"/settings"},"startTime":1779326862064,"traceId":"6f84d0e609888c2a"},{"name":"is-page-static","duration":1003986,"timestamp":518889837381,"id":104,"parentId":63,"tags":{},"startTime":1779326862084,"traceId":"6f84d0e609888c2a"},{"name":"check-page","duration":1022988,"timestamp":518889818435,"id":63,"parentId":19,"tags":{"page":"/tasks"},"startTime":1779326862065,"traceId":"6f84d0e609888c2a"},{"name":"is-page-static","duration":1012291,"timestamp":518889832964,"id":96,"parentId":53,"tags":{},"startTime":1779326862079,"traceId":"6f84d0e609888c2a"},{"name":"check-page","duration":1029264,"timestamp":518889816037,"id":53,"parentId":19,"tags":{"page":"/logs"},"startTime":1779326862062,"traceId":"6f84d0e609888c2a"},{"name":"is-page-static","duration":1010459,"timestamp":518889837369,"id":103,"parentId":62,"tags":{},"startTime":1779326862084,"traceId":"6f84d0e609888c2a"},{"name":"check-page","duration":1029614,"timestamp":518889818263,"id":62,"parentId":19,"tags":{"page":"/tasks/[id]"},"startTime":1779326862065,"traceId":"6f84d0e609888c2a"},{"name":"is-page-static","duration":983224,"timestamp":518889867651,"id":106,"parentId":57,"tags":{},"startTime":1779326862114,"traceId":"6f84d0e609888c2a"},{"name":"check-page","duration":1034266,"timestamp":518889816663,"id":57,"parentId":19,"tags":{"page":"/"},"startTime":1779326862063,"traceId":"6f84d0e609888c2a"},{"name":"is-page-static","duration":1062692,"timestamp":518889822735,"id":68,"parentId":27,"tags":{},"startTime":1779326862069,"traceId":"6f84d0e609888c2a"},{"name":"check-page","duration":1075005,"timestamp":518889810524,"id":27,"parentId":19,"tags":{"page":"/api/auth/v3"},"startTime":1779326862057,"traceId":"6f84d0e609888c2a"},{"name":"is-page-static","duration":1062044,"timestamp":518889832992,"id":98,"parentId":55,"tags":{},"startTime":1779326862079,"traceId":"6f84d0e609888c2a"},{"name":"check-page","duration":1078785,"timestamp":518889816336,"id":55,"parentId":19,"tags":{"page":"/node"},"startTime":1779326862063,"traceId":"6f84d0e609888c2a"},{"name":"is-page-static","duration":1064539,"timestamp":518889832978,"id":97,"parentId":54,"tags":{},"startTime":1779326862079,"traceId":"6f84d0e609888c2a"},{"name":"check-page","duration":1081401,"timestamp":518889816182,"id":54,"parentId":19,"tags":{"page":"/messages"},"startTime":1779326862062,"traceId":"6f84d0e609888c2a"},{"name":"static-check","duration":1095343,"timestamp":518889802289,"id":19,"parentId":1,"tags":{},"startTime":1779326862049,"traceId":"6f84d0e609888c2a"}]
|
|
2
|
+
[{"name":"write-routes-manifest","duration":531,"timestamp":518890911039,"id":108,"parentId":1,"tags":{},"startTime":1779326863157,"traceId":"6f84d0e609888c2a"},{"name":"load-dotenv","duration":66,"timestamp":518890925745,"id":111,"parentId":110,"tags":{},"startTime":1779326863172,"traceId":"6f84d0e609888c2a"},{"name":"run-export-path-map","duration":707,"timestamp":518890931593,"id":112,"parentId":110,"tags":{},"startTime":1779326863178,"traceId":"6f84d0e609888c2a"},{"name":"next-export","duration":691284,"timestamp":518890924284,"id":110,"parentId":1,"tags":{},"startTime":1779326863171,"traceId":"6f84d0e609888c2a"},{"name":"move-exported-app-not-found-","duration":618,"timestamp":518891619421,"id":113,"parentId":109,"tags":{},"startTime":1779326863866,"traceId":"6f84d0e609888c2a"},{"name":"move-exported-app-global-error-","duration":392,"timestamp":518891620158,"id":114,"parentId":109,"tags":{},"startTime":1779326863866,"traceId":"6f84d0e609888c2a"},{"name":"static-generation","duration":706506,"timestamp":518890916245,"id":109,"parentId":1,"tags":{},"startTime":1779326863163,"traceId":"6f84d0e609888c2a"},{"name":"write-routes-manifest","duration":1317,"timestamp":518891623114,"id":115,"parentId":1,"tags":{},"startTime":1779326863869,"traceId":"6f84d0e609888c2a"},{"name":"print-tree-view","duration":5127,"timestamp":518891646953,"id":116,"parentId":1,"tags":{},"startTime":1779326863893,"traceId":"6f84d0e609888c2a"},{"name":"write-route-bundle-stats","duration":17218,"timestamp":518891652120,"id":117,"parentId":1,"tags":{},"startTime":1779326863898,"traceId":"6f84d0e609888c2a"},{"name":"telemetry-flush","duration":12703,"timestamp":518891669384,"id":118,"parentId":1,"tags":{},"startTime":1779326863916,"traceId":"6f84d0e609888c2a"},{"name":"next-build","duration":22930244,"timestamp":518868751895,"id":1,"tags":{"buildMode":"default","version":"16.2.3","bundler":"turbopack","has-custom-webpack-config":"false","use-build-worker":"true"},"startTime":1779326840998,"traceId":"6f84d0e609888c2a"}]
|
package/.next/trace-build
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
[{"name":"run-turbopack","duration":
|
|
1
|
+
[{"name":"run-turbopack","duration":8909891,"timestamp":518869029106,"id":14,"parentId":1,"tags":{},"startTime":1779326841275,"traceId":"6f84d0e609888c2a"},{"name":"turbopack-build-events","duration":100,"timestamp":518869385427,"id":15,"parentId":1,"tags":{},"startTime":1779326841632,"traceId":"6f84d0e609888c2a"},{"name":"run-typescript","duration":11637384,"timestamp":518877952747,"id":16,"parentId":1,"tags":{},"startTime":1779326850199,"traceId":"6f84d0e609888c2a"},{"name":"static-check","duration":1095343,"timestamp":518889802289,"id":19,"parentId":1,"tags":{},"startTime":1779326862049,"traceId":"6f84d0e609888c2a"},{"name":"static-generation","duration":706506,"timestamp":518890916245,"id":109,"parentId":1,"tags":{},"startTime":1779326863163,"traceId":"6f84d0e609888c2a"},{"name":"telemetry-flush","duration":12703,"timestamp":518891669384,"id":118,"parentId":1,"tags":{},"startTime":1779326863916,"traceId":"6f84d0e609888c2a"},{"name":"next-build","duration":22930244,"timestamp":518868751895,"id":1,"tags":{"buildMode":"default","version":"16.2.3","bundler":"turbopack","has-custom-webpack-config":"false","use-build-worker":"true"},"startTime":1779326840998,"traceId":"6f84d0e609888c2a"}]
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { requireDashboardAuth, getV3UserToken } from '@/app/lib/dashboard-auth';
|
|
2
|
+
import { dedupeByHostname, parseHubTime, type HubServerRow } from '@/app/lib/serverDedupe';
|
|
2
3
|
|
|
3
4
|
const HUB_URL = process.env.COMMHUB_URL || 'http://127.0.0.1:9200';
|
|
4
5
|
|
|
@@ -32,35 +33,8 @@ async function hubHeaders(): Promise<Record<string, string>> {
|
|
|
32
33
|
* field in 0.8.1-preview.5.
|
|
33
34
|
*/
|
|
34
35
|
|
|
35
|
-
interface HubServerRow {
|
|
36
|
-
hostname: string;
|
|
37
|
-
ip?: string | null;
|
|
38
|
-
agent_count?: number;
|
|
39
|
-
cpu_load_1min?: number | null;
|
|
40
|
-
cpu_cores?: number | null;
|
|
41
|
-
mem_used_gb?: number | null;
|
|
42
|
-
mem_total_gb?: number | null;
|
|
43
|
-
mem_avail_gb?: number | null;
|
|
44
|
-
disk_used_gb?: number | null;
|
|
45
|
-
disk_total_gb?: number | null;
|
|
46
|
-
cpu_history?: number[];
|
|
47
|
-
mem_history?: number[];
|
|
48
|
-
agents?: unknown[];
|
|
49
|
-
last_seen?: string | null;
|
|
50
|
-
status?: 'online' | 'offline';
|
|
51
|
-
note?: string;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
36
|
function freshnessStatus(lastSeen: string | null | undefined): 'online' | 'offline' {
|
|
55
|
-
|
|
56
|
-
// commhub-server@0.8.1-preview.5 reports last_seen in "YYYY-MM-DD
|
|
57
|
-
// HH:MM:SS" (space-separated, no timezone). Treat as UTC so all
|
|
58
|
-
// clients agree regardless of their local zone. If a later hub
|
|
59
|
-
// upgrade switches to ISO 8601 with explicit timezone, Date.parse
|
|
60
|
-
// will accept either format and the +'Z' suffix is harmless.
|
|
61
|
-
const iso = lastSeen.includes('T') ? lastSeen : lastSeen.replace(' ', 'T');
|
|
62
|
-
const withTz = /[zZ]|[+-]\d{2}:?\d{2}$/.test(iso) ? iso : iso + 'Z';
|
|
63
|
-
const t = Date.parse(withTz);
|
|
37
|
+
const t = parseHubTime(lastSeen);
|
|
64
38
|
if (Number.isNaN(t)) return 'offline';
|
|
65
39
|
// 90s freshness window — wider than the agent-node 30s report
|
|
66
40
|
// cadence to absorb network latency + clock drift between client
|
|
@@ -117,7 +91,7 @@ export async function GET() {
|
|
|
117
91
|
? raw.servers
|
|
118
92
|
: [];
|
|
119
93
|
return Response.json({
|
|
120
|
-
servers: rows.map(normalizeServer),
|
|
94
|
+
servers: dedupeByHostname(rows).map(normalizeServer),
|
|
121
95
|
unavailable: raw?.unavailable === true,
|
|
122
96
|
});
|
|
123
97
|
} catch (e: unknown) {
|
|
@@ -5304,7 +5304,10 @@ export function TopoGraph({ sessions, sseSessions, renameSignal }: TopoGraphProp
|
|
|
5304
5304
|
/* R742 — entrance family +1 member: title-block joins
|
|
5305
5305
|
canvas root as 2nd one-shot-mount surface. Staggered
|
|
5306
5306
|
choreography: canvas 0-600ms, title-block 200-700ms. */
|
|
5307
|
-
|
|
5307
|
+
/* R743 — entrance family +1 → 3 members: chrome strip joins
|
|
5308
|
+
canvas root + title-block, completing the entrance trio.
|
|
5309
|
+
3-stage cascade: 0-600 / 200-700 / 400-900 ms. */
|
|
5310
|
+
{ mode: "one-shot-mount", family: "entrance", members: 3, examples: ["canvas root", "title-block", "chrome strip"] },
|
|
5308
5311
|
])}
|
|
5309
5312
|
data-topo-pinned-aspect={(() => {
|
|
5310
5313
|
const aspects: string[] = [];
|
|
@@ -16909,7 +16912,22 @@ export function TopoGraph({ sessions, sseSessions, renameSignal }: TopoGraphProp
|
|
|
16909
16912
|
for the overlap-test (chrome is HTML overlay on top of
|
|
16910
16913
|
the SVG, not part of the viewBox 1000x680 surface; ring
|
|
16911
16914
|
r=325 / grid gx0 layout untouched). */}
|
|
16912
|
-
|
|
16915
|
+
{/* Round 743 / Loop — chrome strip joins entrance family as 3rd
|
|
16916
|
+
one-shot-mount member, completing the entrance TRIO. Three-
|
|
16917
|
+
stage cascading "settle in" wave:
|
|
16918
|
+
R740 canvas 0 → 600 ms scale 0.99→1, opacity 0.8→1
|
|
16919
|
+
R742 title-block 200 → 700 ms translateY -4→0, opacity 0.7→1
|
|
16920
|
+
R743 chrome strip 400 → 900 ms translateX 8→0, opacity 0.7→1
|
|
16921
|
+
Each stage starts 200 ms after the prior — the canvas
|
|
16922
|
+
arrives, the heading writes in, then the chrome strip slides
|
|
16923
|
+
in from the right edge. translateX (not translateY) because
|
|
16924
|
+
the chrome strip lives at the right edge — sliding in from
|
|
16925
|
+
its own edge reads as "docking into place".
|
|
16926
|
+
Chrome strip wrapper is plain HTML with no existing
|
|
16927
|
+
animation, so a simple single-animation class suffices (no
|
|
16928
|
+
compound needed, unlike R742's title-block). Gated by
|
|
16929
|
+
reducedMotion at JSX level. See globals.css R743 block. */}
|
|
16930
|
+
<div className={`absolute bottom-4 right-4 flex items-center gap-2 text-xs select-none${reducedMotion ? '' : ' anet-topo-chrome-strip-entrance'}`} data-topo-chrome data-topo-chrome-entrance={reducedMotion ? 'false' : 'true'}>
|
|
16913
16931
|
{/* #113: node size — S / M / L segmented control (Vincent 4727).
|
|
16914
16932
|
R154: stable data-* hooks for tests + focus-visible ring so
|
|
16915
16933
|
keyboard navigation lands somewhere visible against the
|
package/app/globals.css
CHANGED
|
@@ -1748,6 +1748,31 @@ body {
|
|
|
1748
1748
|
.anet-topo-title-block-entrance { animation: none; }
|
|
1749
1749
|
}
|
|
1750
1750
|
|
|
1751
|
+
/* Round 743 — chrome strip entrance, 3rd member of the entrance family,
|
|
1752
|
+
completing the entrance TRIO. Three-stage cascade:
|
|
1753
|
+
R740 canvas 0 → 600 ms scale 0.99→1, opacity 0.8→1
|
|
1754
|
+
R742 title-block 200 → 700 ms translateY -4→0, opacity 0.7→1
|
|
1755
|
+
R743 chrome strip 400 → 900 ms translateX 8→0, opacity 0.7→1
|
|
1756
|
+
Each stage offset +200 ms. translateX (not translateY) because the
|
|
1757
|
+
chrome strip docks at the canvas right edge — sliding in from its
|
|
1758
|
+
own edge reads as "docking into place".
|
|
1759
|
+
|
|
1760
|
+
The chrome strip wrapper div has no other animation, so a plain
|
|
1761
|
+
single-animation class works here (no compound needed like R742's
|
|
1762
|
+
title-block which collided with R706 envelope-breath). One-shot —
|
|
1763
|
+
no `infinite`, runs once per mount. prefers-reduced-motion JSX gate
|
|
1764
|
+
+ CSS @media guard. */
|
|
1765
|
+
@keyframes anet-topo-chrome-strip-entrance-kf {
|
|
1766
|
+
0% { transform: translateX(8px); opacity: 0.7; }
|
|
1767
|
+
100% { transform: translateX(0); opacity: 1; }
|
|
1768
|
+
}
|
|
1769
|
+
.anet-topo-chrome-strip-entrance {
|
|
1770
|
+
animation: anet-topo-chrome-strip-entrance-kf 500ms ease-out 400ms backwards;
|
|
1771
|
+
}
|
|
1772
|
+
@media (prefers-reduced-motion: reduce) {
|
|
1773
|
+
.anet-topo-chrome-strip-entrance { animation: none; }
|
|
1774
|
+
}
|
|
1775
|
+
|
|
1751
1776
|
/* Round 707 — chrome Layout wrapper at-rest breath at 17 s. Slowest tier
|
|
1752
1777
|
among HTML chrome respiratory anchors (sibling to R703 zoom-level 9 s
|
|
1753
1778
|
in the chrome strip's data tier; this 17 s lands in the chrome strip's
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* #157 RC#2 — host telemetry row dedup for the Servers panel.
|
|
3
|
+
*
|
|
4
|
+
* The CommHub /api/servers endpoint keys host telemetry by (hostname,
|
|
5
|
+
* ip): a machine whose agents report over more than one interface
|
|
6
|
+
* yields one row per IP. Live data caught `iZrj93pr2rcf5r2y9uo1oyZ`
|
|
7
|
+
* twice — once at the Docker-bridge IP (carrying cpu/mem telemetry)
|
|
8
|
+
* and once at loopback (telemetry null) — so the panel showed the same
|
|
9
|
+
* physical host as two cards with split agent counts.
|
|
10
|
+
*
|
|
11
|
+
* Extracted from the /api/hub/servers route handler so the merge can
|
|
12
|
+
* be unit-tested against a mock fixture independently of the proxy.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
export interface HubServerRow {
|
|
16
|
+
hostname: string;
|
|
17
|
+
ip?: string | null;
|
|
18
|
+
agent_count?: number;
|
|
19
|
+
cpu_load_1min?: number | null;
|
|
20
|
+
cpu_cores?: number | null;
|
|
21
|
+
mem_used_gb?: number | null;
|
|
22
|
+
mem_total_gb?: number | null;
|
|
23
|
+
mem_avail_gb?: number | null;
|
|
24
|
+
disk_used_gb?: number | null;
|
|
25
|
+
disk_total_gb?: number | null;
|
|
26
|
+
cpu_history?: number[];
|
|
27
|
+
mem_history?: number[];
|
|
28
|
+
agents?: unknown[];
|
|
29
|
+
last_seen?: string | null;
|
|
30
|
+
status?: 'online' | 'offline';
|
|
31
|
+
note?: string;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Parse a hub timestamp to epoch ms. CommHub reports last_seen as
|
|
36
|
+
* "YYYY-MM-DD HH:MM:SS" (space-separated, no timezone) — treat as UTC
|
|
37
|
+
* so all clients agree regardless of local zone. ISO 8601 with an
|
|
38
|
+
* explicit offset also parses cleanly (the +'Z' is only appended when
|
|
39
|
+
* no zone is present). Returns NaN for missing / unparseable input.
|
|
40
|
+
*/
|
|
41
|
+
export function parseHubTime(ts: string | null | undefined): number {
|
|
42
|
+
if (!ts) return NaN;
|
|
43
|
+
const iso = ts.includes('T') ? ts : ts.replace(' ', 'T');
|
|
44
|
+
const withTz = /[zZ]|[+-]\d{2}:?\d{2}$/.test(iso) ? iso : iso + 'Z';
|
|
45
|
+
return Date.parse(withTz);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Collapse rows that share a hostname into one card.
|
|
50
|
+
*
|
|
51
|
+
* Dedup keys on hostname, not IP: a hostname is the machine identity,
|
|
52
|
+
* whereas an IP can be shared across hosts behind NAT (two distinct
|
|
53
|
+
* hostnames can surface as the same public IP) or differ per interface
|
|
54
|
+
* on one host. Merge rule for a multi-row hostname:
|
|
55
|
+
* - agent_count = sum across rows (one host's total fan-out)
|
|
56
|
+
* - telemetry = freshest-non-null per field — walk rows newest
|
|
57
|
+
* last_seen first, take the first row that actually
|
|
58
|
+
* reports each field, so a stale-but-telemetried row
|
|
59
|
+
* still contributes cpu/mem when the freshest row's
|
|
60
|
+
* values are null
|
|
61
|
+
* - last_seen = newest across rows
|
|
62
|
+
* - agents[] = union, dedup by alias
|
|
63
|
+
*
|
|
64
|
+
* Sentinel hostnames that are not real identities — empty or the
|
|
65
|
+
* literal "unknown" the hub emits when an agent never resolved its
|
|
66
|
+
* host — are passed through untouched: merging two distinct unknown
|
|
67
|
+
* machines into one card would be worse than showing both.
|
|
68
|
+
*/
|
|
69
|
+
export function dedupeByHostname(rows: HubServerRow[]): HubServerRow[] {
|
|
70
|
+
const groups = new Map<string, HubServerRow[]>();
|
|
71
|
+
const passthrough: HubServerRow[] = [];
|
|
72
|
+
for (const row of rows) {
|
|
73
|
+
const h = row.hostname;
|
|
74
|
+
if (!h || h === 'unknown') { passthrough.push(row); continue; }
|
|
75
|
+
const bucket = groups.get(h) ?? [];
|
|
76
|
+
bucket.push(row);
|
|
77
|
+
groups.set(h, bucket);
|
|
78
|
+
}
|
|
79
|
+
const merged: HubServerRow[] = [];
|
|
80
|
+
for (const bucket of groups.values()) {
|
|
81
|
+
if (bucket.length === 1) { merged.push(bucket[0]); continue; }
|
|
82
|
+
// Freshest last_seen first. NaN (missing timestamp) sorts last.
|
|
83
|
+
const sorted = [...bucket].sort((a, b) => {
|
|
84
|
+
const ta = parseHubTime(a.last_seen), tb = parseHubTime(b.last_seen);
|
|
85
|
+
return (Number.isNaN(tb) ? -Infinity : tb) - (Number.isNaN(ta) ? -Infinity : ta);
|
|
86
|
+
});
|
|
87
|
+
const coalesce = <K extends keyof HubServerRow>(key: K): HubServerRow[K] | undefined => {
|
|
88
|
+
for (const r of sorted) {
|
|
89
|
+
const v = r[key];
|
|
90
|
+
if (v != null) return v;
|
|
91
|
+
}
|
|
92
|
+
return undefined;
|
|
93
|
+
};
|
|
94
|
+
const agentMap = new Map<string, unknown>();
|
|
95
|
+
for (const r of sorted) {
|
|
96
|
+
if (!Array.isArray(r.agents)) continue;
|
|
97
|
+
for (const a of r.agents) {
|
|
98
|
+
const key = (a as { alias?: string })?.alias ?? JSON.stringify(a);
|
|
99
|
+
if (!agentMap.has(key)) agentMap.set(key, a);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
merged.push({
|
|
103
|
+
hostname: sorted[0].hostname,
|
|
104
|
+
ip: coalesce('ip') ?? null,
|
|
105
|
+
agent_count: bucket.reduce((sum, r) => sum + (r.agent_count ?? 0), 0),
|
|
106
|
+
cpu_load_1min: coalesce('cpu_load_1min') ?? null,
|
|
107
|
+
cpu_cores: coalesce('cpu_cores') ?? null,
|
|
108
|
+
mem_used_gb: coalesce('mem_used_gb') ?? null,
|
|
109
|
+
mem_total_gb: coalesce('mem_total_gb') ?? null,
|
|
110
|
+
mem_avail_gb: coalesce('mem_avail_gb') ?? null,
|
|
111
|
+
disk_used_gb: coalesce('disk_used_gb') ?? null,
|
|
112
|
+
disk_total_gb: coalesce('disk_total_gb') ?? null,
|
|
113
|
+
cpu_history: coalesce('cpu_history'),
|
|
114
|
+
mem_history: coalesce('mem_history'),
|
|
115
|
+
agents: agentMap.size > 0 ? [...agentMap.values()] : undefined,
|
|
116
|
+
last_seen: coalesce('last_seen') ?? null,
|
|
117
|
+
status: coalesce('status'),
|
|
118
|
+
note: coalesce('note'),
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
return [...merged, ...passthrough];
|
|
122
|
+
}
|
package/package.json
CHANGED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/* #157 RC#2 verification — Servers panel hostname dedup.
|
|
2
|
+
*
|
|
3
|
+
* Bug (Vincent 5560 + live re-probe 2026-05-20): the hub /api/servers
|
|
4
|
+
* endpoint keys host telemetry by (hostname, ip), so a machine whose
|
|
5
|
+
* agents report over more than one interface surfaces as multiple
|
|
6
|
+
* rows. `iZrj93pr2rcf5r2y9uo1oyZ` appeared twice — Docker-bridge IP
|
|
7
|
+
* (telemetry-bearing) + loopback (telemetry null) — splitting its
|
|
8
|
+
* agent count across two cards.
|
|
9
|
+
*
|
|
10
|
+
* Fix: `dedupeByHostname` in app/lib/serverDedupe.ts, applied in the
|
|
11
|
+
* /api/hub/servers proxy before normalizeServer.
|
|
12
|
+
*
|
|
13
|
+
* Two legs:
|
|
14
|
+
* A. mock fixture — compile serverDedupe.ts, run a crafted payload
|
|
15
|
+
* that exercises every branch (multi-row merge, telemetry
|
|
16
|
+
* coalesce, NAT-shared IP NOT merged, `unknown` passthrough,
|
|
17
|
+
* agents[] union).
|
|
18
|
+
* B. real payload — GET the running dashboard proxy and assert no
|
|
19
|
+
* hostname appears twice + counts are summed.
|
|
20
|
+
*/
|
|
21
|
+
import { execSync } from 'node:child_process';
|
|
22
|
+
import { readFileSync, renameSync, mkdirSync } from 'node:fs';
|
|
23
|
+
import { pathToFileURL } from 'node:url';
|
|
24
|
+
|
|
25
|
+
let failed = 0;
|
|
26
|
+
const ok = (name, cond, detail = '') => {
|
|
27
|
+
if (cond) { console.log(` ✅ ${name}`); }
|
|
28
|
+
else { console.log(` ❌ ${name}${detail ? ' — ' + detail : ''}`); failed++; }
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
// ── Leg A: mock fixture against the real dedup module ──────────────
|
|
32
|
+
console.log('Leg A — mock fixture (compiled serverDedupe.ts):');
|
|
33
|
+
const OUT = '/tmp/p157-rc2-dedupe';
|
|
34
|
+
mkdirSync(OUT, { recursive: true });
|
|
35
|
+
execSync(
|
|
36
|
+
`npx tsc app/lib/serverDedupe.ts --outDir ${OUT} --module es2022 --target es2022 --moduleResolution bundler --skipLibCheck`,
|
|
37
|
+
{ stdio: 'inherit' },
|
|
38
|
+
);
|
|
39
|
+
renameSync(`${OUT}/serverDedupe.js`, `${OUT}/serverDedupe.mjs`);
|
|
40
|
+
const { dedupeByHostname } = await import(pathToFileURL(`${OUT}/serverDedupe.mjs`).href);
|
|
41
|
+
|
|
42
|
+
const fixture = [
|
|
43
|
+
// same hostname, two interfaces — bridge row fresh + telemetried,
|
|
44
|
+
// loopback row staler + telemetry null
|
|
45
|
+
{ hostname: 'host-A', ip: '172.17.0.2', agent_count: 29, last_seen: '2026-05-20 04:41:46',
|
|
46
|
+
cpu_load_1min: 1.49, cpu_cores: 8, mem_used_gb: 22.6, mem_total_gb: 32,
|
|
47
|
+
agents: [{ alias: 'a1' }, { alias: 'a2' }] },
|
|
48
|
+
{ hostname: 'host-A', ip: '127.0.0.1', agent_count: 38, last_seen: '2026-05-20 04:41:43',
|
|
49
|
+
cpu_load_1min: null, mem_used_gb: null,
|
|
50
|
+
agents: [{ alias: 'a2' }, { alias: 'a3' }] },
|
|
51
|
+
// NAT-shared public IP, distinct hostnames — must NOT merge
|
|
52
|
+
{ hostname: 'host-B', ip: '223.167.142.73', agent_count: 5, last_seen: '2026-05-18 02:34:16' },
|
|
53
|
+
{ hostname: 'host-C', ip: '223.167.142.73', agent_count: 2, last_seen: '2026-05-13 16:44:41' },
|
|
54
|
+
// sentinel hostname — two distinct unknown machines, pass through both
|
|
55
|
+
{ hostname: 'unknown', ip: '127.0.0.1', agent_count: 2, last_seen: '2026-05-16 08:40:14' },
|
|
56
|
+
{ hostname: 'unknown', ip: '10.0.0.9', agent_count: 1, last_seen: '2026-05-16 09:00:00' },
|
|
57
|
+
];
|
|
58
|
+
const out = dedupeByHostname(fixture);
|
|
59
|
+
const byHost = (h) => out.filter(r => r.hostname === h);
|
|
60
|
+
const hostA = byHost('host-A')[0];
|
|
61
|
+
|
|
62
|
+
ok('host-A collapses 2 rows → 1', byHost('host-A').length === 1, `got ${byHost('host-A').length}`);
|
|
63
|
+
ok('host-A agent_count summed 29+38=67', hostA?.agent_count === 67, `got ${hostA?.agent_count}`);
|
|
64
|
+
ok('host-A telemetry coalesced from bridge row (cpu 1.49)', hostA?.cpu_load_1min === 1.49, `got ${hostA?.cpu_load_1min}`);
|
|
65
|
+
ok('host-A mem coalesced (22.6)', hostA?.mem_used_gb === 22.6, `got ${hostA?.mem_used_gb}`);
|
|
66
|
+
ok('host-A last_seen = freshest (04:41:46)', hostA?.last_seen === '2026-05-20 04:41:46', `got ${hostA?.last_seen}`);
|
|
67
|
+
ok('host-A agents[] unioned + dedup by alias (a1,a2,a3)',
|
|
68
|
+
hostA?.agents?.length === 3 &&
|
|
69
|
+
new Set(hostA.agents.map(a => a.alias)).size === 3,
|
|
70
|
+
`got ${JSON.stringify(hostA?.agents)}`);
|
|
71
|
+
ok('host-B + host-C NOT merged despite shared IP', byHost('host-B').length === 1 && byHost('host-C').length === 1);
|
|
72
|
+
ok('two `unknown` rows both pass through (not merged)', byHost('unknown').length === 2, `got ${byHost('unknown').length}`);
|
|
73
|
+
ok('total rows: 1 (A) + 1 (B) + 1 (C) + 2 (unknown) = 5', out.length === 5, `got ${out.length}`);
|
|
74
|
+
|
|
75
|
+
// idempotency — running dedup on already-deduped output is a no-op
|
|
76
|
+
const twice = dedupeByHostname(out);
|
|
77
|
+
ok('idempotent — dedup(dedup(x)) === dedup(x)', twice.length === out.length);
|
|
78
|
+
|
|
79
|
+
// ── Leg B: real payload through the running dashboard proxy ─────────
|
|
80
|
+
console.log('\nLeg B — real payload (live /api/hub/servers proxy):');
|
|
81
|
+
let TOKEN;
|
|
82
|
+
try {
|
|
83
|
+
TOKEN = JSON.parse(readFileSync('/home/vansin/.anet/config.json', 'utf8')).token;
|
|
84
|
+
} catch {
|
|
85
|
+
console.log(' ⚠️ no anet config — skipping live leg');
|
|
86
|
+
}
|
|
87
|
+
if (TOKEN) {
|
|
88
|
+
const res = await fetch('http://127.0.0.1:3000/api/hub/servers', {
|
|
89
|
+
headers: { cookie: `anet_dashboard_session=v3:${TOKEN}` },
|
|
90
|
+
});
|
|
91
|
+
ok('proxy returns 200', res.status === 200, `status ${res.status}`);
|
|
92
|
+
const body = await res.json();
|
|
93
|
+
const servers = body.servers ?? [];
|
|
94
|
+
ok('proxy returns servers[]', Array.isArray(servers) && servers.length > 0, `got ${servers.length}`);
|
|
95
|
+
const counts = {};
|
|
96
|
+
for (const s of servers) counts[s.hostname] = (counts[s.hostname] ?? 0) + 1;
|
|
97
|
+
const dups = Object.entries(counts).filter(([h, n]) => n > 1 && h !== 'unknown' && h !== '');
|
|
98
|
+
ok('no real hostname appears twice', dups.length === 0, `dups: ${JSON.stringify(dups)}`);
|
|
99
|
+
const izrj = servers.find(s => s.hostname?.startsWith('iZrj93pr'));
|
|
100
|
+
if (izrj) {
|
|
101
|
+
ok('iZrj93pr… host present as single card', true);
|
|
102
|
+
ok('iZrj93pr… has telemetry after coalesce (cpu non-null)', izrj.cpu_load_1min != null, `cpu ${izrj.cpu_load_1min}`);
|
|
103
|
+
console.log(` ℹ️ iZrj93pr… merged: agent_count=${izrj.agent_count}, cpu=${izrj.cpu_load_1min}, ip=${izrj.ip}`);
|
|
104
|
+
} else {
|
|
105
|
+
console.log(' ℹ️ iZrj93pr… not in current live payload (hub state changed) — structural dup check still authoritative');
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
console.log(`\n${failed === 0 ? '✅ ALL GREEN' : `❌ ${failed} FAILED`}`);
|
|
110
|
+
process.exit(failed === 0 ? 0 : 1);
|
|
@@ -129,12 +129,11 @@ const results = {
|
|
|
129
129
|
one_shot_entrance_pair: oneShot?.family === 'entrance',
|
|
130
130
|
inf_rest_matches_rolodex_count: infRest?.members === rolodexAnchorCount,
|
|
131
131
|
inf_sweep_matches_trio_count: infSweep?.members === scanBeamTrioAnchorCount,
|
|
132
|
-
/*
|
|
133
|
-
*
|
|
134
|
-
*
|
|
135
|
-
* a separate `oneShot_count_is_2` reflecting the post-R742 reality. */
|
|
132
|
+
/* Entrance family has grown: R740 solo (1) → R742 pair (2) → R743
|
|
133
|
+
* trio (3). The cardinality assertion tracks the current snapshot;
|
|
134
|
+
* one_shot_count_at_least_1 is the stable invariant. */
|
|
136
135
|
one_shot_count_at_least_1: (oneShot?.members ?? 0) >= 1,
|
|
137
|
-
|
|
136
|
+
one_shot_count_is_3: oneShot?.members === 3,
|
|
138
137
|
};
|
|
139
138
|
const ok = Object.values(results).every(Boolean);
|
|
140
139
|
console.log(`${ok ? '✅' : '❌'} R741 animation temporal modes catalog (8th meta-doc — octagon, lifecycle dimension):`,
|