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.
Files changed (314) hide show
  1. package/CHANGELOG.md +5 -0
  2. package/cli/app/.next-cli-build/BUILD_ID +1 -1
  3. package/cli/app/.next-cli-build/app-path-routes-manifest.json +11 -11
  4. package/cli/app/.next-cli-build/build-manifest.json +2 -2
  5. package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/automation/page_client-reference-manifest.js +1 -1
  6. package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/basic-chat/page_client-reference-manifest.js +1 -1
  7. package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/cli-tools/[toolId]/page_client-reference-manifest.js +1 -1
  8. package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/cli-tools/page_client-reference-manifest.js +1 -1
  9. package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/combos/page_client-reference-manifest.js +1 -1
  10. package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/console-log/page_client-reference-manifest.js +1 -1
  11. package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/context/page_client-reference-manifest.js +1 -1
  12. package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/endpoint/page_client-reference-manifest.js +1 -1
  13. package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/[kind]/[id]/page_client-reference-manifest.js +1 -1
  14. package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/[kind]/page_client-reference-manifest.js +1 -1
  15. package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/combo/[id]/page_client-reference-manifest.js +1 -1
  16. package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/web/page_client-reference-manifest.js +1 -1
  17. package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/mitm/page_client-reference-manifest.js +1 -1
  18. package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/page_client-reference-manifest.js +1 -1
  19. package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/playground/page_client-reference-manifest.js +1 -1
  20. package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/profile/page_client-reference-manifest.js +1 -1
  21. package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/providers/[id]/page_client-reference-manifest.js +1 -1
  22. package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/providers/new/page_client-reference-manifest.js +1 -1
  23. package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/providers/page_client-reference-manifest.js +1 -1
  24. package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/proxy-pools/page_client-reference-manifest.js +1 -1
  25. package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/pxpipe/page_client-reference-manifest.js +1 -1
  26. package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/quota/page_client-reference-manifest.js +1 -1
  27. package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/settings/pricing/page_client-reference-manifest.js +1 -1
  28. package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/terminal/page_client-reference-manifest.js +1 -1
  29. package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/token-saver/page_client-reference-manifest.js +1 -1
  30. package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/translator/page_client-reference-manifest.js +1 -1
  31. package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/usage/page_client-reference-manifest.js +1 -1
  32. package/cli/app/.next-cli-build/server/app/_global-error/page_client-reference-manifest.js +1 -1
  33. package/cli/app/.next-cli-build/server/app/_global-error.html +1 -1
  34. package/cli/app/.next-cli-build/server/app/_global-error.rsc +1 -1
  35. package/cli/app/.next-cli-build/server/app/_global-error.segments/_full.segment.rsc +1 -1
  36. package/cli/app/.next-cli-build/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  37. package/cli/app/.next-cli-build/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  38. package/cli/app/.next-cli-build/server/app/_global-error.segments/_head.segment.rsc +1 -1
  39. package/cli/app/.next-cli-build/server/app/_global-error.segments/_index.segment.rsc +1 -1
  40. package/cli/app/.next-cli-build/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  41. package/cli/app/.next-cli-build/server/app/_not-found/page_client-reference-manifest.js +1 -1
  42. package/cli/app/.next-cli-build/server/app/_not-found.html +1 -1
  43. package/cli/app/.next-cli-build/server/app/_not-found.rsc +3 -3
  44. package/cli/app/.next-cli-build/server/app/_not-found.segments/_full.segment.rsc +3 -3
  45. package/cli/app/.next-cli-build/server/app/_not-found.segments/_head.segment.rsc +1 -1
  46. package/cli/app/.next-cli-build/server/app/_not-found.segments/_index.segment.rsc +3 -3
  47. package/cli/app/.next-cli-build/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  48. package/cli/app/.next-cli-build/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  49. package/cli/app/.next-cli-build/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  50. package/cli/app/.next-cli-build/server/app/api/models/route.js +1 -1
  51. package/cli/app/.next-cli-build/server/app/api/providers/route.js +1 -1
  52. package/cli/app/.next-cli-build/server/app/api/providers/validate/route.js +1 -1
  53. package/cli/app/.next-cli-build/server/app/api/translator/console-logs/route.js +1 -1
  54. package/cli/app/.next-cli-build/server/app/api/translator/console-logs/stream/route.js +1 -1
  55. package/cli/app/.next-cli-build/server/app/api/version/route.js +1 -1
  56. package/cli/app/.next-cli-build/server/app/api/version/shutdown/route.js +1 -1
  57. package/cli/app/.next-cli-build/server/app/api/version/update/route.js +1 -1
  58. package/cli/app/.next-cli-build/server/app/callback/page_client-reference-manifest.js +1 -1
  59. package/cli/app/.next-cli-build/server/app/callback.html +1 -1
  60. package/cli/app/.next-cli-build/server/app/callback.rsc +3 -3
  61. package/cli/app/.next-cli-build/server/app/callback.segments/_full.segment.rsc +3 -3
  62. package/cli/app/.next-cli-build/server/app/callback.segments/_head.segment.rsc +1 -1
  63. package/cli/app/.next-cli-build/server/app/callback.segments/_index.segment.rsc +3 -3
  64. package/cli/app/.next-cli-build/server/app/callback.segments/_tree.segment.rsc +1 -1
  65. package/cli/app/.next-cli-build/server/app/callback.segments/callback/__PAGE__.segment.rsc +1 -1
  66. package/cli/app/.next-cli-build/server/app/callback.segments/callback.segment.rsc +1 -1
  67. package/cli/app/.next-cli-build/server/app/dashboard/automation.html +1 -1
  68. package/cli/app/.next-cli-build/server/app/dashboard/automation.rsc +5 -5
  69. package/cli/app/.next-cli-build/server/app/dashboard/automation.segments/!KGRhc2hib2FyZCk/dashboard/automation/__PAGE__.segment.rsc +2 -2
  70. package/cli/app/.next-cli-build/server/app/dashboard/automation.segments/!KGRhc2hib2FyZCk/dashboard/automation.segment.rsc +1 -1
  71. package/cli/app/.next-cli-build/server/app/dashboard/automation.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  72. package/cli/app/.next-cli-build/server/app/dashboard/automation.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  73. package/cli/app/.next-cli-build/server/app/dashboard/automation.segments/_full.segment.rsc +5 -5
  74. package/cli/app/.next-cli-build/server/app/dashboard/automation.segments/_head.segment.rsc +1 -1
  75. package/cli/app/.next-cli-build/server/app/dashboard/automation.segments/_index.segment.rsc +3 -3
  76. package/cli/app/.next-cli-build/server/app/dashboard/automation.segments/_tree.segment.rsc +1 -1
  77. package/cli/app/.next-cli-build/server/app/dashboard/basic-chat.html +1 -1
  78. package/cli/app/.next-cli-build/server/app/dashboard/basic-chat.rsc +5 -5
  79. package/cli/app/.next-cli-build/server/app/dashboard/basic-chat.segments/!KGRhc2hib2FyZCk/dashboard/basic-chat/__PAGE__.segment.rsc +2 -2
  80. package/cli/app/.next-cli-build/server/app/dashboard/basic-chat.segments/!KGRhc2hib2FyZCk/dashboard/basic-chat.segment.rsc +1 -1
  81. package/cli/app/.next-cli-build/server/app/dashboard/basic-chat.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  82. package/cli/app/.next-cli-build/server/app/dashboard/basic-chat.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  83. package/cli/app/.next-cli-build/server/app/dashboard/basic-chat.segments/_full.segment.rsc +5 -5
  84. package/cli/app/.next-cli-build/server/app/dashboard/basic-chat.segments/_head.segment.rsc +1 -1
  85. package/cli/app/.next-cli-build/server/app/dashboard/basic-chat.segments/_index.segment.rsc +3 -3
  86. package/cli/app/.next-cli-build/server/app/dashboard/basic-chat.segments/_tree.segment.rsc +1 -1
  87. package/cli/app/.next-cli-build/server/app/dashboard/cli-tools.html +1 -1
  88. package/cli/app/.next-cli-build/server/app/dashboard/cli-tools.rsc +5 -5
  89. package/cli/app/.next-cli-build/server/app/dashboard/cli-tools.segments/!KGRhc2hib2FyZCk/dashboard/cli-tools/__PAGE__.segment.rsc +2 -2
  90. package/cli/app/.next-cli-build/server/app/dashboard/cli-tools.segments/!KGRhc2hib2FyZCk/dashboard/cli-tools.segment.rsc +1 -1
  91. package/cli/app/.next-cli-build/server/app/dashboard/cli-tools.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  92. package/cli/app/.next-cli-build/server/app/dashboard/cli-tools.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  93. package/cli/app/.next-cli-build/server/app/dashboard/cli-tools.segments/_full.segment.rsc +5 -5
  94. package/cli/app/.next-cli-build/server/app/dashboard/cli-tools.segments/_head.segment.rsc +1 -1
  95. package/cli/app/.next-cli-build/server/app/dashboard/cli-tools.segments/_index.segment.rsc +3 -3
  96. package/cli/app/.next-cli-build/server/app/dashboard/cli-tools.segments/_tree.segment.rsc +1 -1
  97. package/cli/app/.next-cli-build/server/app/dashboard/combos.html +1 -1
  98. package/cli/app/.next-cli-build/server/app/dashboard/combos.rsc +5 -5
  99. package/cli/app/.next-cli-build/server/app/dashboard/combos.segments/!KGRhc2hib2FyZCk/dashboard/combos/__PAGE__.segment.rsc +2 -2
  100. package/cli/app/.next-cli-build/server/app/dashboard/combos.segments/!KGRhc2hib2FyZCk/dashboard/combos.segment.rsc +1 -1
  101. package/cli/app/.next-cli-build/server/app/dashboard/combos.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  102. package/cli/app/.next-cli-build/server/app/dashboard/combos.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  103. package/cli/app/.next-cli-build/server/app/dashboard/combos.segments/_full.segment.rsc +5 -5
  104. package/cli/app/.next-cli-build/server/app/dashboard/combos.segments/_head.segment.rsc +1 -1
  105. package/cli/app/.next-cli-build/server/app/dashboard/combos.segments/_index.segment.rsc +3 -3
  106. package/cli/app/.next-cli-build/server/app/dashboard/combos.segments/_tree.segment.rsc +1 -1
  107. package/cli/app/.next-cli-build/server/app/dashboard/context.html +1 -1
  108. package/cli/app/.next-cli-build/server/app/dashboard/context.rsc +5 -5
  109. package/cli/app/.next-cli-build/server/app/dashboard/context.segments/!KGRhc2hib2FyZCk/dashboard/context/__PAGE__.segment.rsc +2 -2
  110. package/cli/app/.next-cli-build/server/app/dashboard/context.segments/!KGRhc2hib2FyZCk/dashboard/context.segment.rsc +1 -1
  111. package/cli/app/.next-cli-build/server/app/dashboard/context.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  112. package/cli/app/.next-cli-build/server/app/dashboard/context.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  113. package/cli/app/.next-cli-build/server/app/dashboard/context.segments/_full.segment.rsc +5 -5
  114. package/cli/app/.next-cli-build/server/app/dashboard/context.segments/_head.segment.rsc +1 -1
  115. package/cli/app/.next-cli-build/server/app/dashboard/context.segments/_index.segment.rsc +3 -3
  116. package/cli/app/.next-cli-build/server/app/dashboard/context.segments/_tree.segment.rsc +1 -1
  117. package/cli/app/.next-cli-build/server/app/dashboard/endpoint.html +1 -1
  118. package/cli/app/.next-cli-build/server/app/dashboard/endpoint.rsc +5 -5
  119. package/cli/app/.next-cli-build/server/app/dashboard/endpoint.segments/!KGRhc2hib2FyZCk/dashboard/endpoint/__PAGE__.segment.rsc +2 -2
  120. package/cli/app/.next-cli-build/server/app/dashboard/endpoint.segments/!KGRhc2hib2FyZCk/dashboard/endpoint.segment.rsc +1 -1
  121. package/cli/app/.next-cli-build/server/app/dashboard/endpoint.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  122. package/cli/app/.next-cli-build/server/app/dashboard/endpoint.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  123. package/cli/app/.next-cli-build/server/app/dashboard/endpoint.segments/_full.segment.rsc +5 -5
  124. package/cli/app/.next-cli-build/server/app/dashboard/endpoint.segments/_head.segment.rsc +1 -1
  125. package/cli/app/.next-cli-build/server/app/dashboard/endpoint.segments/_index.segment.rsc +3 -3
  126. package/cli/app/.next-cli-build/server/app/dashboard/endpoint.segments/_tree.segment.rsc +1 -1
  127. package/cli/app/.next-cli-build/server/app/dashboard/media-providers/web.html +1 -1
  128. package/cli/app/.next-cli-build/server/app/dashboard/media-providers/web.rsc +5 -5
  129. package/cli/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/!KGRhc2hib2FyZCk/dashboard/media-providers/web/__PAGE__.segment.rsc +2 -2
  130. package/cli/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/!KGRhc2hib2FyZCk/dashboard/media-providers/web.segment.rsc +1 -1
  131. package/cli/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/!KGRhc2hib2FyZCk/dashboard/media-providers.segment.rsc +1 -1
  132. package/cli/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  133. package/cli/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  134. package/cli/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/_full.segment.rsc +5 -5
  135. package/cli/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/_head.segment.rsc +1 -1
  136. package/cli/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/_index.segment.rsc +3 -3
  137. package/cli/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/_tree.segment.rsc +1 -1
  138. package/cli/app/.next-cli-build/server/app/dashboard/mitm.html +1 -1
  139. package/cli/app/.next-cli-build/server/app/dashboard/mitm.rsc +5 -5
  140. package/cli/app/.next-cli-build/server/app/dashboard/mitm.segments/!KGRhc2hib2FyZCk/dashboard/mitm/__PAGE__.segment.rsc +2 -2
  141. package/cli/app/.next-cli-build/server/app/dashboard/mitm.segments/!KGRhc2hib2FyZCk/dashboard/mitm.segment.rsc +1 -1
  142. package/cli/app/.next-cli-build/server/app/dashboard/mitm.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  143. package/cli/app/.next-cli-build/server/app/dashboard/mitm.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  144. package/cli/app/.next-cli-build/server/app/dashboard/mitm.segments/_full.segment.rsc +5 -5
  145. package/cli/app/.next-cli-build/server/app/dashboard/mitm.segments/_head.segment.rsc +1 -1
  146. package/cli/app/.next-cli-build/server/app/dashboard/mitm.segments/_index.segment.rsc +3 -3
  147. package/cli/app/.next-cli-build/server/app/dashboard/mitm.segments/_tree.segment.rsc +1 -1
  148. package/cli/app/.next-cli-build/server/app/dashboard/playground.html +1 -1
  149. package/cli/app/.next-cli-build/server/app/dashboard/playground.rsc +5 -5
  150. package/cli/app/.next-cli-build/server/app/dashboard/playground.segments/!KGRhc2hib2FyZCk/dashboard/playground/__PAGE__.segment.rsc +2 -2
  151. package/cli/app/.next-cli-build/server/app/dashboard/playground.segments/!KGRhc2hib2FyZCk/dashboard/playground.segment.rsc +1 -1
  152. package/cli/app/.next-cli-build/server/app/dashboard/playground.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  153. package/cli/app/.next-cli-build/server/app/dashboard/playground.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  154. package/cli/app/.next-cli-build/server/app/dashboard/playground.segments/_full.segment.rsc +5 -5
  155. package/cli/app/.next-cli-build/server/app/dashboard/playground.segments/_head.segment.rsc +1 -1
  156. package/cli/app/.next-cli-build/server/app/dashboard/playground.segments/_index.segment.rsc +3 -3
  157. package/cli/app/.next-cli-build/server/app/dashboard/playground.segments/_tree.segment.rsc +1 -1
  158. package/cli/app/.next-cli-build/server/app/dashboard/profile.html +1 -1
  159. package/cli/app/.next-cli-build/server/app/dashboard/profile.rsc +5 -5
  160. package/cli/app/.next-cli-build/server/app/dashboard/profile.segments/!KGRhc2hib2FyZCk/dashboard/profile/__PAGE__.segment.rsc +2 -2
  161. package/cli/app/.next-cli-build/server/app/dashboard/profile.segments/!KGRhc2hib2FyZCk/dashboard/profile.segment.rsc +1 -1
  162. package/cli/app/.next-cli-build/server/app/dashboard/profile.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  163. package/cli/app/.next-cli-build/server/app/dashboard/profile.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  164. package/cli/app/.next-cli-build/server/app/dashboard/profile.segments/_full.segment.rsc +5 -5
  165. package/cli/app/.next-cli-build/server/app/dashboard/profile.segments/_head.segment.rsc +1 -1
  166. package/cli/app/.next-cli-build/server/app/dashboard/profile.segments/_index.segment.rsc +3 -3
  167. package/cli/app/.next-cli-build/server/app/dashboard/profile.segments/_tree.segment.rsc +1 -1
  168. package/cli/app/.next-cli-build/server/app/dashboard/providers/new.html +1 -1
  169. package/cli/app/.next-cli-build/server/app/dashboard/providers/new.rsc +5 -5
  170. package/cli/app/.next-cli-build/server/app/dashboard/providers/new.segments/!KGRhc2hib2FyZCk/dashboard/providers/new/__PAGE__.segment.rsc +2 -2
  171. package/cli/app/.next-cli-build/server/app/dashboard/providers/new.segments/!KGRhc2hib2FyZCk/dashboard/providers/new.segment.rsc +1 -1
  172. package/cli/app/.next-cli-build/server/app/dashboard/providers/new.segments/!KGRhc2hib2FyZCk/dashboard/providers.segment.rsc +1 -1
  173. package/cli/app/.next-cli-build/server/app/dashboard/providers/new.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  174. package/cli/app/.next-cli-build/server/app/dashboard/providers/new.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  175. package/cli/app/.next-cli-build/server/app/dashboard/providers/new.segments/_full.segment.rsc +5 -5
  176. package/cli/app/.next-cli-build/server/app/dashboard/providers/new.segments/_head.segment.rsc +1 -1
  177. package/cli/app/.next-cli-build/server/app/dashboard/providers/new.segments/_index.segment.rsc +3 -3
  178. package/cli/app/.next-cli-build/server/app/dashboard/providers/new.segments/_tree.segment.rsc +1 -1
  179. package/cli/app/.next-cli-build/server/app/dashboard/providers.html +1 -1
  180. package/cli/app/.next-cli-build/server/app/dashboard/providers.rsc +5 -5
  181. package/cli/app/.next-cli-build/server/app/dashboard/providers.segments/!KGRhc2hib2FyZCk/dashboard/providers/__PAGE__.segment.rsc +2 -2
  182. package/cli/app/.next-cli-build/server/app/dashboard/providers.segments/!KGRhc2hib2FyZCk/dashboard/providers.segment.rsc +1 -1
  183. package/cli/app/.next-cli-build/server/app/dashboard/providers.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  184. package/cli/app/.next-cli-build/server/app/dashboard/providers.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  185. package/cli/app/.next-cli-build/server/app/dashboard/providers.segments/_full.segment.rsc +5 -5
  186. package/cli/app/.next-cli-build/server/app/dashboard/providers.segments/_head.segment.rsc +1 -1
  187. package/cli/app/.next-cli-build/server/app/dashboard/providers.segments/_index.segment.rsc +3 -3
  188. package/cli/app/.next-cli-build/server/app/dashboard/providers.segments/_tree.segment.rsc +1 -1
  189. package/cli/app/.next-cli-build/server/app/dashboard/proxy-pools.html +1 -1
  190. package/cli/app/.next-cli-build/server/app/dashboard/proxy-pools.rsc +5 -5
  191. package/cli/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/!KGRhc2hib2FyZCk/dashboard/proxy-pools/__PAGE__.segment.rsc +2 -2
  192. package/cli/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/!KGRhc2hib2FyZCk/dashboard/proxy-pools.segment.rsc +1 -1
  193. package/cli/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  194. package/cli/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  195. package/cli/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/_full.segment.rsc +5 -5
  196. package/cli/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/_head.segment.rsc +1 -1
  197. package/cli/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/_index.segment.rsc +3 -3
  198. package/cli/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/_tree.segment.rsc +1 -1
  199. package/cli/app/.next-cli-build/server/app/dashboard/pxpipe.html +1 -1
  200. package/cli/app/.next-cli-build/server/app/dashboard/pxpipe.rsc +5 -5
  201. package/cli/app/.next-cli-build/server/app/dashboard/pxpipe.segments/!KGRhc2hib2FyZCk/dashboard/pxpipe/__PAGE__.segment.rsc +2 -2
  202. package/cli/app/.next-cli-build/server/app/dashboard/pxpipe.segments/!KGRhc2hib2FyZCk/dashboard/pxpipe.segment.rsc +1 -1
  203. package/cli/app/.next-cli-build/server/app/dashboard/pxpipe.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  204. package/cli/app/.next-cli-build/server/app/dashboard/pxpipe.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  205. package/cli/app/.next-cli-build/server/app/dashboard/pxpipe.segments/_full.segment.rsc +5 -5
  206. package/cli/app/.next-cli-build/server/app/dashboard/pxpipe.segments/_head.segment.rsc +1 -1
  207. package/cli/app/.next-cli-build/server/app/dashboard/pxpipe.segments/_index.segment.rsc +3 -3
  208. package/cli/app/.next-cli-build/server/app/dashboard/pxpipe.segments/_tree.segment.rsc +1 -1
  209. package/cli/app/.next-cli-build/server/app/dashboard/quota.html +2 -2
  210. package/cli/app/.next-cli-build/server/app/dashboard/quota.rsc +6 -6
  211. package/cli/app/.next-cli-build/server/app/dashboard/quota.segments/!KGRhc2hib2FyZCk/dashboard/quota/__PAGE__.segment.rsc +3 -3
  212. package/cli/app/.next-cli-build/server/app/dashboard/quota.segments/!KGRhc2hib2FyZCk/dashboard/quota.segment.rsc +1 -1
  213. package/cli/app/.next-cli-build/server/app/dashboard/quota.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  214. package/cli/app/.next-cli-build/server/app/dashboard/quota.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  215. package/cli/app/.next-cli-build/server/app/dashboard/quota.segments/_full.segment.rsc +6 -6
  216. package/cli/app/.next-cli-build/server/app/dashboard/quota.segments/_head.segment.rsc +1 -1
  217. package/cli/app/.next-cli-build/server/app/dashboard/quota.segments/_index.segment.rsc +3 -3
  218. package/cli/app/.next-cli-build/server/app/dashboard/quota.segments/_tree.segment.rsc +1 -1
  219. package/cli/app/.next-cli-build/server/app/dashboard/settings/pricing.html +1 -1
  220. package/cli/app/.next-cli-build/server/app/dashboard/settings/pricing.rsc +4 -4
  221. package/cli/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/!KGRhc2hib2FyZCk/dashboard/settings/pricing/__PAGE__.segment.rsc +1 -1
  222. package/cli/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/!KGRhc2hib2FyZCk/dashboard/settings/pricing.segment.rsc +1 -1
  223. package/cli/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/!KGRhc2hib2FyZCk/dashboard/settings.segment.rsc +1 -1
  224. package/cli/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  225. package/cli/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  226. package/cli/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/_full.segment.rsc +4 -4
  227. package/cli/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/_head.segment.rsc +1 -1
  228. package/cli/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/_index.segment.rsc +3 -3
  229. package/cli/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/_tree.segment.rsc +1 -1
  230. package/cli/app/.next-cli-build/server/app/dashboard/token-saver.html +1 -1
  231. package/cli/app/.next-cli-build/server/app/dashboard/token-saver.rsc +5 -5
  232. package/cli/app/.next-cli-build/server/app/dashboard/token-saver.segments/!KGRhc2hib2FyZCk/dashboard/token-saver/__PAGE__.segment.rsc +2 -2
  233. package/cli/app/.next-cli-build/server/app/dashboard/token-saver.segments/!KGRhc2hib2FyZCk/dashboard/token-saver.segment.rsc +1 -1
  234. package/cli/app/.next-cli-build/server/app/dashboard/token-saver.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  235. package/cli/app/.next-cli-build/server/app/dashboard/token-saver.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  236. package/cli/app/.next-cli-build/server/app/dashboard/token-saver.segments/_full.segment.rsc +5 -5
  237. package/cli/app/.next-cli-build/server/app/dashboard/token-saver.segments/_head.segment.rsc +1 -1
  238. package/cli/app/.next-cli-build/server/app/dashboard/token-saver.segments/_index.segment.rsc +3 -3
  239. package/cli/app/.next-cli-build/server/app/dashboard/token-saver.segments/_tree.segment.rsc +1 -1
  240. package/cli/app/.next-cli-build/server/app/dashboard/translator.html +1 -1
  241. package/cli/app/.next-cli-build/server/app/dashboard/translator.rsc +5 -5
  242. package/cli/app/.next-cli-build/server/app/dashboard/translator.segments/!KGRhc2hib2FyZCk/dashboard/translator/__PAGE__.segment.rsc +2 -2
  243. package/cli/app/.next-cli-build/server/app/dashboard/translator.segments/!KGRhc2hib2FyZCk/dashboard/translator.segment.rsc +1 -1
  244. package/cli/app/.next-cli-build/server/app/dashboard/translator.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  245. package/cli/app/.next-cli-build/server/app/dashboard/translator.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  246. package/cli/app/.next-cli-build/server/app/dashboard/translator.segments/_full.segment.rsc +5 -5
  247. package/cli/app/.next-cli-build/server/app/dashboard/translator.segments/_head.segment.rsc +1 -1
  248. package/cli/app/.next-cli-build/server/app/dashboard/translator.segments/_index.segment.rsc +3 -3
  249. package/cli/app/.next-cli-build/server/app/dashboard/translator.segments/_tree.segment.rsc +1 -1
  250. package/cli/app/.next-cli-build/server/app/dashboard/usage.html +1 -1
  251. package/cli/app/.next-cli-build/server/app/dashboard/usage.rsc +5 -5
  252. package/cli/app/.next-cli-build/server/app/dashboard/usage.segments/!KGRhc2hib2FyZCk/dashboard/usage/__PAGE__.segment.rsc +2 -2
  253. package/cli/app/.next-cli-build/server/app/dashboard/usage.segments/!KGRhc2hib2FyZCk/dashboard/usage.segment.rsc +1 -1
  254. package/cli/app/.next-cli-build/server/app/dashboard/usage.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  255. package/cli/app/.next-cli-build/server/app/dashboard/usage.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  256. package/cli/app/.next-cli-build/server/app/dashboard/usage.segments/_full.segment.rsc +5 -5
  257. package/cli/app/.next-cli-build/server/app/dashboard/usage.segments/_head.segment.rsc +1 -1
  258. package/cli/app/.next-cli-build/server/app/dashboard/usage.segments/_index.segment.rsc +3 -3
  259. package/cli/app/.next-cli-build/server/app/dashboard/usage.segments/_tree.segment.rsc +1 -1
  260. package/cli/app/.next-cli-build/server/app/dashboard.html +1 -1
  261. package/cli/app/.next-cli-build/server/app/dashboard.rsc +5 -5
  262. package/cli/app/.next-cli-build/server/app/dashboard.segments/!KGRhc2hib2FyZCk/dashboard/__PAGE__.segment.rsc +2 -2
  263. package/cli/app/.next-cli-build/server/app/dashboard.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  264. package/cli/app/.next-cli-build/server/app/dashboard.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  265. package/cli/app/.next-cli-build/server/app/dashboard.segments/_full.segment.rsc +5 -5
  266. package/cli/app/.next-cli-build/server/app/dashboard.segments/_head.segment.rsc +1 -1
  267. package/cli/app/.next-cli-build/server/app/dashboard.segments/_index.segment.rsc +3 -3
  268. package/cli/app/.next-cli-build/server/app/dashboard.segments/_tree.segment.rsc +1 -1
  269. package/cli/app/.next-cli-build/server/app/index.html +1 -1
  270. package/cli/app/.next-cli-build/server/app/index.rsc +3 -3
  271. package/cli/app/.next-cli-build/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  272. package/cli/app/.next-cli-build/server/app/index.segments/_full.segment.rsc +3 -3
  273. package/cli/app/.next-cli-build/server/app/index.segments/_head.segment.rsc +1 -1
  274. package/cli/app/.next-cli-build/server/app/index.segments/_index.segment.rsc +3 -3
  275. package/cli/app/.next-cli-build/server/app/index.segments/_tree.segment.rsc +1 -1
  276. package/cli/app/.next-cli-build/server/app/landing/page_client-reference-manifest.js +1 -1
  277. package/cli/app/.next-cli-build/server/app/landing.html +1 -1
  278. package/cli/app/.next-cli-build/server/app/landing.rsc +4 -4
  279. package/cli/app/.next-cli-build/server/app/landing.segments/_full.segment.rsc +4 -4
  280. package/cli/app/.next-cli-build/server/app/landing.segments/_head.segment.rsc +1 -1
  281. package/cli/app/.next-cli-build/server/app/landing.segments/_index.segment.rsc +3 -3
  282. package/cli/app/.next-cli-build/server/app/landing.segments/_tree.segment.rsc +1 -1
  283. package/cli/app/.next-cli-build/server/app/landing.segments/landing/__PAGE__.segment.rsc +2 -2
  284. package/cli/app/.next-cli-build/server/app/landing.segments/landing.segment.rsc +1 -1
  285. package/cli/app/.next-cli-build/server/app/login/page_client-reference-manifest.js +1 -1
  286. package/cli/app/.next-cli-build/server/app/login.html +1 -1
  287. package/cli/app/.next-cli-build/server/app/login.rsc +4 -4
  288. package/cli/app/.next-cli-build/server/app/login.segments/_full.segment.rsc +4 -4
  289. package/cli/app/.next-cli-build/server/app/login.segments/_head.segment.rsc +1 -1
  290. package/cli/app/.next-cli-build/server/app/login.segments/_index.segment.rsc +3 -3
  291. package/cli/app/.next-cli-build/server/app/login.segments/_tree.segment.rsc +1 -1
  292. package/cli/app/.next-cli-build/server/app/login.segments/login/__PAGE__.segment.rsc +2 -2
  293. package/cli/app/.next-cli-build/server/app/login.segments/login.segment.rsc +1 -1
  294. package/cli/app/.next-cli-build/server/app/page_client-reference-manifest.js +1 -1
  295. package/cli/app/.next-cli-build/server/app-paths-manifest.json +11 -11
  296. package/cli/app/.next-cli-build/server/chunks/3155.js +1 -1
  297. package/cli/app/.next-cli-build/server/chunks/4746.js +1 -1
  298. package/cli/app/.next-cli-build/server/chunks/5307.js +1 -1
  299. package/cli/app/.next-cli-build/server/chunks/8306.js +1 -1
  300. package/cli/app/.next-cli-build/server/chunks/9621.js +1 -1
  301. package/cli/app/.next-cli-build/server/middleware-build-manifest.js +1 -1
  302. package/cli/app/.next-cli-build/server/pages/404.html +1 -1
  303. package/cli/app/.next-cli-build/server/pages/500.html +1 -1
  304. package/cli/app/.next-cli-build/static/chunks/{620-c15094ea3b9eda2c.js → 620-2db5cff0e3ebc21f.js} +1 -1
  305. package/cli/app/CHANGELOG.md +5 -0
  306. package/cli/app/package.json +1 -1
  307. package/cli/app/src/lib/updater/updater.js +19 -4
  308. package/cli/cli.js +305 -78
  309. package/cli/package.json +1 -1
  310. package/cli/src/cli/routerProcessLifecycle.js +685 -0
  311. package/cli/src/cli/tray/autostart.js +43 -35
  312. package/package.json +1 -1
  313. /package/cli/app/.next-cli-build/static/{nTTf6L7b6eAK9eItpJOcH → 9Vz4OT0qlhev-svz548oQ}/_buildManifest.js +0 -0
  314. /package/cli/app/.next-cli-build/static/{nTTf6L7b6eAK9eItpJOcH → 9Vz4OT0qlhev-svz548oQ}/_ssgManifest.js +0 -0
@@ -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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zevairouter",
3
- "version": "1.0.173",
3
+ "version": "1.0.174",
4
4
  "description": "Self-hosted AI router: many providers, one OpenAI-compatible /v1 endpoint and dashboard",
5
5
  "bin": {
6
6
  "zevai": "cli/cli.js"
@@ -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 { spawn(cmd, { shell: true, detached: true, stdio: "ignore" }).unref(); } catch { /* ignore */ }
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
- if (isPortOccupied(updatePort) && !isZevaiVersionInfo(getLiveVersionInfo(updatePort, 4, updateHost))) {
316
- throw new Error(`Port ${updatePort} is owned by an unverified service; refusing to terminate it.`);
317
- }
318
- if (pm2App) {
319
- execFileSync("pm2", ["stop", String(pm2App.id)], { stdio: "inherit", timeout: 30000 });
320
- } else {
321
- stopOwnedRouterParent(updateRuntime, updatePort);
322
- }
323
- freePortHard(updatePort, updateHost);
324
- if (isPortOccupied(updatePort)) {
325
- throw new Error(`ZevaiRouter on port ${updatePort} did not stop cleanly.`);
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
- if (isPortOccupied(updatePort) && !isZevaiVersionInfo(getLiveVersionInfo(updatePort, 4, updateHost))) {
510
- throw new Error(`Port ${updatePort} is owned by an unverified service; launchd was not changed.`);
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
- if (isPortOccupied(directPort) && !isZevaiVersionInfo(getLiveVersionInfo(directPort, 4, updateHost))) {
603
- rollbackInstall(`Port ${directPort} is owned by an unverified service`);
604
- throw new Error(`Port ${directPort} is owned by an unverified service; it was not terminated`);
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
- // Kill a listener only after its version endpoint proves it is ZevaiRouter.
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
- killVerifiedRouterOnPort(port, checkHost);
997
+ freePortHard(port, checkHost);
959
998
  setTimeout(() => resolve(), 500);
960
999
  } catch (err) {
961
- resolve();
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 output = execSync(`lsof -nP -tiTCP:${numericPort} -sTCP:LISTEN`, {
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
- for (const pid of pids) {
1343
+ if (pids.length !== 1) return false;
1344
+ let linuxStartToken = null;
1345
+ if (process.platform === "linux") {
1301
1346
  try {
1302
- if (process.platform === "win32") {
1303
- execSync(`taskkill /F /T /PID ${pid} 2>nul`, {
1304
- stdio: "ignore",
1305
- shell: true,
1306
- windowsHide: true,
1307
- timeout: 5000,
1308
- });
1309
- } else {
1310
- try { process.kill(pid, "SIGTERM"); } catch {}
1311
- if (!waitForExit(pid, 2000)) {
1312
- try { process.kill(pid, "SIGKILL"); } catch {}
1313
- }
1314
- }
1315
- } catch {}
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 verified ZevaiRouter listener without touching unrelated services. */
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 occupied = isPortOccupied(port);
1440
- const live = occupied ? getLiveVersionInfo(port, 4, host) : null;
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
- console.error(`Port :${port} is already in use by an unverified process.`);
1443
- console.error("ZevaiRouter will not terminate unrelated services. Free the port or choose --port <port>.");
1444
- process.exitCode = 1;
1445
- return;
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 && !underSystemd && healthy && !stale) {
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
- const child = spawn(RUNTIME, [`--max-old-space-size=${maxOldSpace}`, serverPath], {
1551
- cwd: standaloneDir,
1552
- stdio: showLog ? "inherit" : ["ignore", "ignore", "pipe"],
1553
- detached: true,
1554
- windowsHide: true,
1555
- env: {
1556
- ...buildEnvWithRuntime(process.env),
1557
- PORT: port.toString(),
1558
- HOSTNAME: host
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
- if (!showLog && child.stderr) {
1562
- child.stderr.on("data", (data) => {
1563
- const lines = data.toString().split("\n").filter(Boolean);
1564
- crashLog.push(...lines);
1565
- if (crashLog.length > CRASH_LOG_LINES) crashLog = crashLog.slice(-CRASH_LOG_LINES);
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: process.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: { ...process.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 ---");
package/cli/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zevairouter-cli",
3
- "version": "1.0.173",
3
+ "version": "1.0.174",
4
4
  "private": true,
5
5
  "description": "ZevaiRouter CLI - Start and manage ZevaiRouter server",
6
6
  "bin": {