zevairouter 1.0.93 → 1.0.94
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/cli/app/.next-cli-build/BUILD_ID +1 -1
- package/cli/app/.next-cli-build/app-path-routes-manifest.json +5 -5
- 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/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/models/test/route.js +1 -1
- package/cli/app/.next-cli-build/server/app/api/providers/[id]/test-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/terminal/session/[id]/input/route.js.nft.json +1 -1
- package/cli/app/.next-cli-build/server/app/api/terminal/session/[id]/resize/route.js.nft.json +1 -1
- package/cli/app/.next-cli-build/server/app/api/terminal/session/[id]/route.js.nft.json +1 -1
- package/cli/app/.next-cli-build/server/app/api/terminal/session/[id]/stream/route.js.nft.json +1 -1
- package/cli/app/.next-cli-build/server/app/api/terminal/session/route.js.nft.json +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/page_client-reference-manifest.js +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 +3 -3
- package/cli/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/_full.segment.rsc +3 -3
- 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/settings/pricing.segments/dashboard/settings/pricing/__PAGE__.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/dashboard/settings/pricing.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/dashboard/settings.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/dashboard.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 +3 -3
- package/cli/app/.next-cli-build/server/app/landing.segments/_full.segment.rsc +3 -3
- 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 +1 -1
- 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 +5 -5
- package/cli/app/.next-cli-build/server/chunks/3155.js +1 -1
- package/cli/app/.next-cli-build/server/chunks/3407.js +1 -1
- package/cli/app/.next-cli-build/server/chunks/4746.js +1 -1
- package/cli/app/.next-cli-build/server/chunks/6896.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/{3702-a9d48ed3afa2d5fd.js → 3702-19d4792a55f43d97.js} +1 -1
- package/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/src/lib/terminal/ptyBridge.py +163 -0
- package/cli/app/package.json +1 -1
- package/cli/app/src/lib/updater/updater.js +100 -8
- package/cli/cli.js +66 -11
- package/cli/package.json +1 -1
- package/package.json +1 -1
- package/src/lib/appUpdater.js +8 -4
- package/src/lib/updater/updater.js +100 -8
- /package/cli/app/.next-cli-build/static/{cHK1E1W2f05Bp9LKjAKXv → FDemdi0iaxtPuo9mMUQVS}/_buildManifest.js +0 -0
- /package/cli/app/.next-cli-build/static/{cHK1E1W2f05Bp9LKjAKXv → FDemdi0iaxtPuo9mMUQVS}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Minimal PTY bridge for ZevaiRouter web terminal.
|
|
4
|
+
|
|
5
|
+
stdin -> PTY master (keystrokes)
|
|
6
|
+
stdout <- PTY master (shell output), raw binary
|
|
7
|
+
stderr = control / errors (utf-8 text lines)
|
|
8
|
+
|
|
9
|
+
Optional control on a side channel is not needed: resize arrives as
|
|
10
|
+
OSC-like escape on stdin: \\x1b]9999;<cols>;<rows>\\x07
|
|
11
|
+
"""
|
|
12
|
+
from __future__ import annotations
|
|
13
|
+
|
|
14
|
+
import errno
|
|
15
|
+
import fcntl
|
|
16
|
+
import os
|
|
17
|
+
import select
|
|
18
|
+
import signal
|
|
19
|
+
import struct
|
|
20
|
+
import sys
|
|
21
|
+
import termios
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def set_winsize(fd: int, rows: int, cols: int) -> None:
|
|
25
|
+
try:
|
|
26
|
+
packed = struct.pack("HHHH", max(5, rows), max(20, cols), 0, 0)
|
|
27
|
+
fcntl.ioctl(fd, termios.TIOCSWINSZ, packed)
|
|
28
|
+
except Exception:
|
|
29
|
+
pass
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def main() -> int:
|
|
33
|
+
cols = int(sys.argv[1]) if len(sys.argv) > 1 else 120
|
|
34
|
+
rows = int(sys.argv[2]) if len(sys.argv) > 2 else 40
|
|
35
|
+
shell = os.environ.get("SHELL") or ("/bin/bash" if os.path.exists("/bin/bash") else "/bin/sh")
|
|
36
|
+
cwd = os.path.expanduser("~")
|
|
37
|
+
|
|
38
|
+
pid, master = pty_fork = _fork_pty()
|
|
39
|
+
if pid == 0:
|
|
40
|
+
# child
|
|
41
|
+
try:
|
|
42
|
+
os.chdir(cwd)
|
|
43
|
+
except Exception:
|
|
44
|
+
pass
|
|
45
|
+
os.environ.setdefault("TERM", "xterm-256color")
|
|
46
|
+
os.environ.setdefault("COLORTERM", "truecolor")
|
|
47
|
+
os.environ.setdefault("FORCE_COLOR", "1")
|
|
48
|
+
try:
|
|
49
|
+
os.execv(shell, [shell, "-il"])
|
|
50
|
+
except Exception:
|
|
51
|
+
os.execv("/bin/sh", ["/bin/sh", "-i"])
|
|
52
|
+
return 1
|
|
53
|
+
|
|
54
|
+
set_winsize(master, rows, cols)
|
|
55
|
+
|
|
56
|
+
# Non-blocking master + stdin
|
|
57
|
+
for fd in (master, sys.stdin.fileno()):
|
|
58
|
+
fl = fcntl.fcntl(fd, fcntl.F_GETFL)
|
|
59
|
+
fcntl.fcntl(fd, fcntl.F_SETFL, fl | os.O_NONBLOCK)
|
|
60
|
+
|
|
61
|
+
# Binary stdout
|
|
62
|
+
stdout = sys.stdout.buffer
|
|
63
|
+
stdin = sys.stdin.buffer
|
|
64
|
+
|
|
65
|
+
resize_buf = b""
|
|
66
|
+
|
|
67
|
+
def handle_resize_escape(chunk: bytes) -> bytes:
|
|
68
|
+
"""Strip and apply embedded resize escapes, return remaining bytes."""
|
|
69
|
+
nonlocal resize_buf
|
|
70
|
+
data = resize_buf + chunk
|
|
71
|
+
out = bytearray()
|
|
72
|
+
i = 0
|
|
73
|
+
while i < len(data):
|
|
74
|
+
# ESC ] 9999 ; cols ; rows BEL
|
|
75
|
+
if data[i] == 0x1B and data[i : i + 6] == b"\x1b]9999;":
|
|
76
|
+
end = data.find(b"\x07", i + 6)
|
|
77
|
+
if end < 0:
|
|
78
|
+
resize_buf = data[i:]
|
|
79
|
+
return bytes(out)
|
|
80
|
+
payload = data[i + 6 : end].decode("ascii", "ignore")
|
|
81
|
+
try:
|
|
82
|
+
c_s, r_s = payload.split(";", 1)
|
|
83
|
+
set_winsize(master, int(r_s), int(c_s))
|
|
84
|
+
except Exception:
|
|
85
|
+
pass
|
|
86
|
+
i = end + 1
|
|
87
|
+
resize_buf = b""
|
|
88
|
+
continue
|
|
89
|
+
out.append(data[i])
|
|
90
|
+
i += 1
|
|
91
|
+
resize_buf = b""
|
|
92
|
+
return bytes(out)
|
|
93
|
+
|
|
94
|
+
alive = True
|
|
95
|
+
|
|
96
|
+
def on_chld(signum, frame): # noqa: ARG001
|
|
97
|
+
nonlocal alive
|
|
98
|
+
alive = False
|
|
99
|
+
|
|
100
|
+
signal.signal(signal.SIGCHLD, on_chld)
|
|
101
|
+
|
|
102
|
+
try:
|
|
103
|
+
while alive:
|
|
104
|
+
try:
|
|
105
|
+
r, _, _ = select.select([master, sys.stdin.fileno()], [], [], 0.25)
|
|
106
|
+
except InterruptedError:
|
|
107
|
+
continue
|
|
108
|
+
|
|
109
|
+
if master in r:
|
|
110
|
+
try:
|
|
111
|
+
data = os.read(master, 8192)
|
|
112
|
+
except OSError as e:
|
|
113
|
+
if e.errno in (errno.EIO, errno.EAGAIN, errno.EWOULDBLOCK):
|
|
114
|
+
data = b""
|
|
115
|
+
else:
|
|
116
|
+
break
|
|
117
|
+
if not data:
|
|
118
|
+
# EIO often means child exited
|
|
119
|
+
if not alive:
|
|
120
|
+
break
|
|
121
|
+
else:
|
|
122
|
+
stdout.write(data)
|
|
123
|
+
stdout.flush()
|
|
124
|
+
|
|
125
|
+
if sys.stdin.fileno() in r:
|
|
126
|
+
try:
|
|
127
|
+
data = stdin.read(8192)
|
|
128
|
+
except Exception:
|
|
129
|
+
data = b""
|
|
130
|
+
if data is None:
|
|
131
|
+
data = b""
|
|
132
|
+
if data == b"" and not alive:
|
|
133
|
+
break
|
|
134
|
+
if data:
|
|
135
|
+
cleaned = handle_resize_escape(data)
|
|
136
|
+
if cleaned:
|
|
137
|
+
try:
|
|
138
|
+
os.write(master, cleaned)
|
|
139
|
+
except OSError:
|
|
140
|
+
break
|
|
141
|
+
finally:
|
|
142
|
+
try:
|
|
143
|
+
os.close(master)
|
|
144
|
+
except Exception:
|
|
145
|
+
pass
|
|
146
|
+
try:
|
|
147
|
+
os.waitpid(pid, 0)
|
|
148
|
+
except Exception:
|
|
149
|
+
pass
|
|
150
|
+
return 0
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
def _fork_pty():
|
|
154
|
+
import pty
|
|
155
|
+
|
|
156
|
+
return pty.fork()
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
if __name__ == "__main__":
|
|
160
|
+
try:
|
|
161
|
+
raise SystemExit(main())
|
|
162
|
+
except KeyboardInterrupt:
|
|
163
|
+
raise SystemExit(0)
|
package/cli/app/package.json
CHANGED
|
@@ -9,7 +9,8 @@ const path = require("path");
|
|
|
9
9
|
const fs = require("fs");
|
|
10
10
|
const os = require("os");
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
// Must be npm package name (zevairouter), NOT the CLI bin (zevai).
|
|
13
|
+
const packageName = process.env.UPDATER_PKG_NAME || "zevairouter";
|
|
13
14
|
const port = parseInt(process.env.UPDATER_PORT || "20129", 10);
|
|
14
15
|
const tailLines = parseInt(process.env.UPDATER_TAIL_LINES || "8", 10);
|
|
15
16
|
const maxRetries = parseInt(process.env.UPDATER_RETRIES || "3", 10);
|
|
@@ -128,19 +129,72 @@ function sleep(ms) {
|
|
|
128
129
|
return new Promise((r) => setTimeout(r, ms));
|
|
129
130
|
}
|
|
130
131
|
|
|
132
|
+
function resolveSafeInstallHook() {
|
|
133
|
+
const candidates = [
|
|
134
|
+
path.join(path.dirname(process.execPath), "..", "lib", "node_modules", "zevairouter", "cli", "hooks", "safeGlobalInstall.js"),
|
|
135
|
+
path.join("/usr/lib/node_modules/zevairouter/cli/hooks/safeGlobalInstall.js"),
|
|
136
|
+
path.join("/usr/local/lib/node_modules/zevairouter/cli/hooks/safeGlobalInstall.js"),
|
|
137
|
+
path.join("/opt/homebrew/lib/node_modules/zevairouter/cli/hooks/safeGlobalInstall.js"),
|
|
138
|
+
...String(process.env.NODE_PATH || "")
|
|
139
|
+
.split(path.delimiter)
|
|
140
|
+
.filter(Boolean)
|
|
141
|
+
.map((p) => path.join(p, "zevairouter", "cli", "hooks", "safeGlobalInstall.js")),
|
|
142
|
+
];
|
|
143
|
+
try {
|
|
144
|
+
const { createRequire } = require("module");
|
|
145
|
+
const req = createRequire(path.join(process.cwd(), "package.json"));
|
|
146
|
+
candidates.unshift(req.resolve("zevairouter/cli/hooks/safeGlobalInstall.js"));
|
|
147
|
+
} catch { /* ignore */ }
|
|
148
|
+
// Updater itself may live next to a package tree under ~/.zevai
|
|
149
|
+
try {
|
|
150
|
+
const dataDir = getDataDir();
|
|
151
|
+
candidates.push(
|
|
152
|
+
path.join(dataDir, "runtime", "node_modules", "zevairouter", "cli", "hooks", "safeGlobalInstall.js"),
|
|
153
|
+
);
|
|
154
|
+
} catch { /* ignore */ }
|
|
155
|
+
|
|
156
|
+
for (const p of candidates) {
|
|
157
|
+
try {
|
|
158
|
+
if (p && fs.existsSync(p)) return p;
|
|
159
|
+
} catch { /* next */ }
|
|
160
|
+
}
|
|
161
|
+
return null;
|
|
162
|
+
}
|
|
163
|
+
|
|
131
164
|
function runInstall() {
|
|
132
165
|
state.attempt += 1;
|
|
133
166
|
setPhase("installing");
|
|
134
|
-
|
|
167
|
+
// Force-clean path (ENOTEMPTY-safe) like `zevai update` / install.sh.
|
|
168
|
+
// Plain `npm i -g` often leaves the old build running or fails half-way on VPS.
|
|
169
|
+
const pkgSpec = packageName.includes("@") ? packageName : `${packageName}@latest`;
|
|
170
|
+
pushLog(`[updater] attempt ${state.attempt}/${maxRetries} — safe install ${pkgSpec}`);
|
|
135
171
|
|
|
136
172
|
const isWin = process.platform === "win32";
|
|
137
|
-
const
|
|
138
|
-
|
|
173
|
+
const hook = resolveSafeInstallHook();
|
|
174
|
+
|
|
175
|
+
let cmd;
|
|
176
|
+
let args;
|
|
177
|
+
if (hook) {
|
|
178
|
+
cmd = process.execPath;
|
|
179
|
+
args = [hook, "--latest"];
|
|
180
|
+
pushLog(`[updater] using safeGlobalInstall: ${hook}`);
|
|
181
|
+
} else {
|
|
182
|
+
cmd = isWin ? "npm.cmd" : "npm";
|
|
183
|
+
// Explicit @latest — never install a phantom "zevai" package.
|
|
184
|
+
args = ["i", "-g", pkgSpec, "--prefer-online"];
|
|
185
|
+
pushLog(`[updater] safe hook missing — fallback npm ${args.join(" ")}`);
|
|
186
|
+
}
|
|
139
187
|
|
|
140
188
|
const child = spawn(cmd, args, {
|
|
141
189
|
stdio: ["ignore", "pipe", "pipe"],
|
|
142
190
|
windowsHide: true,
|
|
143
|
-
shell: isWin,
|
|
191
|
+
shell: isWin && !hook,
|
|
192
|
+
env: {
|
|
193
|
+
...process.env,
|
|
194
|
+
npm_config_fund: "false",
|
|
195
|
+
npm_config_audit: "false",
|
|
196
|
+
npm_config_update_notifier: "false",
|
|
197
|
+
},
|
|
144
198
|
});
|
|
145
199
|
|
|
146
200
|
child.stdout.on("data", (buf) => {
|
|
@@ -158,7 +212,7 @@ function runInstall() {
|
|
|
158
212
|
});
|
|
159
213
|
|
|
160
214
|
child.on("close", (code) => {
|
|
161
|
-
pushLog(`[updater]
|
|
215
|
+
pushLog(`[updater] install exited with code ${code}`);
|
|
162
216
|
if (code === 0) {
|
|
163
217
|
finalize(true, code, null);
|
|
164
218
|
return;
|
|
@@ -195,8 +249,40 @@ async function waitForAppAndOpenBrowser() {
|
|
|
195
249
|
pushLog(`[updater] app not responding within 30s, skip browser open`);
|
|
196
250
|
}
|
|
197
251
|
|
|
252
|
+
function trySystemdRestart() {
|
|
253
|
+
if (process.platform === "win32" || process.platform === "darwin") return false;
|
|
254
|
+
try {
|
|
255
|
+
const { execFileSync } = require("child_process");
|
|
256
|
+
// Prefer our unit name; fall back to common aliases.
|
|
257
|
+
const units = ["zevairouter.service", "zevai.service"];
|
|
258
|
+
for (const unit of units) {
|
|
259
|
+
try {
|
|
260
|
+
execFileSync("systemctl", ["cat", unit], { stdio: "ignore", timeout: 3000 });
|
|
261
|
+
} catch {
|
|
262
|
+
continue;
|
|
263
|
+
}
|
|
264
|
+
pushLog(`[updater] restarting systemd unit ${unit}`);
|
|
265
|
+
execFileSync("systemctl", ["daemon-reload"], { stdio: "ignore", timeout: 10000 });
|
|
266
|
+
execFileSync("systemctl", ["restart", unit], { stdio: "ignore", timeout: 30000 });
|
|
267
|
+
pushLog(`[updater] systemctl restart ${unit} OK`);
|
|
268
|
+
return true;
|
|
269
|
+
}
|
|
270
|
+
} catch (e) {
|
|
271
|
+
pushLog(`[updater] systemd restart skipped: ${e.message}`);
|
|
272
|
+
}
|
|
273
|
+
return false;
|
|
274
|
+
}
|
|
275
|
+
|
|
198
276
|
function relaunchApp() {
|
|
199
277
|
if (process.env.UPDATER_RELAUNCH !== "1") return;
|
|
278
|
+
|
|
279
|
+
// VPS path: if systemd owns the service, restart that — don't spawn a second
|
|
280
|
+
// tray process that leaves the unit on the old binary forever.
|
|
281
|
+
if (trySystemdRestart()) {
|
|
282
|
+
waitForAppAndOpenBrowser();
|
|
283
|
+
return;
|
|
284
|
+
}
|
|
285
|
+
|
|
200
286
|
const cmd = process.env.UPDATER_RELAUNCH_CMD;
|
|
201
287
|
if (!cmd) return;
|
|
202
288
|
let args = [];
|
|
@@ -208,11 +294,17 @@ function relaunchApp() {
|
|
|
208
294
|
stdio: "ignore",
|
|
209
295
|
windowsHide: true,
|
|
210
296
|
shell: isWin,
|
|
211
|
-
env: {
|
|
297
|
+
env: {
|
|
298
|
+
...process.env,
|
|
299
|
+
UPDATER_RELAUNCH: "",
|
|
300
|
+
UPDATER_RELAUNCH_CMD: "",
|
|
301
|
+
UPDATER_RELAUNCH_ARGS: "",
|
|
302
|
+
// Prevent cli.js from flipping headless server restarts into tray mode.
|
|
303
|
+
ZEVAI_SERVER_MODE: args.includes("--tray") ? "" : "1",
|
|
304
|
+
},
|
|
212
305
|
});
|
|
213
306
|
child.unref();
|
|
214
307
|
pushLog(`[updater] relaunched: ${cmd} ${args.join(" ")} (pid=${child.pid})`);
|
|
215
|
-
// Wait for new app to come up, then auto-open browser so user sees the result
|
|
216
308
|
waitForAppAndOpenBrowser();
|
|
217
309
|
} catch (e) {
|
|
218
310
|
pushLog(`[updater] relaunch failed: ${e.message}`);
|
package/cli/cli.js
CHANGED
|
@@ -123,12 +123,16 @@ Options:
|
|
|
123
123
|
--force-restart Kill existing instance and start a new one (default: attach if healthy)
|
|
124
124
|
--doctor Show install paths (Node/npm/global) + dual-install hints
|
|
125
125
|
--fix-install Repair/reinstall global package for THIS Node (ENOTEMPTY-safe)
|
|
126
|
+
update [--to X.Y.Z] Force update + restart (VPS: systemctl, desktop: relaunch)
|
|
126
127
|
-h, --help Show this help message
|
|
127
128
|
-v, --version Show version
|
|
128
129
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
130
|
+
Update (simple — same Node as this zevai, restarts service):
|
|
131
|
+
zevai update
|
|
132
|
+
zevai update --to 1.0.93
|
|
133
|
+
|
|
134
|
+
One-shot install / reinstall (any device):
|
|
135
|
+
curl -fsSL https://gist.githubusercontent.com/Verifiedlabs/7fe0ab16692acbacd1b471d2c1bbd09b/raw/install.sh | bash
|
|
132
136
|
`);
|
|
133
137
|
process.exit(0);
|
|
134
138
|
} else if (args[i] === "--version" || args[i] === "-v") {
|
|
@@ -142,30 +146,63 @@ One-shot install (any device):
|
|
|
142
146
|
process.exit(1);
|
|
143
147
|
}
|
|
144
148
|
process.exit(0);
|
|
145
|
-
} else if (args[i] === "--fix-install") {
|
|
149
|
+
} else if (args[i] === "--fix-install" || args[i] === "update" || args[i] === "--update") {
|
|
150
|
+
// `zevai update` — one command, same as 9router simplicity.
|
|
151
|
+
// Force-clean global install + restart systemd (VPS) or relaunch process.
|
|
146
152
|
try {
|
|
147
153
|
const { safeInstallGlobal } = require("./hooks/safeGlobalInstall");
|
|
148
|
-
const { spawn } = require("child_process");
|
|
154
|
+
const { spawn, execFileSync } = require("child_process");
|
|
149
155
|
const fs = require("fs");
|
|
150
156
|
const path = require("path");
|
|
151
157
|
const verIdx = args.indexOf("--to");
|
|
152
158
|
const version = verIdx >= 0 && args[verIdx + 1] ? args[verIdx + 1] : "latest";
|
|
153
159
|
const wasTray = process.argv.includes("--tray") || process.env.TRAY_MODE === "1";
|
|
160
|
+
console.log(`\nUpdating zevairouter@${version}…`);
|
|
154
161
|
const result = safeInstallGlobal({ version, forceClean: true });
|
|
155
162
|
if (!result.ok) {
|
|
156
163
|
console.error(result.error || "install failed");
|
|
157
164
|
process.exit(1);
|
|
158
165
|
}
|
|
159
|
-
console.log(`\
|
|
166
|
+
console.log(`\n✓ Installed zevairouter@${result.version || version}`);
|
|
167
|
+
console.log(` binary: ${result.zevaiPath || "zevai"}`);
|
|
160
168
|
|
|
161
169
|
// Relaunch new binary detached, then exit this process so the new build loads.
|
|
162
170
|
if (process.env.ZEVAI_SKIP_RESTART === "1") {
|
|
163
171
|
console.log(`Restart skipped (ZEVAI_SKIP_RESTART=1). Run: zevai`);
|
|
164
172
|
process.exit(0);
|
|
165
173
|
}
|
|
174
|
+
|
|
175
|
+
// VPS: prefer systemd so the unit picks up the new binary path.
|
|
176
|
+
if (process.platform === "linux") {
|
|
177
|
+
for (const unit of ["zevairouter.service", "zevai.service"]) {
|
|
178
|
+
try {
|
|
179
|
+
execFileSync("systemctl", ["cat", unit], { stdio: "ignore", timeout: 3000 });
|
|
180
|
+
console.log(`Restarting ${unit}…`);
|
|
181
|
+
try { execFileSync("systemctl", ["daemon-reload"], { stdio: "ignore", timeout: 10000 }); } catch { /* ignore */ }
|
|
182
|
+
execFileSync("systemctl", ["restart", unit], { stdio: "inherit", timeout: 30000 });
|
|
183
|
+
// Brief health check
|
|
184
|
+
try {
|
|
185
|
+
const { execSync } = require("child_process");
|
|
186
|
+
for (let i = 0; i < 15; i++) {
|
|
187
|
+
execSync("sleep 1");
|
|
188
|
+
try {
|
|
189
|
+
const out = execSync("curl -sS -m 2 http://127.0.0.1:1997/api/version", { encoding: "utf8" });
|
|
190
|
+
console.log(`✓ Live: ${out.trim()}`);
|
|
191
|
+
process.exit(0);
|
|
192
|
+
} catch { /* wait */ }
|
|
193
|
+
}
|
|
194
|
+
} catch { /* ignore */ }
|
|
195
|
+
console.log(`✓ systemctl restart ${unit} done. Check: curl -s http://127.0.0.1:1997/api/version`);
|
|
196
|
+
process.exit(0);
|
|
197
|
+
} catch {
|
|
198
|
+
/* try next unit */
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
166
203
|
const relaunchArgs = wasTray
|
|
167
204
|
? ["--tray", "--skip-update"]
|
|
168
|
-
: ["--port", process.env.PORT || "1997", "--no-browser", "--skip-update"];
|
|
205
|
+
: ["--port", process.env.PORT || "1997", "--no-browser", "--skip-update", "--log"];
|
|
169
206
|
try {
|
|
170
207
|
const logDir = path.join(process.env.HOME || process.env.USERPROFILE || ".", ".zevai", "logs");
|
|
171
208
|
fs.mkdirSync(logDir, { recursive: true });
|
|
@@ -179,13 +216,21 @@ One-shot install (any device):
|
|
|
179
216
|
? spawn(process.execPath, [cliEntry, ...relaunchArgs], {
|
|
180
217
|
detached: true,
|
|
181
218
|
stdio: ["ignore", out, out],
|
|
182
|
-
env: {
|
|
219
|
+
env: {
|
|
220
|
+
...process.env,
|
|
221
|
+
TRAY_MODE: wasTray ? "1" : "",
|
|
222
|
+
ZEVAI_SERVER_MODE: wasTray ? "" : "1",
|
|
223
|
+
},
|
|
183
224
|
})
|
|
184
225
|
: spawn(result.zevaiPath || "zevai", relaunchArgs, {
|
|
185
226
|
detached: true,
|
|
186
227
|
stdio: ["ignore", out, out],
|
|
187
228
|
shell: process.platform === "win32",
|
|
188
|
-
env: {
|
|
229
|
+
env: {
|
|
230
|
+
...process.env,
|
|
231
|
+
TRAY_MODE: wasTray ? "1" : "",
|
|
232
|
+
ZEVAI_SERVER_MODE: wasTray ? "" : "1",
|
|
233
|
+
},
|
|
189
234
|
});
|
|
190
235
|
child.unref();
|
|
191
236
|
console.log(`Restarting ${wasTray ? "tray" : "server"}… (log ${logFile})`);
|
|
@@ -197,14 +242,24 @@ One-shot install (any device):
|
|
|
197
242
|
// Exit soon so :1997 is free for the new process.
|
|
198
243
|
setTimeout(() => process.exit(0), 500);
|
|
199
244
|
} catch (e) {
|
|
200
|
-
console.error("
|
|
245
|
+
console.error("update failed:", e.message);
|
|
201
246
|
process.exit(1);
|
|
202
247
|
}
|
|
203
248
|
}
|
|
204
249
|
}
|
|
205
250
|
|
|
206
251
|
// Auto-relaunch after update: detached process has no TTY → fallback to tray
|
|
207
|
-
|
|
252
|
+
// ONLY for desktop/tray flows. VPS server mode must stay server.
|
|
253
|
+
if (
|
|
254
|
+
skipUpdate
|
|
255
|
+
&& !trayMode
|
|
256
|
+
&& !process.stdin.isTTY
|
|
257
|
+
&& process.env.ZEVAI_SERVER_MODE !== "1"
|
|
258
|
+
&& !process.env.PORT
|
|
259
|
+
&& process.env.TRAY_MODE !== "0"
|
|
260
|
+
) {
|
|
261
|
+
// Heuristic: systemd / nohup restarts often set PORT or ZEVAI_SERVER_MODE.
|
|
262
|
+
// If neither is set and no TTY, assume desktop tray (legacy 9router behaviour).
|
|
208
263
|
trayMode = true;
|
|
209
264
|
process.env.TRAY_MODE = "1";
|
|
210
265
|
}
|
package/cli/package.json
CHANGED
package/package.json
CHANGED
package/src/lib/appUpdater.js
CHANGED
|
@@ -169,10 +169,12 @@ export function spawnUpdaterAndExit(packageName = UPDATER_CONFIG.npmPackageName)
|
|
|
169
169
|
const updaterPath = ensureRuntimeUpdater(resolveBundledUpdaterPath());
|
|
170
170
|
const isTray = process.env.TRAY_MODE === "1";
|
|
171
171
|
const relaunch = resolveRelaunchCommand();
|
|
172
|
-
// Relaunch matching original env: tray stays tray
|
|
172
|
+
// Relaunch matching original env: tray stays tray; server stays server
|
|
173
|
+
// (must pass --port/--no-browser so VPS doesn't flip into tray via no-TTY).
|
|
174
|
+
const appPort = String(process.env.PORT || UPDATER_CONFIG.appPort || 1997);
|
|
173
175
|
const relaunchArgs = isTray
|
|
174
176
|
? [...relaunch.args, "--tray", "--skip-update"]
|
|
175
|
-
: [...relaunch.args, "--skip-update"];
|
|
177
|
+
: [...relaunch.args, "--port", appPort, "--no-browser", "--skip-update", "--log"];
|
|
176
178
|
|
|
177
179
|
spawn(process.execPath, [updaterPath], {
|
|
178
180
|
detached: true,
|
|
@@ -180,7 +182,8 @@ export function spawnUpdaterAndExit(packageName = UPDATER_CONFIG.npmPackageName)
|
|
|
180
182
|
windowsHide: true,
|
|
181
183
|
env: {
|
|
182
184
|
...process.env,
|
|
183
|
-
|
|
185
|
+
// Always npm package name — never the CLI bin name "zevai".
|
|
186
|
+
UPDATER_PKG_NAME: packageName || "zevairouter",
|
|
184
187
|
UPDATER_PORT: String(UPDATER_CONFIG.statusPort),
|
|
185
188
|
UPDATER_TAIL_LINES: String(UPDATER_CONFIG.statusLogTailLines),
|
|
186
189
|
UPDATER_RETRIES: String(UPDATER_CONFIG.installRetries),
|
|
@@ -189,10 +192,11 @@ export function spawnUpdaterAndExit(packageName = UPDATER_CONFIG.npmPackageName)
|
|
|
189
192
|
UPDATER_WAIT_MIN_MS: String(UPDATER_CONFIG.waitForExitMinMs),
|
|
190
193
|
UPDATER_WAIT_MAX_MS: String(UPDATER_CONFIG.waitForExitMaxMs),
|
|
191
194
|
UPDATER_WAIT_CHECK_MS: String(UPDATER_CONFIG.waitForExitCheckMs),
|
|
192
|
-
UPDATER_APP_PORT:
|
|
195
|
+
UPDATER_APP_PORT: appPort,
|
|
193
196
|
UPDATER_RELAUNCH: "1",
|
|
194
197
|
UPDATER_RELAUNCH_CMD: relaunch.cmd,
|
|
195
198
|
UPDATER_RELAUNCH_ARGS: JSON.stringify(relaunchArgs),
|
|
199
|
+
ZEVAI_SERVER_MODE: isTray ? "" : "1",
|
|
196
200
|
},
|
|
197
201
|
}).unref();
|
|
198
202
|
|
|
@@ -9,7 +9,8 @@ const path = require("path");
|
|
|
9
9
|
const fs = require("fs");
|
|
10
10
|
const os = require("os");
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
// Must be npm package name (zevairouter), NOT the CLI bin (zevai).
|
|
13
|
+
const packageName = process.env.UPDATER_PKG_NAME || "zevairouter";
|
|
13
14
|
const port = parseInt(process.env.UPDATER_PORT || "20129", 10);
|
|
14
15
|
const tailLines = parseInt(process.env.UPDATER_TAIL_LINES || "8", 10);
|
|
15
16
|
const maxRetries = parseInt(process.env.UPDATER_RETRIES || "3", 10);
|
|
@@ -128,19 +129,72 @@ function sleep(ms) {
|
|
|
128
129
|
return new Promise((r) => setTimeout(r, ms));
|
|
129
130
|
}
|
|
130
131
|
|
|
132
|
+
function resolveSafeInstallHook() {
|
|
133
|
+
const candidates = [
|
|
134
|
+
path.join(path.dirname(process.execPath), "..", "lib", "node_modules", "zevairouter", "cli", "hooks", "safeGlobalInstall.js"),
|
|
135
|
+
path.join("/usr/lib/node_modules/zevairouter/cli/hooks/safeGlobalInstall.js"),
|
|
136
|
+
path.join("/usr/local/lib/node_modules/zevairouter/cli/hooks/safeGlobalInstall.js"),
|
|
137
|
+
path.join("/opt/homebrew/lib/node_modules/zevairouter/cli/hooks/safeGlobalInstall.js"),
|
|
138
|
+
...String(process.env.NODE_PATH || "")
|
|
139
|
+
.split(path.delimiter)
|
|
140
|
+
.filter(Boolean)
|
|
141
|
+
.map((p) => path.join(p, "zevairouter", "cli", "hooks", "safeGlobalInstall.js")),
|
|
142
|
+
];
|
|
143
|
+
try {
|
|
144
|
+
const { createRequire } = require("module");
|
|
145
|
+
const req = createRequire(path.join(process.cwd(), "package.json"));
|
|
146
|
+
candidates.unshift(req.resolve("zevairouter/cli/hooks/safeGlobalInstall.js"));
|
|
147
|
+
} catch { /* ignore */ }
|
|
148
|
+
// Updater itself may live next to a package tree under ~/.zevai
|
|
149
|
+
try {
|
|
150
|
+
const dataDir = getDataDir();
|
|
151
|
+
candidates.push(
|
|
152
|
+
path.join(dataDir, "runtime", "node_modules", "zevairouter", "cli", "hooks", "safeGlobalInstall.js"),
|
|
153
|
+
);
|
|
154
|
+
} catch { /* ignore */ }
|
|
155
|
+
|
|
156
|
+
for (const p of candidates) {
|
|
157
|
+
try {
|
|
158
|
+
if (p && fs.existsSync(p)) return p;
|
|
159
|
+
} catch { /* next */ }
|
|
160
|
+
}
|
|
161
|
+
return null;
|
|
162
|
+
}
|
|
163
|
+
|
|
131
164
|
function runInstall() {
|
|
132
165
|
state.attempt += 1;
|
|
133
166
|
setPhase("installing");
|
|
134
|
-
|
|
167
|
+
// Force-clean path (ENOTEMPTY-safe) like `zevai update` / install.sh.
|
|
168
|
+
// Plain `npm i -g` often leaves the old build running or fails half-way on VPS.
|
|
169
|
+
const pkgSpec = packageName.includes("@") ? packageName : `${packageName}@latest`;
|
|
170
|
+
pushLog(`[updater] attempt ${state.attempt}/${maxRetries} — safe install ${pkgSpec}`);
|
|
135
171
|
|
|
136
172
|
const isWin = process.platform === "win32";
|
|
137
|
-
const
|
|
138
|
-
|
|
173
|
+
const hook = resolveSafeInstallHook();
|
|
174
|
+
|
|
175
|
+
let cmd;
|
|
176
|
+
let args;
|
|
177
|
+
if (hook) {
|
|
178
|
+
cmd = process.execPath;
|
|
179
|
+
args = [hook, "--latest"];
|
|
180
|
+
pushLog(`[updater] using safeGlobalInstall: ${hook}`);
|
|
181
|
+
} else {
|
|
182
|
+
cmd = isWin ? "npm.cmd" : "npm";
|
|
183
|
+
// Explicit @latest — never install a phantom "zevai" package.
|
|
184
|
+
args = ["i", "-g", pkgSpec, "--prefer-online"];
|
|
185
|
+
pushLog(`[updater] safe hook missing — fallback npm ${args.join(" ")}`);
|
|
186
|
+
}
|
|
139
187
|
|
|
140
188
|
const child = spawn(cmd, args, {
|
|
141
189
|
stdio: ["ignore", "pipe", "pipe"],
|
|
142
190
|
windowsHide: true,
|
|
143
|
-
shell: isWin,
|
|
191
|
+
shell: isWin && !hook,
|
|
192
|
+
env: {
|
|
193
|
+
...process.env,
|
|
194
|
+
npm_config_fund: "false",
|
|
195
|
+
npm_config_audit: "false",
|
|
196
|
+
npm_config_update_notifier: "false",
|
|
197
|
+
},
|
|
144
198
|
});
|
|
145
199
|
|
|
146
200
|
child.stdout.on("data", (buf) => {
|
|
@@ -158,7 +212,7 @@ function runInstall() {
|
|
|
158
212
|
});
|
|
159
213
|
|
|
160
214
|
child.on("close", (code) => {
|
|
161
|
-
pushLog(`[updater]
|
|
215
|
+
pushLog(`[updater] install exited with code ${code}`);
|
|
162
216
|
if (code === 0) {
|
|
163
217
|
finalize(true, code, null);
|
|
164
218
|
return;
|
|
@@ -195,8 +249,40 @@ async function waitForAppAndOpenBrowser() {
|
|
|
195
249
|
pushLog(`[updater] app not responding within 30s, skip browser open`);
|
|
196
250
|
}
|
|
197
251
|
|
|
252
|
+
function trySystemdRestart() {
|
|
253
|
+
if (process.platform === "win32" || process.platform === "darwin") return false;
|
|
254
|
+
try {
|
|
255
|
+
const { execFileSync } = require("child_process");
|
|
256
|
+
// Prefer our unit name; fall back to common aliases.
|
|
257
|
+
const units = ["zevairouter.service", "zevai.service"];
|
|
258
|
+
for (const unit of units) {
|
|
259
|
+
try {
|
|
260
|
+
execFileSync("systemctl", ["cat", unit], { stdio: "ignore", timeout: 3000 });
|
|
261
|
+
} catch {
|
|
262
|
+
continue;
|
|
263
|
+
}
|
|
264
|
+
pushLog(`[updater] restarting systemd unit ${unit}`);
|
|
265
|
+
execFileSync("systemctl", ["daemon-reload"], { stdio: "ignore", timeout: 10000 });
|
|
266
|
+
execFileSync("systemctl", ["restart", unit], { stdio: "ignore", timeout: 30000 });
|
|
267
|
+
pushLog(`[updater] systemctl restart ${unit} OK`);
|
|
268
|
+
return true;
|
|
269
|
+
}
|
|
270
|
+
} catch (e) {
|
|
271
|
+
pushLog(`[updater] systemd restart skipped: ${e.message}`);
|
|
272
|
+
}
|
|
273
|
+
return false;
|
|
274
|
+
}
|
|
275
|
+
|
|
198
276
|
function relaunchApp() {
|
|
199
277
|
if (process.env.UPDATER_RELAUNCH !== "1") return;
|
|
278
|
+
|
|
279
|
+
// VPS path: if systemd owns the service, restart that — don't spawn a second
|
|
280
|
+
// tray process that leaves the unit on the old binary forever.
|
|
281
|
+
if (trySystemdRestart()) {
|
|
282
|
+
waitForAppAndOpenBrowser();
|
|
283
|
+
return;
|
|
284
|
+
}
|
|
285
|
+
|
|
200
286
|
const cmd = process.env.UPDATER_RELAUNCH_CMD;
|
|
201
287
|
if (!cmd) return;
|
|
202
288
|
let args = [];
|
|
@@ -208,11 +294,17 @@ function relaunchApp() {
|
|
|
208
294
|
stdio: "ignore",
|
|
209
295
|
windowsHide: true,
|
|
210
296
|
shell: isWin,
|
|
211
|
-
env: {
|
|
297
|
+
env: {
|
|
298
|
+
...process.env,
|
|
299
|
+
UPDATER_RELAUNCH: "",
|
|
300
|
+
UPDATER_RELAUNCH_CMD: "",
|
|
301
|
+
UPDATER_RELAUNCH_ARGS: "",
|
|
302
|
+
// Prevent cli.js from flipping headless server restarts into tray mode.
|
|
303
|
+
ZEVAI_SERVER_MODE: args.includes("--tray") ? "" : "1",
|
|
304
|
+
},
|
|
212
305
|
});
|
|
213
306
|
child.unref();
|
|
214
307
|
pushLog(`[updater] relaunched: ${cmd} ${args.join(" ")} (pid=${child.pid})`);
|
|
215
|
-
// Wait for new app to come up, then auto-open browser so user sees the result
|
|
216
308
|
waitForAppAndOpenBrowser();
|
|
217
309
|
} catch (e) {
|
|
218
310
|
pushLog(`[updater] relaunch failed: ${e.message}`);
|