axonrouter 2.0.2 → 2.0.4

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 (420) hide show
  1. package/.next/standalone/.next/BUILD_ID +1 -1
  2. package/.next/standalone/.next/build-manifest.json +3 -3
  3. package/.next/standalone/.next/prerender-manifest.json +3 -3
  4. package/.next/standalone/.next/server/app/(dashboard)/dashboard/analytics/page.js.nft.json +1 -1
  5. package/.next/standalone/.next/server/app/(dashboard)/dashboard/analytics/page_client-reference-manifest.js +1 -1
  6. package/.next/standalone/.next/server/app/(dashboard)/dashboard/basic-chat/page.js.nft.json +1 -1
  7. package/.next/standalone/.next/server/app/(dashboard)/dashboard/basic-chat/page_client-reference-manifest.js +1 -1
  8. package/.next/standalone/.next/server/app/(dashboard)/dashboard/caveman/page.js.nft.json +1 -1
  9. package/.next/standalone/.next/server/app/(dashboard)/dashboard/caveman/page_client-reference-manifest.js +1 -1
  10. package/.next/standalone/.next/server/app/(dashboard)/dashboard/cli-tools/page.js.nft.json +1 -1
  11. package/.next/standalone/.next/server/app/(dashboard)/dashboard/cli-tools/page_client-reference-manifest.js +1 -1
  12. package/.next/standalone/.next/server/app/(dashboard)/dashboard/combos/page.js.nft.json +1 -1
  13. package/.next/standalone/.next/server/app/(dashboard)/dashboard/combos/page_client-reference-manifest.js +1 -1
  14. package/.next/standalone/.next/server/app/(dashboard)/dashboard/console-log/page.js.nft.json +1 -1
  15. package/.next/standalone/.next/server/app/(dashboard)/dashboard/console-log/page_client-reference-manifest.js +1 -1
  16. package/.next/standalone/.next/server/app/(dashboard)/dashboard/endpoint/page.js.nft.json +1 -1
  17. package/.next/standalone/.next/server/app/(dashboard)/dashboard/endpoint/page_client-reference-manifest.js +1 -1
  18. package/.next/standalone/.next/server/app/(dashboard)/dashboard/intelligence/page.js.nft.json +1 -1
  19. package/.next/standalone/.next/server/app/(dashboard)/dashboard/intelligence/page_client-reference-manifest.js +1 -1
  20. package/.next/standalone/.next/server/app/(dashboard)/dashboard/mcp/page.js.nft.json +1 -1
  21. package/.next/standalone/.next/server/app/(dashboard)/dashboard/mcp/page_client-reference-manifest.js +1 -1
  22. package/.next/standalone/.next/server/app/(dashboard)/dashboard/media-providers/[kind]/[id]/page.js.nft.json +1 -1
  23. package/.next/standalone/.next/server/app/(dashboard)/dashboard/media-providers/[kind]/[id]/page_client-reference-manifest.js +1 -1
  24. package/.next/standalone/.next/server/app/(dashboard)/dashboard/media-providers/[kind]/page.js.nft.json +1 -1
  25. package/.next/standalone/.next/server/app/(dashboard)/dashboard/media-providers/[kind]/page_client-reference-manifest.js +1 -1
  26. package/.next/standalone/.next/server/app/(dashboard)/dashboard/media-providers/page.js.nft.json +1 -1
  27. package/.next/standalone/.next/server/app/(dashboard)/dashboard/media-providers/page_client-reference-manifest.js +1 -1
  28. package/.next/standalone/.next/server/app/(dashboard)/dashboard/mitm/page.js.nft.json +1 -1
  29. package/.next/standalone/.next/server/app/(dashboard)/dashboard/mitm/page_client-reference-manifest.js +1 -1
  30. package/.next/standalone/.next/server/app/(dashboard)/dashboard/morph/page.js.nft.json +1 -1
  31. package/.next/standalone/.next/server/app/(dashboard)/dashboard/morph/page_client-reference-manifest.js +1 -1
  32. package/.next/standalone/.next/server/app/(dashboard)/dashboard/opencode/page.js.nft.json +1 -1
  33. package/.next/standalone/.next/server/app/(dashboard)/dashboard/opencode/page_client-reference-manifest.js +1 -1
  34. package/.next/standalone/.next/server/app/(dashboard)/dashboard/page.js.nft.json +1 -1
  35. package/.next/standalone/.next/server/app/(dashboard)/dashboard/page_client-reference-manifest.js +1 -1
  36. package/.next/standalone/.next/server/app/(dashboard)/dashboard/profile/page.js.nft.json +1 -1
  37. package/.next/standalone/.next/server/app/(dashboard)/dashboard/profile/page_client-reference-manifest.js +1 -1
  38. package/.next/standalone/.next/server/app/(dashboard)/dashboard/providers/[id]/page.js.nft.json +1 -1
  39. package/.next/standalone/.next/server/app/(dashboard)/dashboard/providers/[id]/page_client-reference-manifest.js +1 -1
  40. package/.next/standalone/.next/server/app/(dashboard)/dashboard/providers/new/page.js.nft.json +1 -1
  41. package/.next/standalone/.next/server/app/(dashboard)/dashboard/providers/new/page_client-reference-manifest.js +1 -1
  42. package/.next/standalone/.next/server/app/(dashboard)/dashboard/providers/page.js.nft.json +1 -1
  43. package/.next/standalone/.next/server/app/(dashboard)/dashboard/providers/page_client-reference-manifest.js +1 -1
  44. package/.next/standalone/.next/server/app/(dashboard)/dashboard/proxy-pools/page.js.nft.json +1 -1
  45. package/.next/standalone/.next/server/app/(dashboard)/dashboard/proxy-pools/page_client-reference-manifest.js +1 -1
  46. package/.next/standalone/.next/server/app/(dashboard)/dashboard/quota/page.js.nft.json +1 -1
  47. package/.next/standalone/.next/server/app/(dashboard)/dashboard/quota/page_client-reference-manifest.js +1 -1
  48. package/.next/standalone/.next/server/app/(dashboard)/dashboard/settings/page.js.nft.json +1 -1
  49. package/.next/standalone/.next/server/app/(dashboard)/dashboard/settings/page_client-reference-manifest.js +1 -1
  50. package/.next/standalone/.next/server/app/(dashboard)/dashboard/settings/pricing/page.js.nft.json +1 -1
  51. package/.next/standalone/.next/server/app/(dashboard)/dashboard/settings/pricing/page_client-reference-manifest.js +1 -1
  52. package/.next/standalone/.next/server/app/(dashboard)/dashboard/skills/page.js.nft.json +1 -1
  53. package/.next/standalone/.next/server/app/(dashboard)/dashboard/skills/page_client-reference-manifest.js +1 -1
  54. package/.next/standalone/.next/server/app/(dashboard)/dashboard/translator/page.js.nft.json +1 -1
  55. package/.next/standalone/.next/server/app/(dashboard)/dashboard/translator/page_client-reference-manifest.js +1 -1
  56. package/.next/standalone/.next/server/app/(dashboard)/dashboard/usage/page.js.nft.json +1 -1
  57. package/.next/standalone/.next/server/app/(dashboard)/dashboard/usage/page_client-reference-manifest.js +1 -1
  58. package/.next/standalone/.next/server/app/_global-error.html +1 -1
  59. package/.next/standalone/.next/server/app/_global-error.rsc +1 -1
  60. package/.next/standalone/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  61. package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  62. package/.next/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  63. package/.next/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  64. package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  65. package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  66. package/.next/standalone/.next/server/app/_not-found.html +1 -1
  67. package/.next/standalone/.next/server/app/_not-found.rsc +2 -2
  68. package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +2 -2
  69. package/.next/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  70. package/.next/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +2 -2
  71. package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  72. package/.next/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  73. package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  74. package/.next/standalone/.next/server/app/api/cli-tools/cowork-settings/route.js.nft.json +1 -1
  75. package/.next/standalone/.next/server/app/callback/page.js.nft.json +1 -1
  76. package/.next/standalone/.next/server/app/callback/page_client-reference-manifest.js +1 -1
  77. package/.next/standalone/.next/server/app/callback.html +1 -1
  78. package/.next/standalone/.next/server/app/callback.rsc +3 -3
  79. package/.next/standalone/.next/server/app/callback.segments/_full.segment.rsc +3 -3
  80. package/.next/standalone/.next/server/app/callback.segments/_head.segment.rsc +1 -1
  81. package/.next/standalone/.next/server/app/callback.segments/_index.segment.rsc +2 -2
  82. package/.next/standalone/.next/server/app/callback.segments/_tree.segment.rsc +2 -2
  83. package/.next/standalone/.next/server/app/callback.segments/callback/__PAGE__.segment.rsc +2 -2
  84. package/.next/standalone/.next/server/app/callback.segments/callback.segment.rsc +1 -1
  85. package/.next/standalone/.next/server/app/dashboard/analytics.html +2 -2
  86. package/.next/standalone/.next/server/app/dashboard/analytics.rsc +6 -6
  87. package/.next/standalone/.next/server/app/dashboard/analytics.segments/!KGRhc2hib2FyZCk/dashboard/analytics/__PAGE__.segment.rsc +2 -2
  88. package/.next/standalone/.next/server/app/dashboard/analytics.segments/!KGRhc2hib2FyZCk/dashboard/analytics.segment.rsc +1 -1
  89. package/.next/standalone/.next/server/app/dashboard/analytics.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  90. package/.next/standalone/.next/server/app/dashboard/analytics.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  91. package/.next/standalone/.next/server/app/dashboard/analytics.segments/_full.segment.rsc +6 -6
  92. package/.next/standalone/.next/server/app/dashboard/analytics.segments/_head.segment.rsc +1 -1
  93. package/.next/standalone/.next/server/app/dashboard/analytics.segments/_index.segment.rsc +3 -3
  94. package/.next/standalone/.next/server/app/dashboard/analytics.segments/_tree.segment.rsc +2 -2
  95. package/.next/standalone/.next/server/app/dashboard/basic-chat.html +2 -2
  96. package/.next/standalone/.next/server/app/dashboard/basic-chat.rsc +6 -6
  97. package/.next/standalone/.next/server/app/dashboard/basic-chat.segments/!KGRhc2hib2FyZCk/dashboard/basic-chat/__PAGE__.segment.rsc +2 -2
  98. package/.next/standalone/.next/server/app/dashboard/basic-chat.segments/!KGRhc2hib2FyZCk/dashboard/basic-chat.segment.rsc +1 -1
  99. package/.next/standalone/.next/server/app/dashboard/basic-chat.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  100. package/.next/standalone/.next/server/app/dashboard/basic-chat.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  101. package/.next/standalone/.next/server/app/dashboard/basic-chat.segments/_full.segment.rsc +6 -6
  102. package/.next/standalone/.next/server/app/dashboard/basic-chat.segments/_head.segment.rsc +1 -1
  103. package/.next/standalone/.next/server/app/dashboard/basic-chat.segments/_index.segment.rsc +3 -3
  104. package/.next/standalone/.next/server/app/dashboard/basic-chat.segments/_tree.segment.rsc +2 -2
  105. package/.next/standalone/.next/server/app/dashboard/caveman.html +2 -2
  106. package/.next/standalone/.next/server/app/dashboard/caveman.rsc +6 -6
  107. package/.next/standalone/.next/server/app/dashboard/caveman.segments/!KGRhc2hib2FyZCk/dashboard/caveman/__PAGE__.segment.rsc +2 -2
  108. package/.next/standalone/.next/server/app/dashboard/caveman.segments/!KGRhc2hib2FyZCk/dashboard/caveman.segment.rsc +1 -1
  109. package/.next/standalone/.next/server/app/dashboard/caveman.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  110. package/.next/standalone/.next/server/app/dashboard/caveman.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  111. package/.next/standalone/.next/server/app/dashboard/caveman.segments/_full.segment.rsc +6 -6
  112. package/.next/standalone/.next/server/app/dashboard/caveman.segments/_head.segment.rsc +1 -1
  113. package/.next/standalone/.next/server/app/dashboard/caveman.segments/_index.segment.rsc +3 -3
  114. package/.next/standalone/.next/server/app/dashboard/caveman.segments/_tree.segment.rsc +2 -2
  115. package/.next/standalone/.next/server/app/dashboard/cli-tools.html +2 -2
  116. package/.next/standalone/.next/server/app/dashboard/cli-tools.rsc +7 -7
  117. package/.next/standalone/.next/server/app/dashboard/cli-tools.segments/!KGRhc2hib2FyZCk/dashboard/cli-tools/__PAGE__.segment.rsc +2 -2
  118. package/.next/standalone/.next/server/app/dashboard/cli-tools.segments/!KGRhc2hib2FyZCk/dashboard/cli-tools.segment.rsc +1 -1
  119. package/.next/standalone/.next/server/app/dashboard/cli-tools.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  120. package/.next/standalone/.next/server/app/dashboard/cli-tools.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  121. package/.next/standalone/.next/server/app/dashboard/cli-tools.segments/_full.segment.rsc +7 -7
  122. package/.next/standalone/.next/server/app/dashboard/cli-tools.segments/_head.segment.rsc +1 -1
  123. package/.next/standalone/.next/server/app/dashboard/cli-tools.segments/_index.segment.rsc +3 -3
  124. package/.next/standalone/.next/server/app/dashboard/cli-tools.segments/_tree.segment.rsc +2 -2
  125. package/.next/standalone/.next/server/app/dashboard/combos.html +2 -2
  126. package/.next/standalone/.next/server/app/dashboard/combos.rsc +6 -6
  127. package/.next/standalone/.next/server/app/dashboard/combos.segments/!KGRhc2hib2FyZCk/dashboard/combos/__PAGE__.segment.rsc +2 -2
  128. package/.next/standalone/.next/server/app/dashboard/combos.segments/!KGRhc2hib2FyZCk/dashboard/combos.segment.rsc +1 -1
  129. package/.next/standalone/.next/server/app/dashboard/combos.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  130. package/.next/standalone/.next/server/app/dashboard/combos.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  131. package/.next/standalone/.next/server/app/dashboard/combos.segments/_full.segment.rsc +6 -6
  132. package/.next/standalone/.next/server/app/dashboard/combos.segments/_head.segment.rsc +1 -1
  133. package/.next/standalone/.next/server/app/dashboard/combos.segments/_index.segment.rsc +3 -3
  134. package/.next/standalone/.next/server/app/dashboard/combos.segments/_tree.segment.rsc +2 -2
  135. package/.next/standalone/.next/server/app/dashboard/endpoint.html +1 -1
  136. package/.next/standalone/.next/server/app/dashboard/endpoint.rsc +7 -7
  137. package/.next/standalone/.next/server/app/dashboard/endpoint.segments/!KGRhc2hib2FyZCk/dashboard/endpoint/__PAGE__.segment.rsc +2 -2
  138. package/.next/standalone/.next/server/app/dashboard/endpoint.segments/!KGRhc2hib2FyZCk/dashboard/endpoint.segment.rsc +1 -1
  139. package/.next/standalone/.next/server/app/dashboard/endpoint.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  140. package/.next/standalone/.next/server/app/dashboard/endpoint.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  141. package/.next/standalone/.next/server/app/dashboard/endpoint.segments/_full.segment.rsc +7 -7
  142. package/.next/standalone/.next/server/app/dashboard/endpoint.segments/_head.segment.rsc +1 -1
  143. package/.next/standalone/.next/server/app/dashboard/endpoint.segments/_index.segment.rsc +3 -3
  144. package/.next/standalone/.next/server/app/dashboard/endpoint.segments/_tree.segment.rsc +2 -2
  145. package/.next/standalone/.next/server/app/dashboard/intelligence.html +1 -1
  146. package/.next/standalone/.next/server/app/dashboard/intelligence.rsc +5 -5
  147. package/.next/standalone/.next/server/app/dashboard/intelligence.segments/!KGRhc2hib2FyZCk/dashboard/intelligence/__PAGE__.segment.rsc +1 -1
  148. package/.next/standalone/.next/server/app/dashboard/intelligence.segments/!KGRhc2hib2FyZCk/dashboard/intelligence.segment.rsc +1 -1
  149. package/.next/standalone/.next/server/app/dashboard/intelligence.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  150. package/.next/standalone/.next/server/app/dashboard/intelligence.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  151. package/.next/standalone/.next/server/app/dashboard/intelligence.segments/_full.segment.rsc +5 -5
  152. package/.next/standalone/.next/server/app/dashboard/intelligence.segments/_head.segment.rsc +1 -1
  153. package/.next/standalone/.next/server/app/dashboard/intelligence.segments/_index.segment.rsc +3 -3
  154. package/.next/standalone/.next/server/app/dashboard/intelligence.segments/_tree.segment.rsc +2 -2
  155. package/.next/standalone/.next/server/app/dashboard/mcp.html +2 -2
  156. package/.next/standalone/.next/server/app/dashboard/mcp.rsc +6 -6
  157. package/.next/standalone/.next/server/app/dashboard/mcp.segments/!KGRhc2hib2FyZCk/dashboard/mcp/__PAGE__.segment.rsc +2 -2
  158. package/.next/standalone/.next/server/app/dashboard/mcp.segments/!KGRhc2hib2FyZCk/dashboard/mcp.segment.rsc +1 -1
  159. package/.next/standalone/.next/server/app/dashboard/mcp.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  160. package/.next/standalone/.next/server/app/dashboard/mcp.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  161. package/.next/standalone/.next/server/app/dashboard/mcp.segments/_full.segment.rsc +6 -6
  162. package/.next/standalone/.next/server/app/dashboard/mcp.segments/_head.segment.rsc +1 -1
  163. package/.next/standalone/.next/server/app/dashboard/mcp.segments/_index.segment.rsc +3 -3
  164. package/.next/standalone/.next/server/app/dashboard/mcp.segments/_tree.segment.rsc +2 -2
  165. package/.next/standalone/.next/server/app/dashboard/media-providers.html +2 -2
  166. package/.next/standalone/.next/server/app/dashboard/media-providers.rsc +6 -6
  167. package/.next/standalone/.next/server/app/dashboard/media-providers.segments/!KGRhc2hib2FyZCk/dashboard/media-providers/__PAGE__.segment.rsc +2 -2
  168. package/.next/standalone/.next/server/app/dashboard/media-providers.segments/!KGRhc2hib2FyZCk/dashboard/media-providers.segment.rsc +1 -1
  169. package/.next/standalone/.next/server/app/dashboard/media-providers.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  170. package/.next/standalone/.next/server/app/dashboard/media-providers.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  171. package/.next/standalone/.next/server/app/dashboard/media-providers.segments/_full.segment.rsc +6 -6
  172. package/.next/standalone/.next/server/app/dashboard/media-providers.segments/_head.segment.rsc +1 -1
  173. package/.next/standalone/.next/server/app/dashboard/media-providers.segments/_index.segment.rsc +3 -3
  174. package/.next/standalone/.next/server/app/dashboard/media-providers.segments/_tree.segment.rsc +2 -2
  175. package/.next/standalone/.next/server/app/dashboard/mitm.html +2 -2
  176. package/.next/standalone/.next/server/app/dashboard/mitm.rsc +6 -6
  177. package/.next/standalone/.next/server/app/dashboard/mitm.segments/!KGRhc2hib2FyZCk/dashboard/mitm/__PAGE__.segment.rsc +2 -2
  178. package/.next/standalone/.next/server/app/dashboard/mitm.segments/!KGRhc2hib2FyZCk/dashboard/mitm.segment.rsc +1 -1
  179. package/.next/standalone/.next/server/app/dashboard/mitm.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  180. package/.next/standalone/.next/server/app/dashboard/mitm.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  181. package/.next/standalone/.next/server/app/dashboard/mitm.segments/_full.segment.rsc +6 -6
  182. package/.next/standalone/.next/server/app/dashboard/mitm.segments/_head.segment.rsc +1 -1
  183. package/.next/standalone/.next/server/app/dashboard/mitm.segments/_index.segment.rsc +3 -3
  184. package/.next/standalone/.next/server/app/dashboard/mitm.segments/_tree.segment.rsc +2 -2
  185. package/.next/standalone/.next/server/app/dashboard/morph.html +1 -1
  186. package/.next/standalone/.next/server/app/dashboard/morph.rsc +6 -6
  187. package/.next/standalone/.next/server/app/dashboard/morph.segments/!KGRhc2hib2FyZCk/dashboard/morph/__PAGE__.segment.rsc +2 -2
  188. package/.next/standalone/.next/server/app/dashboard/morph.segments/!KGRhc2hib2FyZCk/dashboard/morph.segment.rsc +1 -1
  189. package/.next/standalone/.next/server/app/dashboard/morph.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  190. package/.next/standalone/.next/server/app/dashboard/morph.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  191. package/.next/standalone/.next/server/app/dashboard/morph.segments/_full.segment.rsc +6 -6
  192. package/.next/standalone/.next/server/app/dashboard/morph.segments/_head.segment.rsc +1 -1
  193. package/.next/standalone/.next/server/app/dashboard/morph.segments/_index.segment.rsc +3 -3
  194. package/.next/standalone/.next/server/app/dashboard/morph.segments/_tree.segment.rsc +2 -2
  195. package/.next/standalone/.next/server/app/dashboard/opencode.html +1 -1
  196. package/.next/standalone/.next/server/app/dashboard/opencode.rsc +6 -6
  197. package/.next/standalone/.next/server/app/dashboard/opencode.segments/!KGRhc2hib2FyZCk/dashboard/opencode/__PAGE__.segment.rsc +2 -2
  198. package/.next/standalone/.next/server/app/dashboard/opencode.segments/!KGRhc2hib2FyZCk/dashboard/opencode.segment.rsc +1 -1
  199. package/.next/standalone/.next/server/app/dashboard/opencode.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  200. package/.next/standalone/.next/server/app/dashboard/opencode.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  201. package/.next/standalone/.next/server/app/dashboard/opencode.segments/_full.segment.rsc +6 -6
  202. package/.next/standalone/.next/server/app/dashboard/opencode.segments/_head.segment.rsc +1 -1
  203. package/.next/standalone/.next/server/app/dashboard/opencode.segments/_index.segment.rsc +3 -3
  204. package/.next/standalone/.next/server/app/dashboard/opencode.segments/_tree.segment.rsc +2 -2
  205. package/.next/standalone/.next/server/app/dashboard/profile.html +1 -1
  206. package/.next/standalone/.next/server/app/dashboard/profile.rsc +6 -6
  207. package/.next/standalone/.next/server/app/dashboard/profile.segments/!KGRhc2hib2FyZCk/dashboard/profile/__PAGE__.segment.rsc +2 -2
  208. package/.next/standalone/.next/server/app/dashboard/profile.segments/!KGRhc2hib2FyZCk/dashboard/profile.segment.rsc +1 -1
  209. package/.next/standalone/.next/server/app/dashboard/profile.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  210. package/.next/standalone/.next/server/app/dashboard/profile.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  211. package/.next/standalone/.next/server/app/dashboard/profile.segments/_full.segment.rsc +6 -6
  212. package/.next/standalone/.next/server/app/dashboard/profile.segments/_head.segment.rsc +1 -1
  213. package/.next/standalone/.next/server/app/dashboard/profile.segments/_index.segment.rsc +3 -3
  214. package/.next/standalone/.next/server/app/dashboard/profile.segments/_tree.segment.rsc +2 -2
  215. package/.next/standalone/.next/server/app/dashboard/providers/new.html +2 -2
  216. package/.next/standalone/.next/server/app/dashboard/providers/new.rsc +6 -6
  217. package/.next/standalone/.next/server/app/dashboard/providers/new.segments/!KGRhc2hib2FyZCk/dashboard/providers/new/__PAGE__.segment.rsc +2 -2
  218. package/.next/standalone/.next/server/app/dashboard/providers/new.segments/!KGRhc2hib2FyZCk/dashboard/providers/new.segment.rsc +1 -1
  219. package/.next/standalone/.next/server/app/dashboard/providers/new.segments/!KGRhc2hib2FyZCk/dashboard/providers.segment.rsc +1 -1
  220. package/.next/standalone/.next/server/app/dashboard/providers/new.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  221. package/.next/standalone/.next/server/app/dashboard/providers/new.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  222. package/.next/standalone/.next/server/app/dashboard/providers/new.segments/_full.segment.rsc +6 -6
  223. package/.next/standalone/.next/server/app/dashboard/providers/new.segments/_head.segment.rsc +1 -1
  224. package/.next/standalone/.next/server/app/dashboard/providers/new.segments/_index.segment.rsc +3 -3
  225. package/.next/standalone/.next/server/app/dashboard/providers/new.segments/_tree.segment.rsc +2 -2
  226. package/.next/standalone/.next/server/app/dashboard/providers.html +2 -2
  227. package/.next/standalone/.next/server/app/dashboard/providers.rsc +6 -6
  228. package/.next/standalone/.next/server/app/dashboard/providers.segments/!KGRhc2hib2FyZCk/dashboard/providers/__PAGE__.segment.rsc +2 -2
  229. package/.next/standalone/.next/server/app/dashboard/providers.segments/!KGRhc2hib2FyZCk/dashboard/providers.segment.rsc +1 -1
  230. package/.next/standalone/.next/server/app/dashboard/providers.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  231. package/.next/standalone/.next/server/app/dashboard/providers.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  232. package/.next/standalone/.next/server/app/dashboard/providers.segments/_full.segment.rsc +6 -6
  233. package/.next/standalone/.next/server/app/dashboard/providers.segments/_head.segment.rsc +1 -1
  234. package/.next/standalone/.next/server/app/dashboard/providers.segments/_index.segment.rsc +3 -3
  235. package/.next/standalone/.next/server/app/dashboard/providers.segments/_tree.segment.rsc +2 -2
  236. package/.next/standalone/.next/server/app/dashboard/proxy-pools.html +2 -2
  237. package/.next/standalone/.next/server/app/dashboard/proxy-pools.rsc +6 -6
  238. package/.next/standalone/.next/server/app/dashboard/proxy-pools.segments/!KGRhc2hib2FyZCk/dashboard/proxy-pools/__PAGE__.segment.rsc +2 -2
  239. package/.next/standalone/.next/server/app/dashboard/proxy-pools.segments/!KGRhc2hib2FyZCk/dashboard/proxy-pools.segment.rsc +1 -1
  240. package/.next/standalone/.next/server/app/dashboard/proxy-pools.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  241. package/.next/standalone/.next/server/app/dashboard/proxy-pools.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  242. package/.next/standalone/.next/server/app/dashboard/proxy-pools.segments/_full.segment.rsc +6 -6
  243. package/.next/standalone/.next/server/app/dashboard/proxy-pools.segments/_head.segment.rsc +1 -1
  244. package/.next/standalone/.next/server/app/dashboard/proxy-pools.segments/_index.segment.rsc +3 -3
  245. package/.next/standalone/.next/server/app/dashboard/proxy-pools.segments/_tree.segment.rsc +2 -2
  246. package/.next/standalone/.next/server/app/dashboard/quota.html +2 -2
  247. package/.next/standalone/.next/server/app/dashboard/quota.rsc +6 -6
  248. package/.next/standalone/.next/server/app/dashboard/quota.segments/!KGRhc2hib2FyZCk/dashboard/quota/__PAGE__.segment.rsc +2 -2
  249. package/.next/standalone/.next/server/app/dashboard/quota.segments/!KGRhc2hib2FyZCk/dashboard/quota.segment.rsc +1 -1
  250. package/.next/standalone/.next/server/app/dashboard/quota.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  251. package/.next/standalone/.next/server/app/dashboard/quota.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  252. package/.next/standalone/.next/server/app/dashboard/quota.segments/_full.segment.rsc +6 -6
  253. package/.next/standalone/.next/server/app/dashboard/quota.segments/_head.segment.rsc +1 -1
  254. package/.next/standalone/.next/server/app/dashboard/quota.segments/_index.segment.rsc +3 -3
  255. package/.next/standalone/.next/server/app/dashboard/quota.segments/_tree.segment.rsc +2 -2
  256. package/.next/standalone/.next/server/app/dashboard/settings/pricing.html +1 -1
  257. package/.next/standalone/.next/server/app/dashboard/settings/pricing.rsc +5 -5
  258. package/.next/standalone/.next/server/app/dashboard/settings/pricing.segments/!KGRhc2hib2FyZCk/dashboard/settings/pricing/__PAGE__.segment.rsc +1 -1
  259. package/.next/standalone/.next/server/app/dashboard/settings/pricing.segments/!KGRhc2hib2FyZCk/dashboard/settings/pricing.segment.rsc +1 -1
  260. package/.next/standalone/.next/server/app/dashboard/settings/pricing.segments/!KGRhc2hib2FyZCk/dashboard/settings.segment.rsc +1 -1
  261. package/.next/standalone/.next/server/app/dashboard/settings/pricing.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  262. package/.next/standalone/.next/server/app/dashboard/settings/pricing.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  263. package/.next/standalone/.next/server/app/dashboard/settings/pricing.segments/_full.segment.rsc +5 -5
  264. package/.next/standalone/.next/server/app/dashboard/settings/pricing.segments/_head.segment.rsc +1 -1
  265. package/.next/standalone/.next/server/app/dashboard/settings/pricing.segments/_index.segment.rsc +3 -3
  266. package/.next/standalone/.next/server/app/dashboard/settings/pricing.segments/_tree.segment.rsc +2 -2
  267. package/.next/standalone/.next/server/app/dashboard/settings.html +2 -2
  268. package/.next/standalone/.next/server/app/dashboard/settings.rsc +6 -6
  269. package/.next/standalone/.next/server/app/dashboard/settings.segments/!KGRhc2hib2FyZCk/dashboard/settings/__PAGE__.segment.rsc +2 -2
  270. package/.next/standalone/.next/server/app/dashboard/settings.segments/!KGRhc2hib2FyZCk/dashboard/settings.segment.rsc +1 -1
  271. package/.next/standalone/.next/server/app/dashboard/settings.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  272. package/.next/standalone/.next/server/app/dashboard/settings.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  273. package/.next/standalone/.next/server/app/dashboard/settings.segments/_full.segment.rsc +6 -6
  274. package/.next/standalone/.next/server/app/dashboard/settings.segments/_head.segment.rsc +1 -1
  275. package/.next/standalone/.next/server/app/dashboard/settings.segments/_index.segment.rsc +3 -3
  276. package/.next/standalone/.next/server/app/dashboard/settings.segments/_tree.segment.rsc +2 -2
  277. package/.next/standalone/.next/server/app/dashboard/skills.html +2 -2
  278. package/.next/standalone/.next/server/app/dashboard/skills.rsc +6 -6
  279. package/.next/standalone/.next/server/app/dashboard/skills.segments/!KGRhc2hib2FyZCk/dashboard/skills/__PAGE__.segment.rsc +2 -2
  280. package/.next/standalone/.next/server/app/dashboard/skills.segments/!KGRhc2hib2FyZCk/dashboard/skills.segment.rsc +1 -1
  281. package/.next/standalone/.next/server/app/dashboard/skills.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  282. package/.next/standalone/.next/server/app/dashboard/skills.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  283. package/.next/standalone/.next/server/app/dashboard/skills.segments/_full.segment.rsc +6 -6
  284. package/.next/standalone/.next/server/app/dashboard/skills.segments/_head.segment.rsc +1 -1
  285. package/.next/standalone/.next/server/app/dashboard/skills.segments/_index.segment.rsc +3 -3
  286. package/.next/standalone/.next/server/app/dashboard/skills.segments/_tree.segment.rsc +2 -2
  287. package/.next/standalone/.next/server/app/dashboard/translator.html +2 -2
  288. package/.next/standalone/.next/server/app/dashboard/translator.rsc +6 -6
  289. package/.next/standalone/.next/server/app/dashboard/translator.segments/!KGRhc2hib2FyZCk/dashboard/translator/__PAGE__.segment.rsc +2 -2
  290. package/.next/standalone/.next/server/app/dashboard/translator.segments/!KGRhc2hib2FyZCk/dashboard/translator.segment.rsc +1 -1
  291. package/.next/standalone/.next/server/app/dashboard/translator.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  292. package/.next/standalone/.next/server/app/dashboard/translator.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  293. package/.next/standalone/.next/server/app/dashboard/translator.segments/_full.segment.rsc +6 -6
  294. package/.next/standalone/.next/server/app/dashboard/translator.segments/_head.segment.rsc +1 -1
  295. package/.next/standalone/.next/server/app/dashboard/translator.segments/_index.segment.rsc +3 -3
  296. package/.next/standalone/.next/server/app/dashboard/translator.segments/_tree.segment.rsc +2 -2
  297. package/.next/standalone/.next/server/app/dashboard/usage.html +1 -1
  298. package/.next/standalone/.next/server/app/dashboard/usage.rsc +6 -6
  299. package/.next/standalone/.next/server/app/dashboard/usage.segments/!KGRhc2hib2FyZCk/dashboard/usage/__PAGE__.segment.rsc +2 -2
  300. package/.next/standalone/.next/server/app/dashboard/usage.segments/!KGRhc2hib2FyZCk/dashboard/usage.segment.rsc +1 -1
  301. package/.next/standalone/.next/server/app/dashboard/usage.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  302. package/.next/standalone/.next/server/app/dashboard/usage.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  303. package/.next/standalone/.next/server/app/dashboard/usage.segments/_full.segment.rsc +6 -6
  304. package/.next/standalone/.next/server/app/dashboard/usage.segments/_head.segment.rsc +1 -1
  305. package/.next/standalone/.next/server/app/dashboard/usage.segments/_index.segment.rsc +3 -3
  306. package/.next/standalone/.next/server/app/dashboard/usage.segments/_tree.segment.rsc +2 -2
  307. package/.next/standalone/.next/server/app/dashboard.html +1 -1
  308. package/.next/standalone/.next/server/app/dashboard.rsc +7 -7
  309. package/.next/standalone/.next/server/app/dashboard.segments/!KGRhc2hib2FyZCk/dashboard/__PAGE__.segment.rsc +2 -2
  310. package/.next/standalone/.next/server/app/dashboard.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  311. package/.next/standalone/.next/server/app/dashboard.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  312. package/.next/standalone/.next/server/app/dashboard.segments/_full.segment.rsc +7 -7
  313. package/.next/standalone/.next/server/app/dashboard.segments/_head.segment.rsc +1 -1
  314. package/.next/standalone/.next/server/app/dashboard.segments/_index.segment.rsc +3 -3
  315. package/.next/standalone/.next/server/app/dashboard.segments/_tree.segment.rsc +2 -2
  316. package/.next/standalone/.next/server/app/index.html +1 -1
  317. package/.next/standalone/.next/server/app/index.rsc +2 -2
  318. package/.next/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  319. package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +2 -2
  320. package/.next/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  321. package/.next/standalone/.next/server/app/index.segments/_index.segment.rsc +2 -2
  322. package/.next/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  323. package/.next/standalone/.next/server/app/landing/page.js.nft.json +1 -1
  324. package/.next/standalone/.next/server/app/landing/page_client-reference-manifest.js +1 -1
  325. package/.next/standalone/.next/server/app/landing.html +1 -1
  326. package/.next/standalone/.next/server/app/landing.rsc +3 -3
  327. package/.next/standalone/.next/server/app/landing.segments/_full.segment.rsc +3 -3
  328. package/.next/standalone/.next/server/app/landing.segments/_head.segment.rsc +1 -1
  329. package/.next/standalone/.next/server/app/landing.segments/_index.segment.rsc +2 -2
  330. package/.next/standalone/.next/server/app/landing.segments/_tree.segment.rsc +2 -2
  331. package/.next/standalone/.next/server/app/landing.segments/landing/__PAGE__.segment.rsc +2 -2
  332. package/.next/standalone/.next/server/app/landing.segments/landing.segment.rsc +1 -1
  333. package/.next/standalone/.next/server/app/login/page.js.nft.json +1 -1
  334. package/.next/standalone/.next/server/app/login/page_client-reference-manifest.js +1 -1
  335. package/.next/standalone/.next/server/app/login.html +1 -1
  336. package/.next/standalone/.next/server/app/login.rsc +3 -3
  337. package/.next/standalone/.next/server/app/login.segments/_full.segment.rsc +3 -3
  338. package/.next/standalone/.next/server/app/login.segments/_head.segment.rsc +1 -1
  339. package/.next/standalone/.next/server/app/login.segments/_index.segment.rsc +2 -2
  340. package/.next/standalone/.next/server/app/login.segments/_tree.segment.rsc +2 -2
  341. package/.next/standalone/.next/server/app/login.segments/login/__PAGE__.segment.rsc +2 -2
  342. package/.next/standalone/.next/server/app/login.segments/login.segment.rsc +1 -1
  343. package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  344. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0.mzodm._.js +1 -1
  345. package/.next/standalone/.next/server/chunks/[root-of-the-server]__003scm0._.js +1 -1
  346. package/.next/standalone/.next/server/chunks/[root-of-the-server]__01kq~.r._.js +1 -1
  347. package/.next/standalone/.next/server/chunks/[root-of-the-server]__03sw1c3._.js +1 -1
  348. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0brgjhf._.js +1 -1
  349. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0d~p0cq._.js +1 -1
  350. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0h9.ugv._.js +1 -1
  351. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0i8ubss._.js +1 -1
  352. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0k2~rdk._.js +1 -1
  353. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0k6jln3._.js +2 -2
  354. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0m.0h8z._.js +1 -1
  355. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0n~_i6e._.js +1 -1
  356. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0o_0bxa._.js +1 -1
  357. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0uvu.gs._.js +1 -1
  358. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0zbooww._.js +1 -1
  359. package/.next/standalone/.next/server/chunks/_0743~zr._.js +1 -1
  360. package/.next/standalone/.next/server/chunks/_0h~0zar._.js +1 -1
  361. package/.next/standalone/.next/server/chunks/node_modules_next_dist_esm_build_templates_app-route_0k_a0xx.js +1 -1
  362. package/.next/standalone/.next/server/chunks/node_modules_next_dist_esm_build_templates_app-route_0o8sjwu.js +1 -1
  363. package/.next/standalone/.next/server/chunks/node_modules_next_dist_esm_build_templates_app-route_0tqpghm.js +1 -1
  364. package/.next/standalone/.next/server/chunks/node_modules_next_dist_esm_build_templates_app-route_12p6yih.js +5 -5
  365. package/.next/standalone/.next/server/chunks/ssr/_0-o1.gf._.js +3 -0
  366. package/.next/standalone/.next/server/chunks/ssr/_0-~8uap._.js +1 -1
  367. package/.next/standalone/.next/server/chunks/ssr/{_13vwxhk._.js → _03~l39c._.js} +2 -2
  368. package/.next/standalone/.next/server/chunks/ssr/_04w48i.._.js +3 -0
  369. package/.next/standalone/.next/server/chunks/ssr/_0_hztrw._.js +3 -0
  370. package/.next/standalone/.next/server/chunks/ssr/_0bquxrm._.js +3 -0
  371. package/.next/standalone/.next/server/chunks/ssr/_0k060hw._.js +3 -0
  372. package/.next/standalone/.next/server/chunks/ssr/_0p0d9p4._.js +3 -0
  373. package/.next/standalone/.next/server/chunks/ssr/_0p_8t2a._.js +3 -0
  374. package/.next/standalone/.next/server/chunks/ssr/_0y_u_c_._.js +7 -0
  375. package/.next/standalone/.next/server/middleware-build-manifest.js +3 -3
  376. package/.next/standalone/.next/server/pages/404.html +1 -1
  377. package/.next/standalone/.next/server/pages/500.html +1 -1
  378. package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
  379. package/.next/standalone/.next/server/server-reference-manifest.json +1 -1
  380. package/.next/standalone/WorkerProxy/package-lock.json +3570 -0
  381. package/.next/standalone/WorkerProxy/package.json +22 -0
  382. package/.next/standalone/WorkerProxy/tsconfig.json +20 -0
  383. package/.next/standalone/package-lock.json +2 -2
  384. package/.next/standalone/package.json +3 -2
  385. package/.next/static/chunks/{0-7g8~~9az0a9.js → 0-8mpnlo8y_tj.js} +1 -1
  386. package/.next/static/chunks/{09zlsx5qsaeuo.js → 00j87-lc_wvtd.js} +1 -1
  387. package/.next/static/chunks/08hgd_~o140~6.js +1 -0
  388. package/.next/static/chunks/093sb5s6tg.d~.js +7 -0
  389. package/.next/static/chunks/0hf--lbch~.di.js +1 -0
  390. package/.next/static/chunks/0o3xjtrgx~i2u.js +1 -0
  391. package/.next/static/chunks/0r_8gbx840jol.js +1 -0
  392. package/.next/static/chunks/0s~jr3m--sfo2.js +5 -0
  393. package/.next/static/chunks/0woj8_9_5ws~k.css +1 -0
  394. package/.next/static/chunks/0~t7g-h-wdi67.js +1 -0
  395. package/installer.sh +211 -0
  396. package/package.json +3 -2
  397. package/scripts/service.js +386 -74
  398. package/scripts/start.js +23 -1
  399. package/src/app/login/page.tsx +39 -314
  400. package/.next/standalone/.next/server/chunks/ssr/_00f6536._.js +0 -3
  401. package/.next/standalone/.next/server/chunks/ssr/_01hq7xj._.js +0 -7
  402. package/.next/standalone/.next/server/chunks/ssr/_0c9x38a._.js +0 -3
  403. package/.next/standalone/.next/server/chunks/ssr/_0fikbv4._.js +0 -3
  404. package/.next/standalone/.next/server/chunks/ssr/_0fk4yvh._.js +0 -3
  405. package/.next/standalone/.next/server/chunks/ssr/_0frtcm3._.js +0 -3
  406. package/.next/standalone/.next/server/chunks/ssr/_0khqaqv._.js +0 -3
  407. package/.next/standalone/.next/server/chunks/ssr/_0x0xx9p._.js +0 -3
  408. package/.next/standalone/.next/server/chunks/ssr/_13u7lt-._.js +0 -3
  409. package/.next/static/chunks/0-6gya.tj0dk7.js +0 -1
  410. package/.next/static/chunks/04quk80rrt07~.js +0 -1
  411. package/.next/static/chunks/0eu47j24g2bzm.js +0 -5
  412. package/.next/static/chunks/0iv_qp-wgtx-_.css +0 -1
  413. package/.next/static/chunks/0jyn0615kxxi1.js +0 -1
  414. package/.next/static/chunks/0peqcn6~om0vp.js +0 -1
  415. package/.next/static/chunks/0vqox~1257tth.js +0 -1
  416. package/.next/static/chunks/0x871_qyqh.y4.js +0 -1
  417. package/.next/static/chunks/15p_plajhlg_e.js +0 -7
  418. /package/.next/static/{olzWK3KCh9LlwHyWUO_bm → JwKavHa5OgD3g5HXE6pag}/_buildManifest.js +0 -0
  419. /package/.next/static/{olzWK3KCh9LlwHyWUO_bm → JwKavHa5OgD3g5HXE6pag}/_clientMiddlewareManifest.js +0 -0
  420. /package/.next/static/{olzWK3KCh9LlwHyWUO_bm → JwKavHa5OgD3g5HXE6pag}/_ssgManifest.js +0 -0
@@ -1,8 +1,12 @@
1
1
  #!/usr/bin/env node
2
+ // IMPORTANT: Never chown the axonrouter package directory to root.
3
+ // This breaks native modules like better-sqlite3.
2
4
 
3
5
  import { execSync, spawnSync } from "node:child_process";
4
6
  import fs from "node:fs";
7
+ import os from "node:os";
5
8
  import path from "node:path";
9
+ import { fileURLToPath } from "node:url";
6
10
 
7
11
  const SERVICE_NAME = "axonrouter";
8
12
  const SYSTEMD_UNIT_PATH = `/etc/systemd/system/${SERVICE_NAME}.service`;
@@ -10,6 +14,9 @@ const INITD_SCRIPT_PATH = `/etc/init.d/${SERVICE_NAME}`;
10
14
  const PID_FILE = `/var/run/${SERVICE_NAME}.pid`;
11
15
  const DEFAULT_PORT = 12711;
12
16
 
17
+ const USER_SYSTEMD_DIR = path.join(os.homedir(), ".config", "systemd", "user");
18
+ const USER_UNIT_PATH = path.join(USER_SYSTEMD_DIR, `${SERVICE_NAME}.service`);
19
+
13
20
  /**
14
21
  * Check if the current process is running as root (uid 0).
15
22
  */
@@ -17,17 +24,6 @@ export function isRoot() {
17
24
  return process.getuid() === 0;
18
25
  }
19
26
 
20
- /**
21
- * Require root privileges. Prints error and exits if not root.
22
- */
23
- export function requireRoot() {
24
- if (!isRoot()) {
25
- console.error("\x1b[31m[AxonRouter] Error: Service management requires root privileges.\x1b[0m");
26
- console.error("\x1b[33mPlease run with sudo: sudo axonrouter install-service\x1b[0m");
27
- process.exit(1);
28
- }
29
- }
30
-
31
27
  /**
32
28
  * Run a command with sudo if not already root.
33
29
  * Prompts for password interactively when needed.
@@ -63,15 +59,13 @@ export function detectInitSystem() {
63
59
  }
64
60
 
65
61
  /**
66
- * Get the path to the axonrouter binary (via `which axonrouter`).
62
+ * Get the path to the axonrouter binary resolved from import.meta.url.
63
+ * This avoids relying on 'which axonrouter' which fails under sudo or nvm.
67
64
  */
68
65
  export function getExecPath() {
69
- try {
70
- return execSync("which axonrouter", { encoding: "utf-8" }).trim();
71
- } catch {
72
- // Fallback to the current process argv
73
- return process.argv[1] || "/usr/local/bin/axonrouter";
74
- }
66
+ const __filename = fileURLToPath(import.meta.url);
67
+ const __dirname = path.dirname(__filename);
68
+ return path.resolve(__dirname, "..", "bin", "axonrouter.js");
75
69
  }
76
70
 
77
71
  /**
@@ -83,41 +77,171 @@ export function getNodePath() {
83
77
  return process.execPath;
84
78
  }
85
79
 
80
+ /**
81
+ * Resolve the home directory for a given user.
82
+ * When SUDO_USER is set, tries /etc/passwd lookup, then falls back to /home/<user>.
83
+ * For root, returns /root. Otherwise falls back to os.homedir().
84
+ */
85
+ export function getInstallingUserHome(user) {
86
+ if (user === "root") {
87
+ return "/root";
88
+ }
89
+
90
+ // Try to read from /etc/passwd
91
+ try {
92
+ const passwd = fs.readFileSync("/etc/passwd", "utf-8");
93
+ const lines = passwd.split("\n");
94
+ for (const line of lines) {
95
+ const fields = line.split(":");
96
+ if (fields[0] === user && fields[5]) {
97
+ return fields[5];
98
+ }
99
+ }
100
+ } catch {
101
+ // /etc/passwd not readable, fall through
102
+ }
103
+
104
+ // Fall back to /home/<user> if SUDO_USER is set
105
+ if (process.env.SUDO_USER) {
106
+ return `/home/${user}`;
107
+ }
108
+
109
+ return os.homedir();
110
+ }
111
+
112
+ /**
113
+ * Detect the real (non-root) user who invoked the install command.
114
+ * When run via sudo, reads SUDO_USER and SUDO_GID for the original user.
115
+ * Otherwise uses os.userInfo() for the current user.
116
+ * Returns { user, group, home }.
117
+ */
118
+ export function getInstallingUser() {
119
+ const sudoUser = process.env.SUDO_USER;
120
+
121
+ if (sudoUser) {
122
+ let group = process.env.SUDO_GID || String(os.userInfo().gid);
123
+ // Try to resolve group name from GID via /etc/group
124
+ try {
125
+ const groupFile = fs.readFileSync("/etc/group", "utf-8");
126
+ const lines = groupFile.split("\n");
127
+ for (const line of lines) {
128
+ const fields = line.split(":");
129
+ if (fields[2] === group) {
130
+ group = fields[0];
131
+ break;
132
+ }
133
+ }
134
+ } catch {
135
+ // If we can't resolve the group name, use the username as group
136
+ group = sudoUser;
137
+ }
138
+
139
+ // If group is still numeric (GID didn't resolve), fall back to username
140
+ if (/^\d+$/.test(group)) {
141
+ group = sudoUser;
142
+ }
143
+
144
+ const home = getInstallingUserHome(sudoUser);
145
+ return { user: sudoUser, group, home };
146
+ }
147
+
148
+ const info = os.userInfo();
149
+ const user = info.username;
150
+ let group = String(info.gid);
151
+
152
+ // Try to resolve group name from GID via /etc/group
153
+ try {
154
+ const groupFile = fs.readFileSync("/etc/group", "utf-8");
155
+ const lines = groupFile.split("\n");
156
+ for (const line of lines) {
157
+ const fields = line.split(":");
158
+ if (fields[2] === group) {
159
+ group = fields[0];
160
+ break;
161
+ }
162
+ }
163
+ } catch {
164
+ // Fall back to username as group
165
+ group = user;
166
+ }
167
+
168
+ // If group is still numeric (GID didn't resolve), fall back to username
169
+ if (/^\d+$/.test(group)) {
170
+ group = user;
171
+ }
172
+
173
+ const home = getInstallingUserHome(user);
174
+ return { user, group, home };
175
+ }
176
+
86
177
  /**
87
178
  * Generate systemd unit file content.
88
179
  * Uses absolute node path + script path to avoid shebang/PATH issues under systemd.
180
+ * Accepts an optional userInfo parameter to avoid repeated getInstallingUser() calls.
181
+ * When userMode is true, omits User=/Group= and uses WantedBy=default.target.
89
182
  */
90
- export function generateSystemdUnit(execPath) {
183
+ export function generateSystemdUnit(execPath, userInfo, options = {}) {
91
184
  const nodePath = getNodePath();
92
- return `[Unit]
93
- Description=AxonRouter AI Router
94
- After=network.target
95
- StartLimitIntervalSec=300
96
- StartLimitBurst=5
185
+ const { user, group, home } = userInfo || getInstallingUser();
186
+ const workingDirectory = path.resolve(path.dirname(execPath), "..");
187
+ const userMode = options.userMode || false;
97
188
 
98
- [Service]
189
+ let serviceSection;
190
+ if (userMode) {
191
+ serviceSection = `[Service]
99
192
  Type=simple
193
+ WorkingDirectory=${workingDirectory}
100
194
  ExecStart=${nodePath} ${execPath}
101
195
  Restart=always
102
196
  RestartSec=5
103
197
  Environment=NODE_ENV=production
104
198
  Environment=PORT=${DEFAULT_PORT}
199
+ Environment=HOME=${home}
105
200
  # Graceful shutdown timeout
106
201
  TimeoutStopSec=30
107
202
  # Kill remaining child processes (cloudflared, tailscaled) on stop
108
- KillMode=control-group
203
+ KillMode=control-group`;
204
+ } else {
205
+ serviceSection = `[Service]
206
+ Type=simple
207
+ User=${user}
208
+ Group=${group}
209
+ WorkingDirectory=${workingDirectory}
210
+ ExecStart=${nodePath} ${execPath}
211
+ Restart=always
212
+ RestartSec=5
213
+ Environment=NODE_ENV=production
214
+ Environment=PORT=${DEFAULT_PORT}
215
+ Environment=HOME=${home}
216
+ # Graceful shutdown timeout
217
+ TimeoutStopSec=30
218
+ # Kill remaining child processes (cloudflared, tailscaled) on stop
219
+ KillMode=control-group`;
220
+ }
221
+
222
+ const wantedBy = userMode ? "default.target" : "multi-user.target";
223
+
224
+ return `[Unit]
225
+ Description=AxonRouter AI Router
226
+ After=network.target
227
+ StartLimitIntervalSec=300
228
+ StartLimitBurst=5
229
+
230
+ ${serviceSection}
109
231
 
110
232
  [Install]
111
- WantedBy=multi-user.target
233
+ WantedBy=${wantedBy}
112
234
  `;
113
235
  }
114
236
 
115
237
  /**
116
238
  * Generate init.d script content (LSB format).
117
239
  * Uses absolute node path to avoid PATH issues in init environment.
240
+ * Accepts an optional userInfo parameter to avoid repeated getInstallingUser() calls.
118
241
  */
119
- export function generateInitdScript(execPath) {
242
+ export function generateInitdScript(execPath, userInfo) {
120
243
  const nodePath = getNodePath();
244
+ const { user, group, home } = userInfo || getInstallingUser();
121
245
  return `#!/bin/sh
122
246
  ### BEGIN INIT INFO
123
247
  # Provides: ${SERVICE_NAME}
@@ -134,21 +258,24 @@ DAEMON="${execPath}"
134
258
  PIDFILE="${PID_FILE}"
135
259
  NAME="${SERVICE_NAME}"
136
260
  LOG_FILE="/var/log/${SERVICE_NAME}.log"
261
+ USER="${user}"
262
+ GROUP="${group}"
137
263
  export NODE_ENV=production
138
264
  export PORT=${DEFAULT_PORT}
265
+ export HOME=${home}
139
266
 
140
267
  start() {
141
268
  if [ -f "$PIDFILE" ] && kill -0 "$(cat "$PIDFILE")" 2>/dev/null; then
142
269
  echo "$NAME is already running."
143
270
  return 1
144
271
  fi
145
- echo "Starting $NAME..."
272
+ echo "Starting $NAME as user $USER..."
146
273
  # Start with auto-respawn: restart up to 10 times with 5s delay if process exits
147
274
  (
148
275
  RESTART_COUNT=0
149
276
  MAX_RESTARTS=10
150
277
  while [ $RESTART_COUNT -lt $MAX_RESTARTS ]; do
151
- "$NODE" "$DAEMON" >> "$LOG_FILE" 2>&1
278
+ su - "$USER" -c "HOME='${home}' NODE_ENV=production PORT=${DEFAULT_PORT} '${nodePath}' '${execPath}'" >> "$LOG_FILE" 2>&1
152
279
  EXIT_CODE=$?
153
280
  if [ $EXIT_CODE -eq 0 ]; then
154
281
  break
@@ -204,36 +331,97 @@ exit 0
204
331
  `;
205
332
  }
206
333
 
334
+ /**
335
+ * Check if the user session bus is available for systemctl --user commands.
336
+ * Returns true if the session bus is accessible, false otherwise.
337
+ */
338
+ export function isUserSessionAvailable() {
339
+ if (process.env.XDG_RUNTIME_DIR || process.env.DBUS_SESSION_BUS_ADDRESS) {
340
+ return true;
341
+ }
342
+ // Try running systemctl --user as a final check
343
+ try {
344
+ execSync("systemctl --user --no-pager status", { stdio: "ignore" });
345
+ return true;
346
+ } catch {
347
+ return false;
348
+ }
349
+ }
350
+
351
+ /**
352
+ * Get the user-level unit path for a specific user.
353
+ * When running as root with SUDO_USER set, resolves to that user's home.
354
+ */
355
+ export function getUserUnitPath(targetUser) {
356
+ if (targetUser) {
357
+ const home = getInstallingUserHome(targetUser);
358
+ return path.join(home, ".config", "systemd", "user", `${SERVICE_NAME}.service`);
359
+ }
360
+ return USER_UNIT_PATH;
361
+ }
362
+
207
363
  /**
208
364
  * Install the service (systemd or init.d).
209
- * Writes the service file, enables, and starts the service.
365
+ * When running as non-root with systemd, installs a user-level service.
366
+ * When running as root with systemd, installs a system-level service.
367
+ * For init.d, always uses sudo (no user-level support).
210
368
  */
211
369
  export function installService() {
212
370
  const initSystem = detectInitSystem();
213
371
  const execPath = getExecPath();
372
+ const { user, group } = getInstallingUser();
214
373
 
215
374
  console.log(`[AxonRouter] Detected init system: ${initSystem}`);
216
375
  console.log(`[AxonRouter] Executable path: ${execPath}`);
376
+ console.log(`[AxonRouter] Service will run as user: ${user} (group: ${group})`);
377
+
378
+ const userInfo = { user, group, home: getInstallingUserHome(user) };
217
379
 
218
380
  if (initSystem === "systemd") {
219
- const unitContent = generateSystemdUnit(execPath);
220
- // Write unit file via sudo tee (since we may not be root)
221
- const child = spawnSync("sudo", ["tee", SYSTEMD_UNIT_PATH], {
222
- input: unitContent,
223
- stdio: ["pipe", "pipe", "inherit"],
224
- });
225
- if (child.status !== 0) {
226
- console.error("[AxonRouter] Failed to write service file. Sudo access required.");
227
- process.exit(1);
228
- }
229
- console.log(`[AxonRouter] Service file written to ${SYSTEMD_UNIT_PATH}`);
381
+ if (isRoot()) {
382
+ // System-level service installation (existing behavior)
383
+ const unitContent = generateSystemdUnit(execPath, userInfo);
384
+ const child = spawnSync("sudo", ["tee", SYSTEMD_UNIT_PATH], {
385
+ input: unitContent,
386
+ stdio: ["pipe", "pipe", "inherit"],
387
+ });
388
+ if (child.status !== 0) {
389
+ console.error("[AxonRouter] Failed to write service file. Sudo access required.");
390
+ process.exit(1);
391
+ }
392
+ console.log(`[AxonRouter] Service file written to ${SYSTEMD_UNIT_PATH}`);
393
+
394
+ runWithSudo("systemctl daemon-reload");
395
+ runWithSudo(`systemctl enable ${SERVICE_NAME}`);
396
+ runWithSudo(`systemctl start ${SERVICE_NAME}`);
397
+ console.log(`[AxonRouter] System-level service installed, enabled, and started.`);
398
+ } else {
399
+ // User-level service installation (no sudo needed)
400
+ if (!isUserSessionAvailable()) {
401
+ console.error(`[AxonRouter] ERROR: User session bus is not available.`);
402
+ console.error(`[AxonRouter] systemctl --user requires an active user session or lingering enabled.`);
403
+ console.error(`[AxonRouter] To fix this, run: sudo loginctl enable-linger ${user}`);
404
+ console.error(`[AxonRouter] Then log out and back in, or reboot.`);
405
+ process.exit(1);
406
+ }
230
407
 
231
- runWithSudo("systemctl daemon-reload");
232
- runWithSudo(`systemctl enable ${SERVICE_NAME}`);
233
- runWithSudo(`systemctl start ${SERVICE_NAME}`);
234
- console.log(`[AxonRouter] Service installed, enabled, and started.`);
408
+ const unitContent = generateSystemdUnit(execPath, userInfo, { userMode: true });
409
+
410
+ fs.mkdirSync(USER_SYSTEMD_DIR, { recursive: true });
411
+ fs.writeFileSync(USER_UNIT_PATH, unitContent);
412
+ console.log(`[AxonRouter] Service file written to ${USER_UNIT_PATH}`);
413
+
414
+ execSync("systemctl --user daemon-reload", { stdio: "inherit" });
415
+ execSync(`systemctl --user enable ${SERVICE_NAME}`, { stdio: "inherit" });
416
+ execSync(`systemctl --user start ${SERVICE_NAME}`, { stdio: "inherit" });
417
+
418
+ console.log(`[AxonRouter] User-level service installed and started.`);
419
+ console.log(`[AxonRouter] To start at boot without login, run: sudo loginctl enable-linger ${user}`);
420
+ }
235
421
  } else {
236
- const scriptContent = generateInitdScript(execPath);
422
+ // init.d has no user-level support, requires sudo
423
+ console.log(`[AxonRouter] init.d does not support user-level services; sudo is required.`);
424
+ const scriptContent = generateInitdScript(execPath, userInfo);
237
425
  const child = spawnSync("sudo", ["tee", INITD_SCRIPT_PATH], {
238
426
  input: scriptContent,
239
427
  stdio: ["pipe", "pipe", "inherit"],
@@ -262,6 +450,8 @@ export function installService() {
262
450
 
263
451
  /**
264
452
  * Uninstall the service (stop, disable, remove).
453
+ * Detects whether a user-level or system-level service is installed.
454
+ * When running as root, checks if SUDO_USER has a user-level unit.
265
455
  */
266
456
  export function uninstallService() {
267
457
  const initSystem = detectInitSystem();
@@ -269,24 +459,82 @@ export function uninstallService() {
269
459
  console.log(`[AxonRouter] Detected init system: ${initSystem}`);
270
460
 
271
461
  if (initSystem === "systemd") {
272
- try {
273
- runWithSudo(`systemctl stop ${SERVICE_NAME}`);
274
- } catch {
275
- // Service might not be running
276
- }
277
- try {
278
- runWithSudo(`systemctl disable ${SERVICE_NAME}`);
279
- } catch {
280
- // Service might not be enabled
281
- }
282
- try {
283
- runWithSudo(`rm -f ${SYSTEMD_UNIT_PATH}`);
284
- console.log(`[AxonRouter] Removed ${SYSTEMD_UNIT_PATH}`);
285
- } catch {
286
- // File might not exist
462
+ // When running as root with SUDO_USER, check that user's unit path too
463
+ const sudoUser = process.env.SUDO_USER;
464
+ const effectiveUserUnitPath = (isRoot() && sudoUser)
465
+ ? getUserUnitPath(sudoUser)
466
+ : USER_UNIT_PATH;
467
+
468
+ const userLevelExists = fs.existsSync(effectiveUserUnitPath);
469
+ const systemLevelExists = fs.existsSync(SYSTEMD_UNIT_PATH);
470
+
471
+ if (userLevelExists && !isRoot()) {
472
+ // Uninstall user-level service (current user)
473
+ try {
474
+ execSync(`systemctl --user stop ${SERVICE_NAME}`, { stdio: "inherit" });
475
+ } catch {
476
+ // Service might not be running
477
+ }
478
+ try {
479
+ execSync(`systemctl --user disable ${SERVICE_NAME}`, { stdio: "inherit" });
480
+ } catch {
481
+ // Service might not be enabled
482
+ }
483
+ try {
484
+ fs.unlinkSync(USER_UNIT_PATH);
485
+ console.log(`[AxonRouter] Removed ${USER_UNIT_PATH}`);
486
+ } catch {
487
+ // File might not exist
488
+ }
489
+ execSync("systemctl --user daemon-reload", { stdio: "inherit" });
490
+ console.log(`[AxonRouter] User-level service uninstalled.`);
491
+ } else if (userLevelExists && isRoot() && sudoUser) {
492
+ // Root is uninstalling a user-level service owned by SUDO_USER
493
+ try {
494
+ execSync(`sudo -u ${sudoUser} XDG_RUNTIME_DIR=/run/user/$(id -u ${sudoUser}) systemctl --user stop ${SERVICE_NAME}`, { stdio: "inherit" });
495
+ } catch {
496
+ // Service might not be running
497
+ }
498
+ try {
499
+ execSync(`sudo -u ${sudoUser} XDG_RUNTIME_DIR=/run/user/$(id -u ${sudoUser}) systemctl --user disable ${SERVICE_NAME}`, { stdio: "inherit" });
500
+ } catch {
501
+ // Service might not be enabled
502
+ }
503
+ try {
504
+ fs.unlinkSync(effectiveUserUnitPath);
505
+ console.log(`[AxonRouter] Removed ${effectiveUserUnitPath}`);
506
+ } catch {
507
+ // File might not exist
508
+ }
509
+ try {
510
+ execSync(`sudo -u ${sudoUser} XDG_RUNTIME_DIR=/run/user/$(id -u ${sudoUser}) systemctl --user daemon-reload`, { stdio: "inherit" });
511
+ } catch {
512
+ // daemon-reload may fail if session not available, but file is already removed
513
+ }
514
+ console.log(`[AxonRouter] User-level service for ${sudoUser} uninstalled.`);
515
+ } else if (systemLevelExists) {
516
+ // Uninstall system-level service
517
+ try {
518
+ runWithSudo(`systemctl stop ${SERVICE_NAME}`);
519
+ } catch {
520
+ // Service might not be running
521
+ }
522
+ try {
523
+ runWithSudo(`systemctl disable ${SERVICE_NAME}`);
524
+ } catch {
525
+ // Service might not be enabled
526
+ }
527
+ try {
528
+ runWithSudo(`rm -f ${SYSTEMD_UNIT_PATH}`);
529
+ console.log(`[AxonRouter] Removed ${SYSTEMD_UNIT_PATH}`);
530
+ } catch {
531
+ // File might not exist
532
+ }
533
+ runWithSudo("systemctl daemon-reload");
534
+ console.log(`[AxonRouter] System-level service uninstalled.`);
535
+ } else {
536
+ console.log(`[AxonRouter] No service found to uninstall.`);
287
537
  }
288
- runWithSudo("systemctl daemon-reload");
289
- console.log(`[AxonRouter] Service uninstalled.`);
290
538
  } else {
291
539
  try {
292
540
  runWithSudo(`${INITD_SCRIPT_PATH} stop`);
@@ -319,6 +567,7 @@ export function uninstallService() {
319
567
 
320
568
  /**
321
569
  * Check the status of the service.
570
+ * Checks both user-level and system-level unit paths and reports status.
322
571
  */
323
572
  export function checkService() {
324
573
  const initSystem = detectInitSystem();
@@ -326,17 +575,33 @@ export function checkService() {
326
575
  console.log(`[AxonRouter] Init system: ${initSystem}`);
327
576
 
328
577
  if (initSystem === "systemd") {
329
- const installed = fs.existsSync(SYSTEMD_UNIT_PATH);
330
- console.log(`[AxonRouter] Service installed: ${installed}`);
578
+ const userLevelExists = fs.existsSync(USER_UNIT_PATH);
579
+ const systemLevelExists = fs.existsSync(SYSTEMD_UNIT_PATH);
331
580
 
332
- if (installed) {
581
+ if (userLevelExists) {
582
+ console.log(`[AxonRouter] User-level service installed: ${USER_UNIT_PATH}`);
333
583
  try {
334
- const status = execSync(`systemctl is-active ${SERVICE_NAME}`, { encoding: "utf-8" }).trim();
584
+ const status = execSync(`systemctl --user is-active ${SERVICE_NAME}`, { encoding: "utf-8" }).trim();
335
585
  console.log(`[AxonRouter] Service status: ${status}`);
336
- } catch (err) {
586
+ } catch {
337
587
  console.log(`[AxonRouter] Service status: inactive`);
338
588
  }
589
+ try {
590
+ const enabled = execSync(`systemctl --user is-enabled ${SERVICE_NAME}`, { encoding: "utf-8" }).trim();
591
+ console.log(`[AxonRouter] Service enabled: ${enabled}`);
592
+ } catch {
593
+ console.log(`[AxonRouter] Service enabled: disabled`);
594
+ }
595
+ }
339
596
 
597
+ if (systemLevelExists) {
598
+ console.log(`[AxonRouter] System-level service installed: ${SYSTEMD_UNIT_PATH}`);
599
+ try {
600
+ const status = execSync(`systemctl is-active ${SERVICE_NAME}`, { encoding: "utf-8" }).trim();
601
+ console.log(`[AxonRouter] Service status: ${status}`);
602
+ } catch {
603
+ console.log(`[AxonRouter] Service status: inactive`);
604
+ }
340
605
  try {
341
606
  const enabled = execSync(`systemctl is-enabled ${SERVICE_NAME}`, { encoding: "utf-8" }).trim();
342
607
  console.log(`[AxonRouter] Service enabled: ${enabled}`);
@@ -344,6 +609,10 @@ export function checkService() {
344
609
  console.log(`[AxonRouter] Service enabled: disabled`);
345
610
  }
346
611
  }
612
+
613
+ if (!userLevelExists && !systemLevelExists) {
614
+ console.log(`[AxonRouter] Service installed: false`);
615
+ }
347
616
  } else {
348
617
  const installed = fs.existsSync(INITD_SCRIPT_PATH);
349
618
  console.log(`[AxonRouter] Service installed: ${installed}`);
@@ -360,12 +629,24 @@ export function checkService() {
360
629
 
361
630
  /**
362
631
  * Start the service.
632
+ * Checks for user-level service (including via SUDO_USER when root).
363
633
  */
364
634
  export function startService() {
365
635
  const initSystem = detectInitSystem();
366
636
 
367
637
  if (initSystem === "systemd") {
368
- runWithSudo(`systemctl start ${SERVICE_NAME}`);
638
+ const sudoUser = process.env.SUDO_USER;
639
+ const effectiveUserUnitPath = (isRoot() && sudoUser)
640
+ ? getUserUnitPath(sudoUser)
641
+ : USER_UNIT_PATH;
642
+
643
+ if (fs.existsSync(effectiveUserUnitPath) && !isRoot()) {
644
+ execSync(`systemctl --user start ${SERVICE_NAME}`, { stdio: "inherit" });
645
+ } else if (fs.existsSync(effectiveUserUnitPath) && isRoot() && sudoUser) {
646
+ execSync(`sudo -u ${sudoUser} XDG_RUNTIME_DIR=/run/user/$(id -u ${sudoUser}) systemctl --user start ${SERVICE_NAME}`, { stdio: "inherit" });
647
+ } else {
648
+ runWithSudo(`systemctl start ${SERVICE_NAME}`);
649
+ }
369
650
  } else {
370
651
  runWithSudo(`${INITD_SCRIPT_PATH} start`);
371
652
  }
@@ -375,12 +656,24 @@ export function startService() {
375
656
 
376
657
  /**
377
658
  * Stop the service.
659
+ * Checks for user-level service (including via SUDO_USER when root).
378
660
  */
379
661
  export function stopService() {
380
662
  const initSystem = detectInitSystem();
381
663
 
382
664
  if (initSystem === "systemd") {
383
- runWithSudo(`systemctl stop ${SERVICE_NAME}`);
665
+ const sudoUser = process.env.SUDO_USER;
666
+ const effectiveUserUnitPath = (isRoot() && sudoUser)
667
+ ? getUserUnitPath(sudoUser)
668
+ : USER_UNIT_PATH;
669
+
670
+ if (fs.existsSync(effectiveUserUnitPath) && !isRoot()) {
671
+ execSync(`systemctl --user stop ${SERVICE_NAME}`, { stdio: "inherit" });
672
+ } else if (fs.existsSync(effectiveUserUnitPath) && isRoot() && sudoUser) {
673
+ execSync(`sudo -u ${sudoUser} XDG_RUNTIME_DIR=/run/user/$(id -u ${sudoUser}) systemctl --user stop ${SERVICE_NAME}`, { stdio: "inherit" });
674
+ } else {
675
+ runWithSudo(`systemctl stop ${SERVICE_NAME}`);
676
+ }
384
677
  } else {
385
678
  runWithSudo(`${INITD_SCRIPT_PATH} stop`);
386
679
  }
@@ -390,12 +683,24 @@ export function stopService() {
390
683
 
391
684
  /**
392
685
  * Restart the service.
686
+ * Checks for user-level service (including via SUDO_USER when root).
393
687
  */
394
688
  export function restartService() {
395
689
  const initSystem = detectInitSystem();
396
690
 
397
691
  if (initSystem === "systemd") {
398
- runWithSudo(`systemctl restart ${SERVICE_NAME}`);
692
+ const sudoUser = process.env.SUDO_USER;
693
+ const effectiveUserUnitPath = (isRoot() && sudoUser)
694
+ ? getUserUnitPath(sudoUser)
695
+ : USER_UNIT_PATH;
696
+
697
+ if (fs.existsSync(effectiveUserUnitPath) && !isRoot()) {
698
+ execSync(`systemctl --user restart ${SERVICE_NAME}`, { stdio: "inherit" });
699
+ } else if (fs.existsSync(effectiveUserUnitPath) && isRoot() && sudoUser) {
700
+ execSync(`sudo -u ${sudoUser} XDG_RUNTIME_DIR=/run/user/$(id -u ${sudoUser}) systemctl --user restart ${SERVICE_NAME}`, { stdio: "inherit" });
701
+ } else {
702
+ runWithSudo(`systemctl restart ${SERVICE_NAME}`);
703
+ }
399
704
  } else {
400
705
  runWithSudo(`${INITD_SCRIPT_PATH} restart`);
401
706
  }
@@ -407,8 +712,14 @@ export function restartService() {
407
712
  * Show help message with available commands.
408
713
  */
409
714
  export function showHelp() {
715
+ let version = "unknown";
716
+ try {
717
+ const pkgUrl = new URL("../package.json", import.meta.url);
718
+ version = JSON.parse(fs.readFileSync(pkgUrl, "utf8")).version;
719
+ } catch {}
720
+
410
721
  console.log(`
411
- \x1b[1mAxonRouter - AI Router Service Management\x1b[0m
722
+ \x1b[1mAxonRouter v${version} - AI Router\x1b[0m
412
723
 
413
724
  \x1b[33mUsage:\x1b[0m
414
725
  axonrouter <command> [options]
@@ -436,7 +747,8 @@ export function showHelp() {
436
747
  axonrouter --port 3000 Start on custom port
437
748
 
438
749
  \x1b[33mNotes:\x1b[0m
439
- Service commands will prompt for sudo password if not running as root.
750
+ When not running as root, service installs as a user-level systemd service.
751
+ When running as root, service installs as a system-level service.
440
752
  The service auto-restarts on crash (systemd: always, init.d: up to 10 times).
441
753
  `);
442
754
  }