zevairouter 1.0.173 → 1.0.174
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/CHANGELOG.md +5 -0
- package/cli/app/.next-cli-build/BUILD_ID +1 -1
- package/cli/app/.next-cli-build/app-path-routes-manifest.json +11 -11
- package/cli/app/.next-cli-build/build-manifest.json +2 -2
- package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/automation/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/basic-chat/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/cli-tools/[toolId]/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/cli-tools/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/combos/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/console-log/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/context/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/endpoint/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/[kind]/[id]/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/[kind]/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/combo/[id]/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/web/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/mitm/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/playground/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/profile/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/providers/[id]/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/providers/new/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/providers/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/proxy-pools/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/pxpipe/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/quota/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/settings/pricing/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/terminal/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/token-saver/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/translator/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/usage/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/_global-error.html +1 -1
- package/cli/app/.next-cli-build/server/app/_global-error.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/_not-found.html +1 -1
- package/cli/app/.next-cli-build/server/app/_not-found.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/_not-found.segments/_full.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/_not-found.segments/_index.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/api/models/route.js +1 -1
- package/cli/app/.next-cli-build/server/app/api/providers/route.js +1 -1
- package/cli/app/.next-cli-build/server/app/api/providers/validate/route.js +1 -1
- package/cli/app/.next-cli-build/server/app/api/translator/console-logs/route.js +1 -1
- package/cli/app/.next-cli-build/server/app/api/translator/console-logs/stream/route.js +1 -1
- package/cli/app/.next-cli-build/server/app/api/version/route.js +1 -1
- package/cli/app/.next-cli-build/server/app/api/version/shutdown/route.js +1 -1
- package/cli/app/.next-cli-build/server/app/api/version/update/route.js +1 -1
- package/cli/app/.next-cli-build/server/app/callback/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/callback.html +1 -1
- package/cli/app/.next-cli-build/server/app/callback.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/callback.segments/_full.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/callback.segments/_head.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/callback.segments/_index.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/callback.segments/_tree.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/callback.segments/callback/__PAGE__.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/callback.segments/callback.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/automation.html +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/automation.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/automation.segments/!KGRhc2hib2FyZCk/dashboard/automation/__PAGE__.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/automation.segments/!KGRhc2hib2FyZCk/dashboard/automation.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/automation.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/automation.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/automation.segments/_full.segment.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/automation.segments/_head.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/automation.segments/_index.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/dashboard/automation.segments/_tree.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/basic-chat.html +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/basic-chat.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/basic-chat.segments/!KGRhc2hib2FyZCk/dashboard/basic-chat/__PAGE__.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/basic-chat.segments/!KGRhc2hib2FyZCk/dashboard/basic-chat.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/basic-chat.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/basic-chat.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/basic-chat.segments/_full.segment.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/basic-chat.segments/_head.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/basic-chat.segments/_index.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/dashboard/basic-chat.segments/_tree.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/cli-tools.html +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/cli-tools.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/cli-tools.segments/!KGRhc2hib2FyZCk/dashboard/cli-tools/__PAGE__.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/cli-tools.segments/!KGRhc2hib2FyZCk/dashboard/cli-tools.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/cli-tools.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/cli-tools.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/cli-tools.segments/_full.segment.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/cli-tools.segments/_head.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/cli-tools.segments/_index.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/dashboard/cli-tools.segments/_tree.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/combos.html +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/combos.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/combos.segments/!KGRhc2hib2FyZCk/dashboard/combos/__PAGE__.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/combos.segments/!KGRhc2hib2FyZCk/dashboard/combos.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/combos.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/combos.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/combos.segments/_full.segment.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/combos.segments/_head.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/combos.segments/_index.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/dashboard/combos.segments/_tree.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/context.html +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/context.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/context.segments/!KGRhc2hib2FyZCk/dashboard/context/__PAGE__.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/context.segments/!KGRhc2hib2FyZCk/dashboard/context.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/context.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/context.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/context.segments/_full.segment.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/context.segments/_head.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/context.segments/_index.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/dashboard/context.segments/_tree.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/endpoint.html +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/endpoint.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/endpoint.segments/!KGRhc2hib2FyZCk/dashboard/endpoint/__PAGE__.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/endpoint.segments/!KGRhc2hib2FyZCk/dashboard/endpoint.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/endpoint.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/endpoint.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/endpoint.segments/_full.segment.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/endpoint.segments/_head.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/endpoint.segments/_index.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/dashboard/endpoint.segments/_tree.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/media-providers/web.html +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/media-providers/web.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/!KGRhc2hib2FyZCk/dashboard/media-providers/web/__PAGE__.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/!KGRhc2hib2FyZCk/dashboard/media-providers/web.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/!KGRhc2hib2FyZCk/dashboard/media-providers.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/_full.segment.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/_head.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/_index.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/_tree.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/mitm.html +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/mitm.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/mitm.segments/!KGRhc2hib2FyZCk/dashboard/mitm/__PAGE__.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/mitm.segments/!KGRhc2hib2FyZCk/dashboard/mitm.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/mitm.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/mitm.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/mitm.segments/_full.segment.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/mitm.segments/_head.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/mitm.segments/_index.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/dashboard/mitm.segments/_tree.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/playground.html +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/playground.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/playground.segments/!KGRhc2hib2FyZCk/dashboard/playground/__PAGE__.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/playground.segments/!KGRhc2hib2FyZCk/dashboard/playground.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/playground.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/playground.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/playground.segments/_full.segment.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/playground.segments/_head.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/playground.segments/_index.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/dashboard/playground.segments/_tree.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/profile.html +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/profile.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/profile.segments/!KGRhc2hib2FyZCk/dashboard/profile/__PAGE__.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/profile.segments/!KGRhc2hib2FyZCk/dashboard/profile.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/profile.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/profile.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/profile.segments/_full.segment.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/profile.segments/_head.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/profile.segments/_index.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/dashboard/profile.segments/_tree.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/providers/new.html +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/providers/new.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/providers/new.segments/!KGRhc2hib2FyZCk/dashboard/providers/new/__PAGE__.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/providers/new.segments/!KGRhc2hib2FyZCk/dashboard/providers/new.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/providers/new.segments/!KGRhc2hib2FyZCk/dashboard/providers.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/providers/new.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/providers/new.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/providers/new.segments/_full.segment.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/providers/new.segments/_head.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/providers/new.segments/_index.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/dashboard/providers/new.segments/_tree.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/providers.html +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/providers.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/providers.segments/!KGRhc2hib2FyZCk/dashboard/providers/__PAGE__.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/providers.segments/!KGRhc2hib2FyZCk/dashboard/providers.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/providers.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/providers.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/providers.segments/_full.segment.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/providers.segments/_head.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/providers.segments/_index.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/dashboard/providers.segments/_tree.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/proxy-pools.html +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/proxy-pools.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/!KGRhc2hib2FyZCk/dashboard/proxy-pools/__PAGE__.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/!KGRhc2hib2FyZCk/dashboard/proxy-pools.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/_full.segment.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/_head.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/_index.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/_tree.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/pxpipe.html +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/pxpipe.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/pxpipe.segments/!KGRhc2hib2FyZCk/dashboard/pxpipe/__PAGE__.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/pxpipe.segments/!KGRhc2hib2FyZCk/dashboard/pxpipe.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/pxpipe.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/pxpipe.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/pxpipe.segments/_full.segment.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/pxpipe.segments/_head.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/pxpipe.segments/_index.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/dashboard/pxpipe.segments/_tree.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/quota.html +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/quota.rsc +6 -6
- package/cli/app/.next-cli-build/server/app/dashboard/quota.segments/!KGRhc2hib2FyZCk/dashboard/quota/__PAGE__.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/dashboard/quota.segments/!KGRhc2hib2FyZCk/dashboard/quota.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/quota.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/quota.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/quota.segments/_full.segment.rsc +6 -6
- package/cli/app/.next-cli-build/server/app/dashboard/quota.segments/_head.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/quota.segments/_index.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/dashboard/quota.segments/_tree.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/settings/pricing.html +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/settings/pricing.rsc +4 -4
- package/cli/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/!KGRhc2hib2FyZCk/dashboard/settings/pricing/__PAGE__.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/!KGRhc2hib2FyZCk/dashboard/settings/pricing.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/!KGRhc2hib2FyZCk/dashboard/settings.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/_full.segment.rsc +4 -4
- package/cli/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/_head.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/_index.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/_tree.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/token-saver.html +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/token-saver.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/token-saver.segments/!KGRhc2hib2FyZCk/dashboard/token-saver/__PAGE__.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/token-saver.segments/!KGRhc2hib2FyZCk/dashboard/token-saver.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/token-saver.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/token-saver.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/token-saver.segments/_full.segment.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/token-saver.segments/_head.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/token-saver.segments/_index.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/dashboard/token-saver.segments/_tree.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/translator.html +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/translator.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/translator.segments/!KGRhc2hib2FyZCk/dashboard/translator/__PAGE__.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/translator.segments/!KGRhc2hib2FyZCk/dashboard/translator.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/translator.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/translator.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/translator.segments/_full.segment.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/translator.segments/_head.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/translator.segments/_index.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/dashboard/translator.segments/_tree.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/usage.html +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/usage.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/usage.segments/!KGRhc2hib2FyZCk/dashboard/usage/__PAGE__.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/usage.segments/!KGRhc2hib2FyZCk/dashboard/usage.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/usage.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/usage.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/usage.segments/_full.segment.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/usage.segments/_head.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/usage.segments/_index.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/dashboard/usage.segments/_tree.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard.html +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard.segments/!KGRhc2hib2FyZCk/dashboard/__PAGE__.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard.segments/_full.segment.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard.segments/_head.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard.segments/_index.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/dashboard.segments/_tree.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/index.html +1 -1
- package/cli/app/.next-cli-build/server/app/index.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/index.segments/__PAGE__.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/index.segments/_full.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/index.segments/_head.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/index.segments/_index.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/index.segments/_tree.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/landing/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/landing.html +1 -1
- package/cli/app/.next-cli-build/server/app/landing.rsc +4 -4
- package/cli/app/.next-cli-build/server/app/landing.segments/_full.segment.rsc +4 -4
- package/cli/app/.next-cli-build/server/app/landing.segments/_head.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/landing.segments/_index.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/landing.segments/_tree.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/landing.segments/landing/__PAGE__.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/landing.segments/landing.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/login/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/login.html +1 -1
- package/cli/app/.next-cli-build/server/app/login.rsc +4 -4
- package/cli/app/.next-cli-build/server/app/login.segments/_full.segment.rsc +4 -4
- package/cli/app/.next-cli-build/server/app/login.segments/_head.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/login.segments/_index.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/login.segments/_tree.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/login.segments/login/__PAGE__.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/login.segments/login.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app-paths-manifest.json +11 -11
- package/cli/app/.next-cli-build/server/chunks/3155.js +1 -1
- package/cli/app/.next-cli-build/server/chunks/4746.js +1 -1
- package/cli/app/.next-cli-build/server/chunks/5307.js +1 -1
- package/cli/app/.next-cli-build/server/chunks/8306.js +1 -1
- package/cli/app/.next-cli-build/server/chunks/9621.js +1 -1
- package/cli/app/.next-cli-build/server/middleware-build-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/pages/404.html +1 -1
- package/cli/app/.next-cli-build/server/pages/500.html +1 -1
- package/cli/app/.next-cli-build/static/chunks/{620-c15094ea3b9eda2c.js → 620-2db5cff0e3ebc21f.js} +1 -1
- package/cli/app/CHANGELOG.md +5 -0
- package/cli/app/package.json +1 -1
- package/cli/app/src/lib/updater/updater.js +19 -4
- package/cli/cli.js +305 -78
- package/cli/package.json +1 -1
- package/cli/src/cli/routerProcessLifecycle.js +685 -0
- package/cli/src/cli/tray/autostart.js +43 -35
- package/package.json +1 -1
- /package/cli/app/.next-cli-build/static/{nTTf6L7b6eAK9eItpJOcH → 9Vz4OT0qlhev-svz548oQ}/_buildManifest.js +0 -0
- /package/cli/app/.next-cli-build/static/{nTTf6L7b6eAK9eItpJOcH → 9Vz4OT0qlhev-svz548oQ}/_ssgManifest.js +0 -0
package/cli/app/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
# Unreleased
|
|
2
2
|
|
|
3
|
+
# v1.0.174 (2026-07-29)
|
|
4
|
+
|
|
5
|
+
## Fixes
|
|
6
|
+
- **Self-healing macOS router startup**: `zevai` now identifies and reaps only exact orphaned ZevaiRouter `next-server` listeners when HTTP health/version probes hang, while mixed or unrelated port owners still fail closed. LaunchAgent-owned children stay attached to launchd, and hidden server errors go to a durable private log instead of a parent-owned pipe that can break and spin after an abrupt CLI exit.
|
|
7
|
+
|
|
3
8
|
# v1.0.173 (2026-07-29)
|
|
4
9
|
|
|
5
10
|
## Fixes
|
package/cli/app/package.json
CHANGED
|
@@ -129,6 +129,15 @@ function sleep(ms) {
|
|
|
129
129
|
return new Promise((r) => setTimeout(r, ms));
|
|
130
130
|
}
|
|
131
131
|
|
|
132
|
+
function createDetachedEnv(overrides = {}) {
|
|
133
|
+
const env = { ...process.env, ...overrides };
|
|
134
|
+
// A detached helper is no longer owned by the LaunchAgent that started the
|
|
135
|
+
// original CLI/Next pair, even when the updater was launched from that pair.
|
|
136
|
+
delete env.ZEVAI_LAUNCHD_JOB;
|
|
137
|
+
delete env.XPC_SERVICE_NAME;
|
|
138
|
+
return env;
|
|
139
|
+
}
|
|
140
|
+
|
|
132
141
|
function resolveSafeInstallHook() {
|
|
133
142
|
const candidates = [
|
|
134
143
|
path.join(path.dirname(process.execPath), "..", "lib", "node_modules", "zevairouter", "cli", "hooks", "safeGlobalInstall.js"),
|
|
@@ -231,7 +240,14 @@ function openBrowser(url) {
|
|
|
231
240
|
const cmd = platform === "darwin" ? `open "${url}"`
|
|
232
241
|
: platform === "win32" ? `start "" "${url}"`
|
|
233
242
|
: `xdg-open "${url}"`;
|
|
234
|
-
try {
|
|
243
|
+
try {
|
|
244
|
+
spawn(cmd, {
|
|
245
|
+
shell: true,
|
|
246
|
+
detached: true,
|
|
247
|
+
stdio: "ignore",
|
|
248
|
+
env: createDetachedEnv(),
|
|
249
|
+
}).unref();
|
|
250
|
+
} catch { /* ignore */ }
|
|
235
251
|
}
|
|
236
252
|
|
|
237
253
|
// Wait until app port is listening (server alive again), then open dashboard
|
|
@@ -294,14 +310,13 @@ function relaunchApp() {
|
|
|
294
310
|
stdio: "ignore",
|
|
295
311
|
windowsHide: true,
|
|
296
312
|
shell: isWin,
|
|
297
|
-
env: {
|
|
298
|
-
...process.env,
|
|
313
|
+
env: createDetachedEnv({
|
|
299
314
|
UPDATER_RELAUNCH: "",
|
|
300
315
|
UPDATER_RELAUNCH_CMD: "",
|
|
301
316
|
UPDATER_RELAUNCH_ARGS: "",
|
|
302
317
|
// Prevent cli.js from flipping headless server restarts into tray mode.
|
|
303
318
|
ZEVAI_SERVER_MODE: args.includes("--tray") ? "" : "1",
|
|
304
|
-
},
|
|
319
|
+
}),
|
|
305
320
|
});
|
|
306
321
|
child.unref();
|
|
307
322
|
pushLog(`[updater] relaunched: ${cmd} ${args.join(" ")} (pid=${child.pid})`);
|
package/cli/cli.js
CHANGED
|
@@ -65,6 +65,14 @@ const INSTALL_CMD_LATEST = `npm i -g ${APP_NAME}@latest --prefer-online`;
|
|
|
65
65
|
const DEFAULT_PORT = 1997;
|
|
66
66
|
const DEFAULT_HOST = "127.0.0.1";
|
|
67
67
|
const MAX_PORT_ATTEMPTS = 10;
|
|
68
|
+
|
|
69
|
+
function buildDetachedProcessEnv(overrides = {}) {
|
|
70
|
+
const env = { ...process.env, ...overrides };
|
|
71
|
+
delete env.ZEVAI_LAUNCHD_JOB;
|
|
72
|
+
delete env.XPC_SERVICE_NAME;
|
|
73
|
+
return env;
|
|
74
|
+
}
|
|
75
|
+
|
|
68
76
|
// Identifiers for killAllAppProcesses - only kill our app specifically.
|
|
69
77
|
// "zevai" matches the current install; "zevairouter" matches the legacy upstream
|
|
70
78
|
// fork so upgrading users' old instances still get cleaned up.
|
|
@@ -312,17 +320,27 @@ One-shot install / reinstall (any device):
|
|
|
312
320
|
const needsPreInstallStop = !skipRestart && (hasCronWatchdog || pm2App) && !wasTray;
|
|
313
321
|
if (needsPreInstallStop) {
|
|
314
322
|
console.log("Stopping server first (frees RAM for install on small VPS)…");
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
323
|
+
let pm2StopAttempted = false;
|
|
324
|
+
try {
|
|
325
|
+
if (pm2App) {
|
|
326
|
+
pm2StopAttempted = true;
|
|
327
|
+
execFileSync("pm2", ["stop", String(pm2App.id)], { stdio: "inherit", timeout: 30000 });
|
|
328
|
+
} else {
|
|
329
|
+
stopOwnedRouterParent(updateRuntime, updatePort);
|
|
330
|
+
}
|
|
331
|
+
freePortHard(updatePort, updateHost);
|
|
332
|
+
if (isPortOccupied(updatePort)) {
|
|
333
|
+
throw new Error(`ZevaiRouter on port ${updatePort} did not stop cleanly.`);
|
|
334
|
+
}
|
|
335
|
+
} catch (stopError) {
|
|
336
|
+
if (pm2StopAttempted) {
|
|
337
|
+
try {
|
|
338
|
+
execFileSync("pm2", ["restart", String(pm2App.id)], { stdio: "inherit", timeout: 30000 });
|
|
339
|
+
} catch (restartError) {
|
|
340
|
+
throw new Error(`${stopError.message}; PM2 recovery also failed: ${restartError.message}`);
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
throw stopError;
|
|
326
344
|
}
|
|
327
345
|
}
|
|
328
346
|
|
|
@@ -506,8 +524,14 @@ WantedBy=multi-user.target
|
|
|
506
524
|
// old child while a detached replacement tries to claim the same port.
|
|
507
525
|
if (launchdManager) {
|
|
508
526
|
try {
|
|
509
|
-
|
|
510
|
-
|
|
527
|
+
// An inactive, validated job can leave its old detached Next child
|
|
528
|
+
// behind. Reap only a live-verified router or an exact macOS orphan
|
|
529
|
+
// before asking launchd to start the newly installed package.
|
|
530
|
+
if (launchdManager.pid == null && isPortOccupied(updatePort)) {
|
|
531
|
+
freePortHard(updatePort, updateHost);
|
|
532
|
+
if (isPortOccupied(updatePort)) {
|
|
533
|
+
throw new Error(`Port ${updatePort} is owned by an unverified service; launchd was not changed.`);
|
|
534
|
+
}
|
|
511
535
|
}
|
|
512
536
|
console.log(`Restarting validated LaunchAgent ${launchdManager.target}…`);
|
|
513
537
|
execFileSync("launchctl", ["kickstart", "-k", launchdManager.target], {
|
|
@@ -599,12 +623,13 @@ WantedBy=multi-user.target
|
|
|
599
623
|
// Free the port BEFORE spawning — otherwise the new detached process crashes
|
|
600
624
|
// on EADDRINUSE while the old one keeps serving the stale build (buildMismatch).
|
|
601
625
|
const directPort = updatePort;
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
626
|
+
try {
|
|
627
|
+
stopOwnedRouterParent(updateRuntime, directPort);
|
|
628
|
+
freePortHard(directPort, updateHost);
|
|
629
|
+
} catch (stopError) {
|
|
630
|
+
rollbackInstall(`Could not safely stop port ${directPort}: ${stopError.message}`);
|
|
631
|
+
throw stopError;
|
|
605
632
|
}
|
|
606
|
-
stopOwnedRouterParent(updateRuntime, directPort);
|
|
607
|
-
freePortHard(directPort, updateHost);
|
|
608
633
|
if (isPortOccupied(directPort)) {
|
|
609
634
|
rollbackInstall(`ZevaiRouter on port ${directPort} did not stop`);
|
|
610
635
|
throw new Error(`Port ${directPort} did not become free; the previous package was restored`);
|
|
@@ -622,25 +647,23 @@ WantedBy=multi-user.target
|
|
|
622
647
|
? spawn(process.execPath, [cliEntry, ...relaunchArgs], {
|
|
623
648
|
detached: true,
|
|
624
649
|
stdio: ["ignore", out, out],
|
|
625
|
-
env: {
|
|
626
|
-
...process.env,
|
|
650
|
+
env: buildDetachedProcessEnv({
|
|
627
651
|
PORT: String(updatePort),
|
|
628
652
|
HOSTNAME: updateHost,
|
|
629
653
|
TRAY_MODE: wasTray ? "1" : "",
|
|
630
654
|
ZEVAI_SERVER_MODE: wasTray ? "" : "1",
|
|
631
|
-
},
|
|
655
|
+
}),
|
|
632
656
|
})
|
|
633
657
|
: spawn(result.zevaiPath || "zevai", relaunchArgs, {
|
|
634
658
|
detached: true,
|
|
635
659
|
stdio: ["ignore", out, out],
|
|
636
660
|
shell: process.platform === "win32",
|
|
637
|
-
env: {
|
|
638
|
-
...process.env,
|
|
661
|
+
env: buildDetachedProcessEnv({
|
|
639
662
|
PORT: String(updatePort),
|
|
640
663
|
HOSTNAME: updateHost,
|
|
641
664
|
TRAY_MODE: wasTray ? "1" : "",
|
|
642
665
|
ZEVAI_SERVER_MODE: wasTray ? "" : "1",
|
|
643
|
-
},
|
|
666
|
+
}),
|
|
644
667
|
});
|
|
645
668
|
child.unref();
|
|
646
669
|
return { child, logFile };
|
|
@@ -729,6 +752,22 @@ if (
|
|
|
729
752
|
process.env.TRAY_MODE = "1";
|
|
730
753
|
}
|
|
731
754
|
|
|
755
|
+
// New LaunchAgents set an explicit marker. The PID check keeps older, already
|
|
756
|
+
// loaded plists safe until their next reload applies that marker.
|
|
757
|
+
const launchdOwned = process.platform === "darwin" && trayMode && (
|
|
758
|
+
process.env.ZEVAI_LAUNCHD_JOB === "1"
|
|
759
|
+
|| process.env.XPC_SERVICE_NAME === "com.zevairouter.autostart"
|
|
760
|
+
|| (() => {
|
|
761
|
+
try {
|
|
762
|
+
const { isCurrentMacOSLaunchAgent } = require("./src/cli/tray/autostart");
|
|
763
|
+
return isCurrentMacOSLaunchAgent();
|
|
764
|
+
} catch {
|
|
765
|
+
return false;
|
|
766
|
+
}
|
|
767
|
+
})()
|
|
768
|
+
);
|
|
769
|
+
if (launchdOwned) process.env.ZEVAI_LAUNCHD_JOB = "1";
|
|
770
|
+
|
|
732
771
|
// Always use Node.js runtime with absolute path
|
|
733
772
|
const RUNTIME = process.execPath;
|
|
734
773
|
|
|
@@ -951,14 +990,14 @@ function killProxyByPidFile() {
|
|
|
951
990
|
} catch { }
|
|
952
991
|
}
|
|
953
992
|
|
|
954
|
-
//
|
|
993
|
+
// Stop a listener through the platform-specific, identity-bound lifecycle.
|
|
955
994
|
function killProcessOnPort(port, checkHost = host) {
|
|
956
|
-
return new Promise((resolve) => {
|
|
995
|
+
return new Promise((resolve, reject) => {
|
|
957
996
|
try {
|
|
958
|
-
|
|
997
|
+
freePortHard(port, checkHost);
|
|
959
998
|
setTimeout(() => resolve(), 500);
|
|
960
999
|
} catch (err) {
|
|
961
|
-
|
|
1000
|
+
reject(err);
|
|
962
1001
|
}
|
|
963
1002
|
});
|
|
964
1003
|
}
|
|
@@ -1166,7 +1205,8 @@ function getPortOwnerPids(checkPort) {
|
|
|
1166
1205
|
.filter((pid) => Number.isInteger(pid) && pid > 0))];
|
|
1167
1206
|
}
|
|
1168
1207
|
|
|
1169
|
-
const
|
|
1208
|
+
const lsofPath = process.platform === "darwin" ? "/usr/sbin/lsof" : "lsof";
|
|
1209
|
+
const output = execFileSync(lsofPath, ["-nP", `-tiTCP:${numericPort}`, "-sTCP:LISTEN"], {
|
|
1170
1210
|
encoding: "utf8",
|
|
1171
1211
|
stdio: ["ignore", "pipe", "ignore"],
|
|
1172
1212
|
timeout: 5000,
|
|
@@ -1240,9 +1280,6 @@ function stopOwnedRouterParent(runtime, checkPort) {
|
|
|
1240
1280
|
if (snapshots.length === 0) return false;
|
|
1241
1281
|
|
|
1242
1282
|
const occupied = isPortOccupied(checkPort);
|
|
1243
|
-
if (occupied && !isZevaiVersionInfo(getLiveVersionInfo(checkPort, 4, runtime?.host))) {
|
|
1244
|
-
throw new Error(`Port ${checkPort} is owned by an unverified service; its parent was not stopped.`);
|
|
1245
|
-
}
|
|
1246
1283
|
const listenerPids = occupied ? getPortOwnerPids(checkPort) : [];
|
|
1247
1284
|
if (occupied && listenerPids.length === 0) {
|
|
1248
1285
|
throw new Error(`Could not prove listener ownership on port ${checkPort}; its parent was not stopped.`);
|
|
@@ -1293,28 +1330,114 @@ function stopOwnedRouterParent(runtime, checkPort) {
|
|
|
1293
1330
|
}
|
|
1294
1331
|
|
|
1295
1332
|
function killVerifiedRouterOnPort(checkPort, checkHost = DEFAULT_HOST) {
|
|
1333
|
+
// macOS cleanup uses the stronger ancestry/cwd/start-time proofs below.
|
|
1334
|
+
// Linux keeps a healthy detached-orphan fallback, bound to one PID and its
|
|
1335
|
+
// immutable /proc start time. Windows retains the legacy single-PID proof.
|
|
1336
|
+
if (process.platform === "darwin" || !["linux", "win32"].includes(process.platform)) {
|
|
1337
|
+
return false;
|
|
1338
|
+
}
|
|
1296
1339
|
const live = getLiveVersionInfo(checkPort, 4, checkHost);
|
|
1297
1340
|
if (!isZevaiVersionInfo(live)) return false;
|
|
1298
1341
|
|
|
1299
1342
|
const pids = getPortOwnerPids(checkPort).filter((pid) => pid !== process.pid);
|
|
1300
|
-
|
|
1343
|
+
if (pids.length !== 1) return false;
|
|
1344
|
+
let linuxStartToken = null;
|
|
1345
|
+
if (process.platform === "linux") {
|
|
1301
1346
|
try {
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1347
|
+
const { parseLinuxProcStatStartToken } = require("./src/cli/routerProcessLifecycle");
|
|
1348
|
+
linuxStartToken = parseLinuxProcStatStartToken(
|
|
1349
|
+
fs.readFileSync(`/proc/${pids[0]}/stat`, "utf8"),
|
|
1350
|
+
pids[0],
|
|
1351
|
+
);
|
|
1352
|
+
} catch {
|
|
1353
|
+
return false;
|
|
1354
|
+
}
|
|
1355
|
+
if (!linuxStartToken) return false;
|
|
1356
|
+
}
|
|
1357
|
+
if (!isZevaiVersionInfo(getLiveVersionInfo(checkPort, 4, checkHost))) return false;
|
|
1358
|
+
const confirmedPids = getPortOwnerPids(checkPort).filter((pid) => pid !== process.pid);
|
|
1359
|
+
if (confirmedPids.length !== 1 || confirmedPids[0] !== pids[0]) return false;
|
|
1360
|
+
if (process.platform === "linux") {
|
|
1361
|
+
try {
|
|
1362
|
+
const { parseLinuxProcStatStartToken } = require("./src/cli/routerProcessLifecycle");
|
|
1363
|
+
const confirmedStartToken = parseLinuxProcStatStartToken(
|
|
1364
|
+
fs.readFileSync(`/proc/${pids[0]}/stat`, "utf8"),
|
|
1365
|
+
pids[0],
|
|
1366
|
+
);
|
|
1367
|
+
if (confirmedStartToken !== linuxStartToken) return false;
|
|
1368
|
+
} catch {
|
|
1369
|
+
return false;
|
|
1370
|
+
}
|
|
1371
|
+
}
|
|
1372
|
+
try {
|
|
1373
|
+
if (process.platform === "win32") {
|
|
1374
|
+
execSync(`taskkill /F /T /PID ${pids[0]} 2>nul`, {
|
|
1375
|
+
stdio: "ignore",
|
|
1376
|
+
shell: true,
|
|
1377
|
+
windowsHide: true,
|
|
1378
|
+
timeout: 5000,
|
|
1379
|
+
});
|
|
1380
|
+
return true;
|
|
1381
|
+
}
|
|
1382
|
+
process.kill(pids[0], "SIGTERM");
|
|
1383
|
+
if (waitForExit(pids[0], 2000)) return true;
|
|
1384
|
+
const beforeKillPids = getPortOwnerPids(checkPort).filter((pid) => pid !== process.pid);
|
|
1385
|
+
if (beforeKillPids.length !== 1 || beforeKillPids[0] !== pids[0]) return false;
|
|
1386
|
+
const { parseLinuxProcStatStartToken } = require("./src/cli/routerProcessLifecycle");
|
|
1387
|
+
const beforeKillStartToken = parseLinuxProcStatStartToken(
|
|
1388
|
+
fs.readFileSync(`/proc/${pids[0]}/stat`, "utf8"),
|
|
1389
|
+
pids[0],
|
|
1390
|
+
);
|
|
1391
|
+
if (beforeKillStartToken !== linuxStartToken) return false;
|
|
1392
|
+
process.kill(pids[0], "SIGKILL");
|
|
1393
|
+
return waitForExit(pids[0], 1000);
|
|
1394
|
+
} catch {
|
|
1395
|
+
return false;
|
|
1396
|
+
}
|
|
1397
|
+
}
|
|
1398
|
+
|
|
1399
|
+
function stopOwnedMacOsOrphanOnPort(checkPort) {
|
|
1400
|
+
if (process.platform !== "darwin") return false;
|
|
1401
|
+
let signaledOwnedProcess = false;
|
|
1402
|
+
try {
|
|
1403
|
+
const {
|
|
1404
|
+
createMacOsProcessLifecycleDependencies,
|
|
1405
|
+
stopOwnedMacOsOrphanListeners,
|
|
1406
|
+
} = require("./src/cli/routerProcessLifecycle");
|
|
1407
|
+
const lexicalGlobalRoot = path.dirname(path.dirname(__dirname));
|
|
1408
|
+
let globalRoot = lexicalGlobalRoot;
|
|
1409
|
+
try { globalRoot = fs.realpathSync.native(lexicalGlobalRoot); } catch {}
|
|
1410
|
+
const dependencies = createMacOsProcessLifecycleDependencies();
|
|
1411
|
+
const sendSignal = dependencies.sendSignal;
|
|
1412
|
+
dependencies.sendSignal = (pid, signal) => {
|
|
1413
|
+
sendSignal(pid, signal);
|
|
1414
|
+
signaledOwnedProcess = true;
|
|
1415
|
+
};
|
|
1416
|
+
const result = stopOwnedMacOsOrphanListeners({
|
|
1417
|
+
port: Number(checkPort),
|
|
1418
|
+
globalRoot,
|
|
1419
|
+
dependencies,
|
|
1420
|
+
});
|
|
1421
|
+
return result.stopped === true;
|
|
1422
|
+
} catch (error) {
|
|
1423
|
+
// Once an exact owned process has been signaled, a partial cleanup is a
|
|
1424
|
+
// hard startup failure even if TERM already made the port look free.
|
|
1425
|
+
if (signaledOwnedProcess) throw error;
|
|
1426
|
+
return false;
|
|
1427
|
+
}
|
|
1428
|
+
}
|
|
1429
|
+
|
|
1430
|
+
function stopCurrentOwnedRouterParent(checkPort, checkHost = DEFAULT_HOST) {
|
|
1431
|
+
if (process.platform === "win32") return false;
|
|
1432
|
+
try {
|
|
1433
|
+
const current = readOwnedProcessState();
|
|
1434
|
+
return stopOwnedRouterParent({
|
|
1435
|
+
runningProcesses: current.runningProcesses,
|
|
1436
|
+
host: checkHost,
|
|
1437
|
+
}, checkPort);
|
|
1438
|
+
} catch {
|
|
1439
|
+
return false;
|
|
1316
1440
|
}
|
|
1317
|
-
return pids.length > 0;
|
|
1318
1441
|
}
|
|
1319
1442
|
|
|
1320
1443
|
/**
|
|
@@ -1334,8 +1457,13 @@ function isStaleRouterOnPort(checkPort, checkHost = DEFAULT_HOST) {
|
|
|
1334
1457
|
return false;
|
|
1335
1458
|
}
|
|
1336
1459
|
|
|
1337
|
-
/** Free a
|
|
1460
|
+
/** Free a proven ZevaiRouter listener without touching unrelated services. */
|
|
1338
1461
|
function freePortHard(checkPort, checkHost = DEFAULT_HOST) {
|
|
1462
|
+
if (process.platform === "win32") {
|
|
1463
|
+
return killVerifiedRouterOnPort(checkPort, checkHost);
|
|
1464
|
+
}
|
|
1465
|
+
if (stopCurrentOwnedRouterParent(checkPort, checkHost)) return true;
|
|
1466
|
+
if (process.platform === "darwin") return stopOwnedMacOsOrphanOnPort(checkPort);
|
|
1339
1467
|
return killVerifiedRouterOnPort(checkPort, checkHost);
|
|
1340
1468
|
}
|
|
1341
1469
|
|
|
@@ -1436,13 +1564,25 @@ function attachToRunningRouter(latestVersion) {
|
|
|
1436
1564
|
// Check for updates FIRST, then start server (or attach if already healthy)
|
|
1437
1565
|
checkForUpdate().then((latestVersion) => {
|
|
1438
1566
|
const underSystemd = Boolean(process.env.INVOCATION_ID) || process.env.ZEVAI_SERVER_MODE === "1";
|
|
1439
|
-
const
|
|
1440
|
-
|
|
1567
|
+
const underManagedSupervisor = underSystemd || launchdOwned;
|
|
1568
|
+
let occupied = isPortOccupied(port);
|
|
1569
|
+
let live = occupied ? getLiveVersionInfo(port, 4, host) : null;
|
|
1441
1570
|
if (occupied && !isZevaiVersionInfo(live)) {
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1571
|
+
let recovered = stopCurrentOwnedRouterParent(port, host);
|
|
1572
|
+
if (isPortOccupied(port)) {
|
|
1573
|
+
recovered = stopOwnedMacOsOrphanOnPort(port) || recovered;
|
|
1574
|
+
}
|
|
1575
|
+
occupied = isPortOccupied(port);
|
|
1576
|
+
if (occupied) {
|
|
1577
|
+
console.error(`Port :${port} is already in use by an unverified process.`);
|
|
1578
|
+
console.error("ZevaiRouter will not terminate unrelated services. Free the port or choose --port <port>.");
|
|
1579
|
+
process.exitCode = 1;
|
|
1580
|
+
return;
|
|
1581
|
+
}
|
|
1582
|
+
if (recovered) {
|
|
1583
|
+
console.log(`Recovered an unresponsive ZevaiRouter process on :${port}.`);
|
|
1584
|
+
}
|
|
1585
|
+
live = null;
|
|
1446
1586
|
}
|
|
1447
1587
|
const stale = isStaleRouterOnPort(port, host);
|
|
1448
1588
|
const healthy = isRouterHealthy(port, host);
|
|
@@ -1450,7 +1590,7 @@ checkForUpdate().then((latestVersion) => {
|
|
|
1450
1590
|
// Bare `zevai` while a *matching* server already serves :1997 → attach.
|
|
1451
1591
|
// If the listener is an OLD orphan next-server (buildVersion lag), take over.
|
|
1452
1592
|
// Never attach when launched by systemd / server mode — parent must stay alive.
|
|
1453
|
-
if (!forceRestart && !
|
|
1593
|
+
if (!forceRestart && !underManagedSupervisor && healthy && !stale) {
|
|
1454
1594
|
attachToRunningRouter(latestVersion);
|
|
1455
1595
|
return;
|
|
1456
1596
|
}
|
|
@@ -1469,15 +1609,22 @@ checkForUpdate().then((latestVersion) => {
|
|
|
1469
1609
|
}
|
|
1470
1610
|
}
|
|
1471
1611
|
|
|
1472
|
-
killAllAppProcesses(port)
|
|
1612
|
+
return killAllAppProcesses(port)
|
|
1473
1613
|
.then(() => killProcessOnPort(port, host))
|
|
1474
1614
|
.then(() => {
|
|
1475
1615
|
freePortHard(port, host);
|
|
1476
1616
|
return new Promise((r) => setTimeout(r, 400));
|
|
1477
1617
|
})
|
|
1478
1618
|
.then(() => {
|
|
1619
|
+
if (isPortOccupied(port)) {
|
|
1620
|
+
throw new Error(`Port :${port} is still occupied after safe cleanup.`);
|
|
1621
|
+
}
|
|
1479
1622
|
startServer(latestVersion);
|
|
1480
1623
|
});
|
|
1624
|
+
}).catch((error) => {
|
|
1625
|
+
console.error(`ZevaiRouter startup aborted: ${error.message}`);
|
|
1626
|
+
console.error("An owned router process could not be cleaned up completely.");
|
|
1627
|
+
process.exitCode = 1;
|
|
1481
1628
|
});
|
|
1482
1629
|
|
|
1483
1630
|
// Show interface selection menu
|
|
@@ -1536,7 +1683,60 @@ function startServer(latestVersion) {
|
|
|
1536
1683
|
let serverStartTime = Date.now();
|
|
1537
1684
|
|
|
1538
1685
|
const CRASH_LOG_LINES = 50;
|
|
1686
|
+
const CRASH_LOG_BYTES = 64 * 1024;
|
|
1687
|
+
const SERVER_LOG_MAX_BYTES = 4 * 1024 * 1024;
|
|
1688
|
+
const SERVER_LOG_CHECK_MS = 30 * 1000;
|
|
1689
|
+
const serverLogPath = path.join(getAppDataDir(), "logs", "router-server.log");
|
|
1690
|
+
const noFollowFlag = fs.constants.O_NOFOLLOW || 0;
|
|
1691
|
+
const serverLogReadFlags = fs.constants.O_RDONLY | noFollowFlag;
|
|
1692
|
+
const serverLogWriteFlags = fs.constants.O_WRONLY
|
|
1693
|
+
| fs.constants.O_CREAT
|
|
1694
|
+
| fs.constants.O_APPEND
|
|
1695
|
+
| noFollowFlag;
|
|
1696
|
+
const serverDetached = !launchdOwned;
|
|
1539
1697
|
let crashLog = [];
|
|
1698
|
+
let serverLogOffset = null;
|
|
1699
|
+
let serverLogMaintenance = null;
|
|
1700
|
+
|
|
1701
|
+
function readServerCrashLog() {
|
|
1702
|
+
if (serverLogOffset == null) return [];
|
|
1703
|
+
let fd;
|
|
1704
|
+
try {
|
|
1705
|
+
fd = fs.openSync(serverLogPath, serverLogReadFlags);
|
|
1706
|
+
const stat = fs.fstatSync(fd);
|
|
1707
|
+
if (!stat.isFile()) return [];
|
|
1708
|
+
const size = stat.size;
|
|
1709
|
+
const start = Math.max(serverLogOffset, size - CRASH_LOG_BYTES, 0);
|
|
1710
|
+
const length = Math.max(0, size - start);
|
|
1711
|
+
if (length === 0) return [];
|
|
1712
|
+
const buffer = Buffer.alloc(length);
|
|
1713
|
+
fs.readSync(fd, buffer, 0, length, start);
|
|
1714
|
+
return buffer.toString("utf8").split("\n").filter(Boolean).slice(-CRASH_LOG_LINES);
|
|
1715
|
+
} catch {
|
|
1716
|
+
return [];
|
|
1717
|
+
} finally {
|
|
1718
|
+
if (fd != null) {
|
|
1719
|
+
try { fs.closeSync(fd); } catch {}
|
|
1720
|
+
}
|
|
1721
|
+
}
|
|
1722
|
+
}
|
|
1723
|
+
|
|
1724
|
+
function enforceServerLogLimit() {
|
|
1725
|
+
let fd;
|
|
1726
|
+
try {
|
|
1727
|
+
fd = fs.openSync(serverLogPath, serverLogWriteFlags, 0o600);
|
|
1728
|
+
const stat = fs.fstatSync(fd);
|
|
1729
|
+
if (!stat.isFile() || stat.size <= SERVER_LOG_MAX_BYTES) return;
|
|
1730
|
+
fs.ftruncateSync(fd, 0);
|
|
1731
|
+
serverLogOffset = 0;
|
|
1732
|
+
} catch {
|
|
1733
|
+
// Hidden logging is best-effort and must never take down the router.
|
|
1734
|
+
} finally {
|
|
1735
|
+
if (fd != null) {
|
|
1736
|
+
try { fs.closeSync(fd); } catch {}
|
|
1737
|
+
}
|
|
1738
|
+
}
|
|
1739
|
+
}
|
|
1540
1740
|
|
|
1541
1741
|
function spawnServer() {
|
|
1542
1742
|
serverStartTime = Date.now();
|
|
@@ -1547,28 +1747,49 @@ function startServer(latestVersion) {
|
|
|
1547
1747
|
const maxOldSpace = String(
|
|
1548
1748
|
parseInt(process.env.ZEVAI_MAX_OLD_SPACE_SIZE || "1536", 10) || 1536
|
|
1549
1749
|
);
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1750
|
+
let logFd = null;
|
|
1751
|
+
let stdio = "inherit";
|
|
1752
|
+
if (!showLog) {
|
|
1753
|
+
try {
|
|
1754
|
+
fs.mkdirSync(path.dirname(serverLogPath), { recursive: true, mode: 0o700 });
|
|
1755
|
+
logFd = fs.openSync(serverLogPath, serverLogWriteFlags, 0o600);
|
|
1756
|
+
const logStat = fs.fstatSync(logFd);
|
|
1757
|
+
if (!logStat.isFile()) throw new Error("router server log is not a regular file");
|
|
1758
|
+
if (logStat.size > SERVER_LOG_MAX_BYTES) fs.ftruncateSync(logFd, 0);
|
|
1759
|
+
serverLogOffset = fs.fstatSync(logFd).size;
|
|
1760
|
+
if (process.platform !== "win32") fs.fchmodSync(logFd, 0o600);
|
|
1761
|
+
stdio = ["ignore", "ignore", logFd];
|
|
1762
|
+
} catch {
|
|
1763
|
+
serverLogOffset = null;
|
|
1764
|
+
stdio = ["ignore", "ignore", "ignore"];
|
|
1559
1765
|
}
|
|
1560
|
-
}
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1766
|
+
} else {
|
|
1767
|
+
serverLogOffset = null;
|
|
1768
|
+
}
|
|
1769
|
+
try {
|
|
1770
|
+
return spawn(RUNTIME, [`--max-old-space-size=${maxOldSpace}`, serverPath], {
|
|
1771
|
+
cwd: standaloneDir,
|
|
1772
|
+
stdio,
|
|
1773
|
+
detached: serverDetached,
|
|
1774
|
+
windowsHide: true,
|
|
1775
|
+
env: {
|
|
1776
|
+
...buildEnvWithRuntime(serverDetached ? buildDetachedProcessEnv() : process.env),
|
|
1777
|
+
PORT: port.toString(),
|
|
1778
|
+
HOSTNAME: host
|
|
1779
|
+
}
|
|
1566
1780
|
});
|
|
1781
|
+
} finally {
|
|
1782
|
+
if (logFd != null) {
|
|
1783
|
+
try { fs.closeSync(logFd); } catch {}
|
|
1784
|
+
}
|
|
1567
1785
|
}
|
|
1568
|
-
return child;
|
|
1569
1786
|
}
|
|
1570
1787
|
|
|
1571
1788
|
let server = spawnServer();
|
|
1789
|
+
if (!showLog) {
|
|
1790
|
+
serverLogMaintenance = setInterval(enforceServerLogLimit, SERVER_LOG_CHECK_MS);
|
|
1791
|
+
serverLogMaintenance.unref?.();
|
|
1792
|
+
}
|
|
1572
1793
|
|
|
1573
1794
|
// Cleanup function - force kill server process
|
|
1574
1795
|
let isCleaningUp = false;
|
|
@@ -1585,12 +1806,17 @@ function startServer(latestVersion) {
|
|
|
1585
1806
|
killProxyByPidFile();
|
|
1586
1807
|
// Kill cloudflared/tailscale via PID file (only this app's tunnel)
|
|
1587
1808
|
killTunnelByPidFile();
|
|
1809
|
+
if (serverLogMaintenance) {
|
|
1810
|
+
clearInterval(serverLogMaintenance);
|
|
1811
|
+
serverLogMaintenance = null;
|
|
1812
|
+
}
|
|
1588
1813
|
// Kill server process directly
|
|
1589
1814
|
if (server.pid) {
|
|
1590
|
-
process.kill(server.pid, "SIGKILL");
|
|
1815
|
+
try { process.kill(server.pid, "SIGKILL"); } catch {}
|
|
1816
|
+
if (serverDetached) {
|
|
1817
|
+
try { process.kill(-server.pid, "SIGKILL"); } catch {}
|
|
1818
|
+
}
|
|
1591
1819
|
}
|
|
1592
|
-
// Also try to kill process group
|
|
1593
|
-
process.kill(-server.pid, "SIGKILL");
|
|
1594
1820
|
} catch (e) { }
|
|
1595
1821
|
}
|
|
1596
1822
|
|
|
@@ -1719,7 +1945,7 @@ function startServer(latestVersion) {
|
|
|
1719
1945
|
const child = spawn(process.execPath, [process.argv[1], "--skip-update", ...process.argv.slice(2).filter((a) => a !== "--skip-update")], {
|
|
1720
1946
|
detached: true,
|
|
1721
1947
|
stdio: "ignore",
|
|
1722
|
-
env:
|
|
1948
|
+
env: buildDetachedProcessEnv(),
|
|
1723
1949
|
});
|
|
1724
1950
|
child.unref();
|
|
1725
1951
|
} catch {
|
|
@@ -1769,7 +1995,7 @@ function startServer(latestVersion) {
|
|
|
1769
1995
|
detached: true,
|
|
1770
1996
|
stdio: "ignore",
|
|
1771
1997
|
windowsHide: true,
|
|
1772
|
-
env:
|
|
1998
|
+
env: buildDetachedProcessEnv()
|
|
1773
1999
|
});
|
|
1774
2000
|
bgProcess.unref();
|
|
1775
2001
|
|
|
@@ -1836,6 +2062,7 @@ function startServer(latestVersion) {
|
|
|
1836
2062
|
|
|
1837
2063
|
restartCount++;
|
|
1838
2064
|
const delay = Math.min(1000 * restartCount, 10000);
|
|
2065
|
+
crashLog = readServerCrashLog();
|
|
1839
2066
|
console.error(`\n⚠️ Server exited (code=${code ?? "unknown"}). Restarting in ${delay / 1000}s... (${restartCount}/${MAX_RESTARTS})`);
|
|
1840
2067
|
if (crashLog.length) {
|
|
1841
2068
|
console.error("\n--- Server crash log ---");
|