@thangnm.nip/arouter 0.1.11 → 0.1.13

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 (208) hide show
  1. package/.next/standalone/.next/BUILD_ID +1 -1
  2. package/.next/standalone/.next/app-path-routes-manifest.json +7 -6
  3. package/.next/standalone/.next/build-manifest.json +4 -4
  4. package/.next/standalone/.next/prerender-manifest.json +3 -3
  5. package/.next/standalone/.next/required-server-files.json +4 -4
  6. package/.next/standalone/.next/routes-manifest.json +6 -0
  7. package/.next/standalone/.next/server/app/(dashboard)/mitm/page.js +2 -2
  8. package/.next/standalone/.next/server/app/(dashboard)/mitm/page.js.nft.json +1 -1
  9. package/.next/standalone/.next/server/app/(dashboard)/mitm/page_client-reference-manifest.js +1 -1
  10. package/.next/standalone/.next/server/app/(dashboard)/page.js +2 -2
  11. package/.next/standalone/.next/server/app/(dashboard)/page.js.nft.json +1 -1
  12. package/.next/standalone/.next/server/app/(dashboard)/page_client-reference-manifest.js +1 -1
  13. package/.next/standalone/.next/server/app/_global-error/page.js +3 -3
  14. package/.next/standalone/.next/server/app/_global-error/page.js.nft.json +1 -1
  15. package/.next/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  16. package/.next/standalone/.next/server/app/_global-error.html +2 -2
  17. package/.next/standalone/.next/server/app/_global-error.rsc +1 -1
  18. package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  19. package/.next/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  20. package/.next/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  21. package/.next/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  22. package/.next/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  23. package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  24. package/.next/standalone/.next/server/app/_not-found/page.js +2 -2
  25. package/.next/standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
  26. package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  27. package/.next/standalone/.next/server/app/_not-found.html +1 -1
  28. package/.next/standalone/.next/server/app/_not-found.rsc +3 -3
  29. package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +3 -3
  30. package/.next/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  31. package/.next/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +3 -3
  32. package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  33. package/.next/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  34. package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  35. package/.next/standalone/.next/server/app/api/cli-tools/antigravity-mitm/alias/route.js +2 -2
  36. package/.next/standalone/.next/server/app/api/cli-tools/antigravity-mitm/alias/route_client-reference-manifest.js +1 -1
  37. package/.next/standalone/.next/server/app/api/cli-tools/antigravity-mitm/console-logs/route.js +2 -2
  38. package/.next/standalone/.next/server/app/api/cli-tools/antigravity-mitm/console-logs/route_client-reference-manifest.js +1 -1
  39. package/.next/standalone/.next/server/app/api/cli-tools/antigravity-mitm/logs/route.js +8 -0
  40. package/.next/standalone/.next/server/app/api/cli-tools/antigravity-mitm/logs/route.js.nft.json +1 -0
  41. package/.next/standalone/.next/server/app/api/cli-tools/antigravity-mitm/logs/route_client-reference-manifest.js +1 -0
  42. package/.next/standalone/.next/server/app/api/cli-tools/antigravity-mitm/route.js +1 -1
  43. package/.next/standalone/.next/server/app/api/cli-tools/antigravity-mitm/route_client-reference-manifest.js +1 -1
  44. package/.next/standalone/.next/server/app/api/cli-tools/antigravity-mitm/settings/route.js +2 -2
  45. package/.next/standalone/.next/server/app/api/cli-tools/antigravity-mitm/settings/route_client-reference-manifest.js +1 -1
  46. package/.next/standalone/.next/server/app/api/cli-tools/claude-settings/route.js +2 -2
  47. package/.next/standalone/.next/server/app/api/cli-tools/claude-settings/route_client-reference-manifest.js +1 -1
  48. package/.next/standalone/.next/server/app/api/cli-tools/codex-settings/route.js +3 -3
  49. package/.next/standalone/.next/server/app/api/cli-tools/codex-settings/route_client-reference-manifest.js +1 -1
  50. package/.next/standalone/.next/server/app/api/cli-tools/copilot-settings/route.js +2 -2
  51. package/.next/standalone/.next/server/app/api/cli-tools/copilot-settings/route_client-reference-manifest.js +1 -1
  52. package/.next/standalone/.next/server/app/api/cli-tools/droid-settings/route.js +1 -1
  53. package/.next/standalone/.next/server/app/api/cli-tools/droid-settings/route_client-reference-manifest.js +1 -1
  54. package/.next/standalone/.next/server/app/api/cli-tools/openclaw-settings/route.js +2 -2
  55. package/.next/standalone/.next/server/app/api/cli-tools/openclaw-settings/route_client-reference-manifest.js +1 -1
  56. package/.next/standalone/.next/server/app/api/cli-tools/opencode-settings/route.js +2 -2
  57. package/.next/standalone/.next/server/app/api/cli-tools/opencode-settings/route_client-reference-manifest.js +1 -1
  58. package/.next/standalone/.next/server/app/api/keys/[id]/route.js +1 -1
  59. package/.next/standalone/.next/server/app/api/keys/[id]/route_client-reference-manifest.js +1 -1
  60. package/.next/standalone/.next/server/app/api/keys/route.js +1 -1
  61. package/.next/standalone/.next/server/app/api/keys/route_client-reference-manifest.js +1 -1
  62. package/.next/standalone/.next/server/app/api/locale/route.js +2 -2
  63. package/.next/standalone/.next/server/app/api/locale/route_client-reference-manifest.js +1 -1
  64. package/.next/standalone/.next/server/app/api/models/alias/route.js +1 -1
  65. package/.next/standalone/.next/server/app/api/models/alias/route_client-reference-manifest.js +1 -1
  66. package/.next/standalone/.next/server/app/api/models/route.js +1 -1
  67. package/.next/standalone/.next/server/app/api/models/route_client-reference-manifest.js +1 -1
  68. package/.next/standalone/.next/server/app/api/providers/route.js +1 -1
  69. package/.next/standalone/.next/server/app/api/providers/route_client-reference-manifest.js +1 -1
  70. package/.next/standalone/.next/server/app/api/settings/route.js +1 -1
  71. package/.next/standalone/.next/server/app/api/settings/route_client-reference-manifest.js +1 -1
  72. package/.next/standalone/.next/server/app/api/version/route.js +1 -1
  73. package/.next/standalone/.next/server/app/api/version/route_client-reference-manifest.js +1 -1
  74. package/.next/standalone/.next/server/app/index.html +1 -1
  75. package/.next/standalone/.next/server/app/index.rsc +4 -4
  76. package/.next/standalone/.next/server/app/index.segments/!KGRhc2hib2FyZCk/__PAGE__.segment.rsc +1 -1
  77. package/.next/standalone/.next/server/app/index.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  78. package/.next/standalone/.next/server/app/index.segments/_full.segment.rsc +4 -4
  79. package/.next/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  80. package/.next/standalone/.next/server/app/index.segments/_index.segment.rsc +3 -3
  81. package/.next/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  82. package/.next/standalone/.next/server/app/mitm.html +1 -1
  83. package/.next/standalone/.next/server/app/mitm.rsc +5 -5
  84. package/.next/standalone/.next/server/app/mitm.segments/!KGRhc2hib2FyZCk/mitm/__PAGE__.segment.rsc +2 -2
  85. package/.next/standalone/.next/server/app/mitm.segments/!KGRhc2hib2FyZCk/mitm.segment.rsc +1 -1
  86. package/.next/standalone/.next/server/app/mitm.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  87. package/.next/standalone/.next/server/app/mitm.segments/_full.segment.rsc +5 -5
  88. package/.next/standalone/.next/server/app/mitm.segments/_head.segment.rsc +1 -1
  89. package/.next/standalone/.next/server/app/mitm.segments/_index.segment.rsc +3 -3
  90. package/.next/standalone/.next/server/app/mitm.segments/_tree.segment.rsc +1 -1
  91. package/.next/standalone/.next/server/app-paths-manifest.json +7 -6
  92. package/.next/standalone/.next/server/chunks/138.js +1 -1
  93. package/.next/standalone/.next/server/chunks/182.js +9 -2
  94. package/.next/standalone/.next/server/chunks/219.js +1 -0
  95. package/.next/standalone/.next/server/chunks/471.js +13 -0
  96. package/.next/standalone/.next/server/chunks/741.js +2 -2
  97. package/.next/standalone/.next/server/chunks/900.js +7 -0
  98. package/.next/standalone/.next/server/middleware-build-manifest.js +1 -1
  99. package/.next/standalone/.next/server/middleware.js +2 -2
  100. package/.next/standalone/.next/server/next-font-manifest.js +1 -1
  101. package/.next/standalone/.next/server/next-font-manifest.json +1 -1
  102. package/.next/standalone/.next/server/pages/404.html +1 -1
  103. package/.next/standalone/.next/server/pages/500.html +2 -2
  104. package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
  105. package/.next/standalone/.next/server/server-reference-manifest.json +1 -1
  106. package/.next/standalone/.next/static/chunks/{702-8f4a71e9289e360c.js → 702-c4610efa55dfb155.js} +1 -1
  107. package/.next/standalone/.next/static/chunks/{794-e4409998c8ba5c29.js → 794-37dad9bbc14b04b8.js} +1 -1
  108. package/.next/standalone/.next/static/chunks/{852-6b2b2eefb2d99b28.js → 852-d8cad4b0d71288a2.js} +3 -3
  109. package/.next/standalone/.next/static/chunks/app/(dashboard)/layout-579c25ca675b41ac.js +1 -0
  110. package/.next/standalone/.next/static/chunks/app/(dashboard)/mitm/page-d25cf1803f6924ee.js +7 -0
  111. package/.next/standalone/.next/static/chunks/app/(dashboard)/{page-a4e7c4e324778903.js → page-5c09ac097fc0cc9b.js} +1 -1
  112. package/.next/standalone/.next/static/chunks/app/_global-error/{page-a4e7c4e324778903.js → page-5c09ac097fc0cc9b.js} +1 -1
  113. package/.next/standalone/.next/static/chunks/app/_not-found/{page-f6a07fd1289f84a5.js → page-038730efde50428c.js} +1 -1
  114. package/.next/standalone/.next/static/chunks/app/api/cli-tools/antigravity-mitm/alias/{route-a4e7c4e324778903.js → route-5c09ac097fc0cc9b.js} +1 -1
  115. package/.next/standalone/.next/static/chunks/app/api/cli-tools/antigravity-mitm/console-logs/{route-a4e7c4e324778903.js → route-5c09ac097fc0cc9b.js} +1 -1
  116. package/.next/standalone/.next/static/chunks/app/api/cli-tools/antigravity-mitm/logs/route-5c09ac097fc0cc9b.js +1 -0
  117. package/.next/standalone/.next/static/chunks/app/api/cli-tools/antigravity-mitm/route-5c09ac097fc0cc9b.js +1 -0
  118. package/.next/standalone/.next/static/chunks/app/api/cli-tools/antigravity-mitm/settings/route-5c09ac097fc0cc9b.js +1 -0
  119. package/.next/standalone/.next/static/chunks/app/api/cli-tools/claude-settings/route-5c09ac097fc0cc9b.js +1 -0
  120. package/.next/standalone/.next/static/chunks/app/api/cli-tools/codex-settings/route-5c09ac097fc0cc9b.js +1 -0
  121. package/.next/standalone/.next/static/chunks/app/api/cli-tools/copilot-settings/route-5c09ac097fc0cc9b.js +1 -0
  122. package/.next/standalone/.next/static/chunks/app/api/cli-tools/droid-settings/route-5c09ac097fc0cc9b.js +1 -0
  123. package/.next/standalone/.next/static/chunks/app/api/cli-tools/openclaw-settings/route-5c09ac097fc0cc9b.js +1 -0
  124. package/.next/standalone/.next/static/chunks/app/api/cli-tools/opencode-settings/route-5c09ac097fc0cc9b.js +1 -0
  125. package/.next/standalone/.next/static/chunks/app/api/keys/[id]/route-5c09ac097fc0cc9b.js +1 -0
  126. package/.next/standalone/.next/static/chunks/app/api/keys/route-5c09ac097fc0cc9b.js +1 -0
  127. package/.next/standalone/.next/static/chunks/app/api/locale/route-5c09ac097fc0cc9b.js +1 -0
  128. package/.next/standalone/.next/static/chunks/app/api/models/alias/route-5c09ac097fc0cc9b.js +1 -0
  129. package/.next/standalone/.next/static/chunks/app/api/models/route-5c09ac097fc0cc9b.js +1 -0
  130. package/.next/standalone/.next/static/chunks/app/api/providers/route-5c09ac097fc0cc9b.js +1 -0
  131. package/.next/standalone/.next/static/chunks/app/api/settings/route-5c09ac097fc0cc9b.js +1 -0
  132. package/.next/standalone/.next/static/chunks/app/api/version/route-5c09ac097fc0cc9b.js +1 -0
  133. package/.next/standalone/.next/static/chunks/app/{layout-6de9a5310276adf9.js → layout-6e491caa4df42293.js} +1 -1
  134. package/.next/standalone/.next/static/chunks/{main-9b410d84e10d7a77.js → main-842bf1ddb8ee9ec0.js} +2 -2
  135. package/.next/standalone/.next/static/chunks/{main-app-2ed2446a2e4f75e7.js → main-app-0fea626ed7ee1281.js} +1 -1
  136. package/.next/standalone/.next/static/chunks/next/dist/client/components/builtin/app-error-5c09ac097fc0cc9b.js +1 -0
  137. package/.next/standalone/.next/static/chunks/next/dist/client/components/builtin/forbidden-5c09ac097fc0cc9b.js +1 -0
  138. package/.next/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-89d8af6ad4f69554.js +1 -0
  139. package/.next/standalone/.next/static/chunks/next/dist/client/components/builtin/not-found-5c09ac097fc0cc9b.js +1 -0
  140. package/.next/standalone/.next/static/chunks/next/dist/client/components/builtin/unauthorized-5c09ac097fc0cc9b.js +1 -0
  141. package/.next/standalone/.next/static/rZAYFVGk5tWg3Az1gc9jl/_buildManifest.js +1 -0
  142. package/.next/standalone/node_modules/@next/env/package.json +1 -1
  143. package/.next/standalone/node_modules/next/dist/build/swc/index.js +1 -1
  144. package/.next/standalone/node_modules/next/dist/build/webpack-config.js +3 -3
  145. package/.next/standalone/node_modules/next/dist/compiled/http-proxy/index.js +5 -5
  146. package/.next/standalone/node_modules/next/dist/compiled/next-server/app-page-experimental.runtime.prod.js +3 -3
  147. package/.next/standalone/node_modules/next/dist/compiled/next-server/app-page-turbo-experimental.runtime.prod.js +12 -12
  148. package/.next/standalone/node_modules/next/dist/compiled/next-server/app-page-turbo.runtime.prod.js +3 -3
  149. package/.next/standalone/node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js +3 -3
  150. package/.next/standalone/node_modules/next/dist/compiled/next-server/app-route.runtime.prod.js +2 -2
  151. package/.next/standalone/node_modules/next/dist/compiled/next-server/pages-turbo.runtime.prod.js +2 -2
  152. package/.next/standalone/node_modules/next/dist/compiled/next-server/pages.runtime.prod.js +2 -2
  153. package/.next/standalone/node_modules/next/dist/server/app-render/action-handler.js +7 -11
  154. package/.next/standalone/node_modules/next/dist/server/base-server.js +22 -8
  155. package/.next/standalone/node_modules/next/dist/server/config-schema.js +0 -1
  156. package/.next/standalone/node_modules/next/dist/server/dev/hot-reloader-turbopack.js +1 -1
  157. package/.next/standalone/node_modules/next/dist/server/dev/hot-reloader-webpack.js +1 -1
  158. package/.next/standalone/node_modules/next/dist/server/image-optimizer.js +22 -148
  159. package/.next/standalone/node_modules/next/dist/server/lib/app-info-log.js +1 -1
  160. package/.next/standalone/node_modules/next/dist/server/lib/lru-cache.js +1 -2
  161. package/.next/standalone/node_modules/next/dist/server/lib/patch-fetch.js +6 -15
  162. package/.next/standalone/node_modules/next/dist/server/lib/router-server.js +3 -3
  163. package/.next/standalone/node_modules/next/dist/server/lib/router-utils/{block-cross-site-dev.js → block-cross-site.js} +17 -11
  164. package/.next/standalone/node_modules/next/dist/server/lib/start-server.js +1 -1
  165. package/.next/standalone/node_modules/next/dist/shared/lib/errors/canary-only-config-error.js +1 -1
  166. package/.next/standalone/node_modules/next/dist/shared/lib/image-config.js +0 -1
  167. package/.next/standalone/node_modules/next/dist/telemetry/anonymous-meta.js +1 -1
  168. package/.next/standalone/node_modules/next/dist/telemetry/events/version.js +2 -2
  169. package/.next/standalone/node_modules/next/package.json +16 -16
  170. package/.next/standalone/package.json +1 -1
  171. package/.next/standalone/server.js +1 -1
  172. package/.next/standalone/src/mitm/manager.js +51 -9
  173. package/bin/arouter.js +292 -0
  174. package/bin/arouter.mjs +264 -111
  175. package/bin/paths.js +23 -0
  176. package/bin/paths.mjs +23 -0
  177. package/package.json +1 -1
  178. package/scripts/postinstall.mjs +19 -23
  179. package/.next/standalone/.next/server/chunks/411.js +0 -1
  180. package/.next/standalone/.next/server/chunks/63.js +0 -13
  181. package/.next/standalone/.next/server/chunks/724.js +0 -7
  182. package/.next/standalone/.next/static/chunks/app/(dashboard)/layout-384bfa634ec14bbe.js +0 -1
  183. package/.next/standalone/.next/static/chunks/app/(dashboard)/mitm/page-3dca1ab0735aaa0f.js +0 -7
  184. package/.next/standalone/.next/static/chunks/app/api/cli-tools/antigravity-mitm/route-a4e7c4e324778903.js +0 -1
  185. package/.next/standalone/.next/static/chunks/app/api/cli-tools/antigravity-mitm/settings/route-a4e7c4e324778903.js +0 -1
  186. package/.next/standalone/.next/static/chunks/app/api/cli-tools/claude-settings/route-a4e7c4e324778903.js +0 -1
  187. package/.next/standalone/.next/static/chunks/app/api/cli-tools/codex-settings/route-a4e7c4e324778903.js +0 -1
  188. package/.next/standalone/.next/static/chunks/app/api/cli-tools/copilot-settings/route-a4e7c4e324778903.js +0 -1
  189. package/.next/standalone/.next/static/chunks/app/api/cli-tools/droid-settings/route-a4e7c4e324778903.js +0 -1
  190. package/.next/standalone/.next/static/chunks/app/api/cli-tools/openclaw-settings/route-a4e7c4e324778903.js +0 -1
  191. package/.next/standalone/.next/static/chunks/app/api/cli-tools/opencode-settings/route-a4e7c4e324778903.js +0 -1
  192. package/.next/standalone/.next/static/chunks/app/api/keys/[id]/route-a4e7c4e324778903.js +0 -1
  193. package/.next/standalone/.next/static/chunks/app/api/keys/route-a4e7c4e324778903.js +0 -1
  194. package/.next/standalone/.next/static/chunks/app/api/locale/route-a4e7c4e324778903.js +0 -1
  195. package/.next/standalone/.next/static/chunks/app/api/models/alias/route-a4e7c4e324778903.js +0 -1
  196. package/.next/standalone/.next/static/chunks/app/api/models/route-a4e7c4e324778903.js +0 -1
  197. package/.next/standalone/.next/static/chunks/app/api/providers/route-a4e7c4e324778903.js +0 -1
  198. package/.next/standalone/.next/static/chunks/app/api/settings/route-a4e7c4e324778903.js +0 -1
  199. package/.next/standalone/.next/static/chunks/app/api/version/route-a4e7c4e324778903.js +0 -1
  200. package/.next/standalone/.next/static/chunks/next/dist/client/components/builtin/app-error-a4e7c4e324778903.js +0 -1
  201. package/.next/standalone/.next/static/chunks/next/dist/client/components/builtin/forbidden-a4e7c4e324778903.js +0 -1
  202. package/.next/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-a42479e2ca7868a9.js +0 -1
  203. package/.next/standalone/.next/static/chunks/next/dist/client/components/builtin/not-found-a4e7c4e324778903.js +0 -1
  204. package/.next/standalone/.next/static/chunks/next/dist/client/components/builtin/unauthorized-a4e7c4e324778903.js +0 -1
  205. package/.next/standalone/.next/static/cn0nPxdvWWK5t_Uw1V17t/_buildManifest.js +0 -1
  206. package/.next/standalone/node_modules/next/dist/server/lib/disk-lru-cache.external.js +0 -57
  207. package/.next/standalone/node_modules/next/dist/server/lib/postponed-request-body.js +0 -64
  208. /package/.next/standalone/.next/static/{cn0nPxdvWWK5t_Uw1V17t → rZAYFVGk5tWg3Az1gc9jl}/_ssgManifest.js +0 -0
@@ -9,7 +9,7 @@ const currentPort = parseInt(process.env.PORT, 10) || 3000
9
9
  const hostname = process.env.HOSTNAME || '0.0.0.0'
10
10
 
11
11
  let keepAliveTimeout = parseInt(process.env.KEEP_ALIVE_TIMEOUT, 10)
12
- const nextConfig = {"env":{},"typescript":{"ignoreBuildErrors":false},"typedRoutes":false,"distDir":"./.next","cleanDistDir":true,"assetPrefix":"","cacheMaxMemorySize":52428800,"configOrigin":"next.config.mjs","useFileSystemPublicRoutes":true,"generateEtags":true,"pageExtensions":["tsx","ts","jsx","js"],"poweredByHeader":true,"compress":true,"images":{"deviceSizes":[640,750,828,1080,1200,1920,2048,3840],"imageSizes":[32,48,64,96,128,256,384],"path":"/_next/image","loader":"default","loaderFile":"","domains":[],"disableStaticImages":false,"minimumCacheTTL":14400,"formats":["image/webp"],"maximumRedirects":3,"maximumResponseBody":50000000,"dangerouslyAllowLocalIP":false,"dangerouslyAllowSVG":false,"contentSecurityPolicy":"script-src 'none'; frame-src 'none'; sandbox;","contentDispositionType":"attachment","localPatterns":[{"pathname":"**","search":""}],"remotePatterns":[],"qualities":[75],"unoptimized":true},"devIndicators":{"position":"bottom-left"},"onDemandEntries":{"maxInactiveAge":60000,"pagesBufferLength":5},"basePath":"","sassOptions":{},"trailingSlash":false,"i18n":null,"productionBrowserSourceMaps":false,"excludeDefaultMomentLocales":true,"reactProductionProfiling":false,"reactStrictMode":null,"reactMaxHeadersLength":6000,"httpAgentOptions":{"keepAlive":true},"logging":{},"compiler":{},"expireTime":31536000,"staticPageGenerationTimeout":60,"output":"standalone","modularizeImports":{"@mui/icons-material":{"transform":"@mui/icons-material/{{member}}"},"lodash":{"transform":"lodash/{{member}}"}},"outputFileTracingRoot":"/Users/nip/WORKSPACE/02.SOURCE/ICHECK/01. PROJECT/AI CENTER/arouter","cacheComponents":false,"cacheLife":{"default":{"stale":300,"revalidate":900,"expire":4294967294},"seconds":{"stale":30,"revalidate":1,"expire":60},"minutes":{"stale":300,"revalidate":60,"expire":3600},"hours":{"stale":300,"revalidate":3600,"expire":86400},"days":{"stale":300,"revalidate":86400,"expire":604800},"weeks":{"stale":300,"revalidate":604800,"expire":2592000},"max":{"stale":300,"revalidate":2592000,"expire":31536000}},"cacheHandlers":{},"experimental":{"useSkewCookie":false,"cssChunking":true,"multiZoneDraftMode":false,"appNavFailHandling":false,"prerenderEarlyExit":true,"serverMinification":true,"linkNoTouchStart":false,"caseSensitiveRoutes":false,"dynamicOnHover":false,"preloadEntriesOnStart":true,"clientRouterFilter":true,"clientRouterFilterRedirects":false,"fetchCacheKeyPrefix":"","proxyPrefetch":"flexible","optimisticClientCache":true,"manualClientBasePath":false,"cpus":7,"memoryBasedWorkersCount":false,"imgOptConcurrency":null,"imgOptTimeoutInSeconds":7,"imgOptMaxInputPixels":268402689,"imgOptSequentialRead":null,"imgOptSkipMetadata":null,"isrFlushToDisk":true,"workerThreads":false,"optimizeCss":false,"nextScriptWorkers":false,"scrollRestoration":false,"externalDir":false,"disableOptimizedLoading":false,"gzipSize":true,"craCompat":false,"esmExternals":true,"fullySpecified":false,"swcTraceProfiling":false,"forceSwcTransforms":false,"largePageDataBytes":128000,"typedEnv":false,"parallelServerCompiles":false,"parallelServerBuildTraces":false,"ppr":false,"authInterrupts":false,"webpackMemoryOptimizations":false,"optimizeServerReact":true,"viewTransition":false,"removeUncaughtErrorAndRejectionListeners":false,"validateRSCRequestHeaders":false,"staleTimes":{"dynamic":0,"static":300},"reactDebugChannel":false,"serverComponentsHmrCache":true,"staticGenerationMaxConcurrency":8,"staticGenerationMinPagesPerWorker":25,"transitionIndicator":false,"inlineCss":false,"useCache":false,"globalNotFound":false,"browserDebugInfoInTerminal":false,"lockDistDir":true,"isolatedDevBuild":true,"proxyClientMaxBodySize":10485760,"hideLogsAfterAbort":false,"mcpServer":true,"turbopackFileSystemCacheForDev":true,"turbopackFileSystemCacheForBuild":false,"turbopackInferModuleSideEffects":false,"optimizePackageImports":["lucide-react","date-fns","lodash-es","ramda","antd","react-bootstrap","ahooks","@ant-design/icons","@headlessui/react","@headlessui-float/react","@heroicons/react/20/solid","@heroicons/react/24/solid","@heroicons/react/24/outline","@visx/visx","@tremor/react","rxjs","@mui/material","@mui/icons-material","recharts","react-use","effect","@effect/schema","@effect/platform","@effect/platform-node","@effect/platform-browser","@effect/platform-bun","@effect/sql","@effect/sql-mssql","@effect/sql-mysql2","@effect/sql-pg","@effect/sql-sqlite-node","@effect/sql-sqlite-bun","@effect/sql-sqlite-wasm","@effect/sql-sqlite-react-native","@effect/rpc","@effect/rpc-http","@effect/typeclass","@effect/experimental","@effect/opentelemetry","@material-ui/core","@material-ui/icons","@tabler/icons-react","mui-core","react-icons/ai","react-icons/bi","react-icons/bs","react-icons/cg","react-icons/ci","react-icons/di","react-icons/fa","react-icons/fa6","react-icons/fc","react-icons/fi","react-icons/gi","react-icons/go","react-icons/gr","react-icons/hi","react-icons/hi2","react-icons/im","react-icons/io","react-icons/io5","react-icons/lia","react-icons/lib","react-icons/lu","react-icons/md","react-icons/pi","react-icons/ri","react-icons/rx","react-icons/si","react-icons/sl","react-icons/tb","react-icons/tfi","react-icons/ti","react-icons/vsc","react-icons/wi"],"trustHostHeader":false,"isExperimentalCompile":false},"htmlLimitedBots":"[\\w-]+-Google|Google-[\\w-]+|Chrome-Lighthouse|Slurp|DuckDuckBot|baiduspider|yandex|sogou|bitlybot|tumblr|vkShare|quora link preview|redditbot|ia_archiver|Bingbot|BingPreview|applebot|facebookexternalhit|facebookcatalog|Twitterbot|LinkedInBot|Slackbot|Discordbot|WhatsApp|SkypeUriPreview|Yeti|googleweblight","bundlePagesRouterDependencies":false,"configFileName":"next.config.mjs","turbopack":{"root":"/Users/nip/WORKSPACE/02.SOURCE/ICHECK/01. PROJECT/AI CENTER/arouter"},"distDirRoot":".next","_originalRewrites":{"beforeFiles":[],"afterFiles":[{"source":"/v1/v1/:path*","destination":"/api/v1/:path*"},{"source":"/v1/v1","destination":"/api/v1"},{"source":"/codex/:path*","destination":"/api/v1/responses"},{"source":"/v1/:path*","destination":"/api/v1/:path*"},{"source":"/v1","destination":"/api/v1"}],"fallback":[]}}
12
+ const nextConfig = {"env":{},"typescript":{"ignoreBuildErrors":false},"typedRoutes":false,"distDir":"./.next","cleanDistDir":true,"assetPrefix":"","cacheMaxMemorySize":52428800,"configOrigin":"next.config.mjs","useFileSystemPublicRoutes":true,"generateEtags":true,"pageExtensions":["tsx","ts","jsx","js"],"poweredByHeader":true,"compress":true,"images":{"deviceSizes":[640,750,828,1080,1200,1920,2048,3840],"imageSizes":[32,48,64,96,128,256,384],"path":"/_next/image","loader":"default","loaderFile":"","domains":[],"disableStaticImages":false,"minimumCacheTTL":14400,"formats":["image/webp"],"maximumRedirects":3,"maximumResponseBody":50000000,"dangerouslyAllowLocalIP":false,"dangerouslyAllowSVG":false,"contentSecurityPolicy":"script-src 'none'; frame-src 'none'; sandbox;","contentDispositionType":"attachment","localPatterns":[{"pathname":"**","search":""}],"remotePatterns":[],"qualities":[75],"unoptimized":true},"devIndicators":{"position":"bottom-left"},"onDemandEntries":{"maxInactiveAge":60000,"pagesBufferLength":5},"basePath":"","sassOptions":{},"trailingSlash":false,"i18n":null,"productionBrowserSourceMaps":false,"excludeDefaultMomentLocales":true,"reactProductionProfiling":false,"reactStrictMode":null,"reactMaxHeadersLength":6000,"httpAgentOptions":{"keepAlive":true},"logging":{},"compiler":{},"expireTime":31536000,"staticPageGenerationTimeout":60,"output":"standalone","modularizeImports":{"@mui/icons-material":{"transform":"@mui/icons-material/{{member}}"},"lodash":{"transform":"lodash/{{member}}"}},"outputFileTracingRoot":"/Users/nip/Desktop/WORKSPACE/iCheck/iCheck.AI.Workflows/arouter","cacheComponents":false,"cacheLife":{"default":{"stale":300,"revalidate":900,"expire":4294967294},"seconds":{"stale":30,"revalidate":1,"expire":60},"minutes":{"stale":300,"revalidate":60,"expire":3600},"hours":{"stale":300,"revalidate":3600,"expire":86400},"days":{"stale":300,"revalidate":86400,"expire":604800},"weeks":{"stale":300,"revalidate":604800,"expire":2592000},"max":{"stale":300,"revalidate":2592000,"expire":31536000}},"cacheHandlers":{},"experimental":{"useSkewCookie":false,"cssChunking":true,"multiZoneDraftMode":false,"appNavFailHandling":false,"prerenderEarlyExit":true,"serverMinification":true,"linkNoTouchStart":false,"caseSensitiveRoutes":false,"dynamicOnHover":false,"preloadEntriesOnStart":true,"clientRouterFilter":true,"clientRouterFilterRedirects":false,"fetchCacheKeyPrefix":"","proxyPrefetch":"flexible","optimisticClientCache":true,"manualClientBasePath":false,"cpus":9,"memoryBasedWorkersCount":false,"imgOptConcurrency":null,"imgOptTimeoutInSeconds":7,"imgOptMaxInputPixels":268402689,"imgOptSequentialRead":null,"imgOptSkipMetadata":null,"isrFlushToDisk":true,"workerThreads":false,"optimizeCss":false,"nextScriptWorkers":false,"scrollRestoration":false,"externalDir":false,"disableOptimizedLoading":false,"gzipSize":true,"craCompat":false,"esmExternals":true,"fullySpecified":false,"swcTraceProfiling":false,"forceSwcTransforms":false,"largePageDataBytes":128000,"typedEnv":false,"parallelServerCompiles":false,"parallelServerBuildTraces":false,"ppr":false,"authInterrupts":false,"webpackMemoryOptimizations":false,"optimizeServerReact":true,"viewTransition":false,"removeUncaughtErrorAndRejectionListeners":false,"validateRSCRequestHeaders":false,"staleTimes":{"dynamic":0,"static":300},"reactDebugChannel":false,"serverComponentsHmrCache":true,"staticGenerationMaxConcurrency":8,"staticGenerationMinPagesPerWorker":25,"transitionIndicator":false,"inlineCss":false,"useCache":false,"globalNotFound":false,"browserDebugInfoInTerminal":false,"lockDistDir":true,"isolatedDevBuild":true,"proxyClientMaxBodySize":10485760,"hideLogsAfterAbort":false,"mcpServer":true,"turbopackFileSystemCacheForDev":true,"turbopackFileSystemCacheForBuild":false,"turbopackInferModuleSideEffects":false,"optimizePackageImports":["lucide-react","date-fns","lodash-es","ramda","antd","react-bootstrap","ahooks","@ant-design/icons","@headlessui/react","@headlessui-float/react","@heroicons/react/20/solid","@heroicons/react/24/solid","@heroicons/react/24/outline","@visx/visx","@tremor/react","rxjs","@mui/material","@mui/icons-material","recharts","react-use","effect","@effect/schema","@effect/platform","@effect/platform-node","@effect/platform-browser","@effect/platform-bun","@effect/sql","@effect/sql-mssql","@effect/sql-mysql2","@effect/sql-pg","@effect/sql-sqlite-node","@effect/sql-sqlite-bun","@effect/sql-sqlite-wasm","@effect/sql-sqlite-react-native","@effect/rpc","@effect/rpc-http","@effect/typeclass","@effect/experimental","@effect/opentelemetry","@material-ui/core","@material-ui/icons","@tabler/icons-react","mui-core","react-icons/ai","react-icons/bi","react-icons/bs","react-icons/cg","react-icons/ci","react-icons/di","react-icons/fa","react-icons/fa6","react-icons/fc","react-icons/fi","react-icons/gi","react-icons/go","react-icons/gr","react-icons/hi","react-icons/hi2","react-icons/im","react-icons/io","react-icons/io5","react-icons/lia","react-icons/lib","react-icons/lu","react-icons/md","react-icons/pi","react-icons/ri","react-icons/rx","react-icons/si","react-icons/sl","react-icons/tb","react-icons/tfi","react-icons/ti","react-icons/vsc","react-icons/wi"],"trustHostHeader":false,"isExperimentalCompile":false},"htmlLimitedBots":"[\\w-]+-Google|Google-[\\w-]+|Chrome-Lighthouse|Slurp|DuckDuckBot|baiduspider|yandex|sogou|bitlybot|tumblr|vkShare|quora link preview|redditbot|ia_archiver|Bingbot|BingPreview|applebot|facebookexternalhit|facebookcatalog|Twitterbot|LinkedInBot|Slackbot|Discordbot|WhatsApp|SkypeUriPreview|Yeti|googleweblight","bundlePagesRouterDependencies":false,"configFileName":"next.config.mjs","turbopack":{"root":"/Users/nip/Desktop/WORKSPACE/iCheck/iCheck.AI.Workflows/arouter"},"distDirRoot":".next","_originalRewrites":{"beforeFiles":[],"afterFiles":[{"source":"/v1/v1/:path*","destination":"/api/v1/:path*"},{"source":"/v1/v1","destination":"/api/v1"},{"source":"/codex/:path*","destination":"/api/v1/responses"},{"source":"/v1/:path*","destination":"/api/v1/:path*"},{"source":"/v1","destination":"/api/v1"}],"fallback":[]}}
13
13
 
14
14
  process.env.__NEXT_PRIVATE_STANDALONE_CONFIG = JSON.stringify(nextConfig)
15
15
 
@@ -75,22 +75,39 @@ function isProcessAlive(pid) {
75
75
  process.kill(pid, 0);
76
76
  return true;
77
77
  } catch (err) {
78
- return err.code === "EACCES";
78
+ return err.code === "EACCES" || err.code === "EPERM";
79
79
  }
80
80
  }
81
81
 
82
- function killProcess(pid, force = false, sudoPassword = null) {
82
+ async function killProcess(pid, force = false, sudoPassword = null) {
83
83
  if (IS_WIN) {
84
84
  const flag = force ? "/F " : "";
85
- exec(`taskkill ${flag}/PID ${pid}`, { windowsHide: true }, () => { });
85
+ return new Promise(r => exec(`taskkill ${flag}/PID ${pid}`, { windowsHide: true }, r));
86
86
  } else {
87
- const sig = force ? "SIGKILL" : "SIGTERM";
88
- const cmd = `pkill -${sig} -P ${pid} 2>/dev/null; kill -${sig} ${pid} 2>/dev/null`;
87
+ const sig = force ? "KILL" : "TERM";
88
+ const cmd = `pkill -${sig} -P ${pid} 2>/dev/null || true; kill -${sig} ${pid} 2>/dev/null || true`;
89
89
  if (sudoPassword) {
90
90
  const { execWithPassword } = require("./dns/dnsConfig");
91
- execWithPassword(cmd, sudoPassword).catch(() => exec(cmd, () => { }));
91
+ const fs = require("fs");
92
+ const logFile = require("os").homedir() + "/.arouter/mitm_kill.log";
93
+ try {
94
+ log(`Executing sudo kill for PID ${pid}...`);
95
+ fs.appendFileSync(logFile, `\n\n[${new Date().toISOString()}] Attempting kill for PID ${pid} with force=${force}\nCmd: ${cmd}\n`);
96
+ const out = await execWithPassword(cmd, sudoPassword);
97
+ fs.appendFileSync(logFile, `execWithPassword SUCCESS: ${out}\n`);
98
+ log(`Sudo kill output: ${out}`);
99
+ } catch (e) {
100
+ fs.appendFileSync(logFile, `execWithPassword FAILED: ${e.message}\n`);
101
+ err(`Sudo kill failed: ${e.message}`);
102
+ // Fallback: try raw exec with echo
103
+ return new Promise(r => exec(`echo "${sudoPassword.replace(/"/g, '\\"')}" | sudo -S sh -c "${cmd}"`, (cmdErr, stdout, stderr) => {
104
+ fs.appendFileSync(logFile, `Fallback Result -> err: ${cmdErr?.message}, stdout: ${stdout}, stderr: ${stderr}\n`);
105
+ if (cmdErr) err(`Raw sudo kill failed too: ${stderr || cmdErr.message}`);
106
+ r();
107
+ }));
108
+ }
92
109
  } else {
93
- exec(cmd, () => { });
110
+ return new Promise(r => exec(cmd, r));
94
111
  }
95
112
  }
96
113
  }
@@ -276,6 +293,15 @@ async function getMitmStatus() {
276
293
  } catch { /* ignore */ }
277
294
  }
278
295
 
296
+ if (!running) {
297
+ const health = await pollMitmHealth(1000, MITM_PORT);
298
+ if (health && health.ok) {
299
+ running = true;
300
+ pid = health.pid;
301
+ try { fs.writeFileSync(PID_FILE, String(pid)); } catch {}
302
+ }
303
+ }
304
+
279
305
  const dnsStatus = checkAllDNSStatus();
280
306
  const rootCACertPath = path.join(MITM_DIR, "rootCA.crt");
281
307
  const certExists = fs.existsSync(rootCACertPath);
@@ -350,6 +376,18 @@ async function startServer(apiKey, sudoPassword) {
350
376
  } catch { /* ignore */ }
351
377
  }
352
378
 
379
+ if (!serverProcess || serverProcess.killed) {
380
+ const health = await pollMitmHealth(1000, MITM_PORT);
381
+ if (health && health.ok) {
382
+ serverPid = health.pid;
383
+ log(`♻️ Found running MITM server (PID: ${health.pid}). Adopting it.`);
384
+ try { fs.writeFileSync(PID_FILE, String(serverPid)); } catch {}
385
+ await saveMitmSettings(true, sudoPassword);
386
+ if (sudoPassword) setCachedPassword(sudoPassword);
387
+ return { running: true, pid: serverPid };
388
+ }
389
+ }
390
+
353
391
  if (serverProcess && !serverProcess.killed) {
354
392
  throw new Error("MITM server is already running");
355
393
  }
@@ -520,9 +558,13 @@ async function stopServer(sudoPassword) {
520
558
 
521
559
  if (pidToKill && isProcessAlive(pidToKill)) {
522
560
  log(`Killing server (PID: ${pidToKill})...`);
523
- killProcess(pidToKill, false, password);
561
+ await killProcess(pidToKill, false, password);
524
562
  await new Promise(r => setTimeout(r, 1000));
525
- if (isProcessAlive(pidToKill)) killProcess(pidToKill, true, password);
563
+ if (isProcessAlive(pidToKill)) await killProcess(pidToKill, true, password);
564
+ await new Promise(r => setTimeout(r, 1000));
565
+ if (isProcessAlive(pidToKill)) {
566
+ throw new Error("Cannot kill server process. Sudo password may be missing or incorrect.");
567
+ }
526
568
  }
527
569
  serverProcess = null;
528
570
  serverPid = null;
package/bin/arouter.js ADDED
@@ -0,0 +1,292 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { spawn, execSync } from "child_process";
4
+ import { existsSync, readFileSync, writeFileSync, unlinkSync, openSync } from "fs";
5
+ import { resolve } from "path";
6
+ import { platform } from "os";
7
+ import { createServer } from "net";
8
+ import { PROJECT_ROOT, DATA_DIR, PID_FILE, LOG_FILE, PORT, DASHBOARD_URL } from "./paths.js";
9
+
10
+ // ─── Helpers ────────────────────────────────────────────────────────────
11
+
12
+ const IS_WIN = platform() === "win32";
13
+ const GREEN = "\x1b[32m";
14
+ const YELLOW = "\x1b[33m";
15
+ const RED = "\x1b[31m";
16
+ const CYAN = "\x1b[36m";
17
+ const DIM = "\x1b[2m";
18
+ const BOLD = "\x1b[1m";
19
+ const RESET = "\x1b[0m";
20
+
21
+ function log(msg) { console.log(`${DIM}[arouter]${RESET} ${msg}`); }
22
+ function success(msg) { console.log(`${GREEN}✔${RESET} ${msg}`); }
23
+ function warn(msg) { console.log(`${YELLOW}⚠${RESET} ${msg}`); }
24
+ function error(msg) { console.error(`${RED}✖${RESET} ${msg}`); }
25
+
26
+ /** Cross-platform port check using Node.js net module */
27
+ function isPortInUse(port) {
28
+ return new Promise((resolve) => {
29
+ const server = createServer();
30
+ server.once("error", (err) => {
31
+ if (err.code === "EADDRINUSE") resolve(true);
32
+ else resolve(false);
33
+ });
34
+ server.once("listening", () => {
35
+ server.close(() => resolve(false));
36
+ });
37
+ server.listen(port, "0.0.0.0");
38
+ });
39
+ }
40
+
41
+ function getRunningPid() {
42
+ if (!existsSync(PID_FILE)) return null;
43
+ const pid = parseInt(readFileSync(PID_FILE, "utf-8").trim(), 10);
44
+ if (isNaN(pid)) return null;
45
+ try {
46
+ process.kill(pid, 0); // check if alive (works on all platforms)
47
+ return pid;
48
+ } catch {
49
+ // stale PID file
50
+ try { unlinkSync(PID_FILE); } catch { /* ignore */ }
51
+ return null;
52
+ }
53
+ }
54
+
55
+ function waitForServer(timeoutMs = 60000) {
56
+ return new Promise((resolve, reject) => {
57
+ const start = Date.now();
58
+ const check = () => {
59
+ if (Date.now() - start > timeoutMs) {
60
+ return reject(new Error("Server startup timed out"));
61
+ }
62
+ import("http").then(({ default: http }) => {
63
+ const req = http.get(`http://localhost:${PORT}`, (res) => {
64
+ res.resume();
65
+ resolve();
66
+ });
67
+ req.on("error", () => setTimeout(check, 500));
68
+ req.setTimeout(2000, () => { req.destroy(); setTimeout(check, 500); });
69
+ });
70
+ };
71
+ check();
72
+ });
73
+ }
74
+
75
+ /** Cross-platform: get npm executable name */
76
+ function npmCommand() {
77
+ return IS_WIN ? "npm.cmd" : "npm";
78
+ }
79
+
80
+ // ─── Commands ───────────────────────────────────────────────────────────
81
+
82
+ async function buildIfNeeded() {
83
+ const standaloneServer = resolve(PROJECT_ROOT, ".next/standalone/server.js");
84
+ if (existsSync(standaloneServer)) return;
85
+
86
+ log("First run — building production bundle...");
87
+ log(`${DIM}This will take a minute, please wait...${RESET}`);
88
+
89
+ try {
90
+ execSync(`${npmCommand()} run build`, {
91
+ cwd: PROJECT_ROOT,
92
+ stdio: "inherit",
93
+ env: { ...process.env, NODE_ENV: "production" },
94
+ shell: true,
95
+ });
96
+ success("Build complete!");
97
+ } catch (e) {
98
+ error("Build failed. Check the output above.");
99
+ process.exit(1);
100
+ }
101
+ }
102
+
103
+ async function startServer() {
104
+ const pid = getRunningPid();
105
+ if (pid) {
106
+ success(`aRouter is already running ${DIM}(PID: ${pid})${RESET}`);
107
+ console.log();
108
+ console.log(` ${BOLD}Dashboard${RESET} ${CYAN}${DASHBOARD_URL}${RESET}`);
109
+ console.log();
110
+ return;
111
+ }
112
+
113
+ const portBusy = await isPortInUse(PORT);
114
+ if (portBusy) {
115
+ error(`Port ${PORT} is already in use by another process.`);
116
+ log(`Stop the other process or change the port.`);
117
+ process.exit(1);
118
+ }
119
+
120
+ await buildIfNeeded();
121
+
122
+ log("Starting aRouter...");
123
+
124
+ const logFd = openSync(LOG_FILE, "a");
125
+
126
+ // Cross-platform: use node directly to run server.js
127
+ const serverScript = resolve(PROJECT_ROOT, ".next/standalone/server.js");
128
+ const child = spawn(process.execPath, [serverScript], {
129
+ cwd: PROJECT_ROOT,
130
+ detached: !IS_WIN, // detached not supported on Windows the same way
131
+ stdio: ["ignore", logFd, logFd],
132
+ env: {
133
+ ...process.env,
134
+ NODE_ENV: "production",
135
+ PORT: String(PORT),
136
+ HOSTNAME: "0.0.0.0",
137
+ },
138
+ // Windows: use windowsHide to hide console window
139
+ ...(IS_WIN ? { windowsHide: true } : {}),
140
+ });
141
+
142
+ writeFileSync(PID_FILE, String(child.pid));
143
+ child.unref();
144
+
145
+ // Wait for server to be ready
146
+ try {
147
+ process.stdout.write(` Waiting for server `);
148
+ await waitForServer(60000);
149
+ process.stdout.write(`${GREEN}ready!${RESET}\n`);
150
+ } catch {
151
+ process.stdout.write(`${YELLOW}(timeout — check logs)${RESET}\n`);
152
+ }
153
+
154
+ console.log();
155
+ console.log(` ${GREEN}${BOLD}aRouter is running!${RESET}`);
156
+ console.log();
157
+ console.log(` ${BOLD}Dashboard${RESET} ${CYAN}${DASHBOARD_URL}${RESET}`);
158
+ console.log(` ${BOLD}API${RESET} ${CYAN}${DASHBOARD_URL}/v1${RESET}`);
159
+ console.log(` ${BOLD}PID${RESET} ${DIM}${child.pid}${RESET}`);
160
+ console.log(` ${BOLD}Logs${RESET} ${DIM}${LOG_FILE}${RESET}`);
161
+ console.log();
162
+ console.log(` ${DIM}Run ${RESET}arouter stop${DIM} to stop the server.${RESET}`);
163
+ console.log();
164
+ }
165
+
166
+ function stopServer() {
167
+ const pid = getRunningPid();
168
+ if (!pid) {
169
+ warn("aRouter is not running.");
170
+ return;
171
+ }
172
+
173
+ log(`Stopping aRouter (PID: ${pid})...`);
174
+ try {
175
+ if (IS_WIN) {
176
+ // Windows: use taskkill for tree kill
177
+ execSync(`taskkill /PID ${pid} /T /F`, { stdio: "ignore", shell: true });
178
+ } else {
179
+ process.kill(pid, "SIGTERM");
180
+ // Wait a bit then force kill if needed
181
+ setTimeout(() => {
182
+ try {
183
+ process.kill(pid, 0);
184
+ process.kill(pid, "SIGKILL");
185
+ } catch { /* already dead */ }
186
+ }, 3000);
187
+ }
188
+ } catch (e) {
189
+ warn(`Could not kill process: ${e.message}`);
190
+ }
191
+
192
+ try { unlinkSync(PID_FILE); } catch { /* ignore */ }
193
+ success("aRouter stopped.");
194
+ }
195
+
196
+ function showStatus() {
197
+ const pid = getRunningPid();
198
+ if (pid) {
199
+ success(`aRouter is running ${DIM}(PID: ${pid})${RESET}`);
200
+ console.log(` ${BOLD}Dashboard${RESET} ${CYAN}${DASHBOARD_URL}${RESET}`);
201
+ } else {
202
+ warn("aRouter is not running.");
203
+ }
204
+ }
205
+
206
+ function showLogs() {
207
+ if (!existsSync(LOG_FILE)) {
208
+ warn("No log file found. Start the server first.");
209
+ return;
210
+ }
211
+
212
+ // Tail last 50 lines
213
+ try {
214
+ const content = readFileSync(LOG_FILE, "utf-8");
215
+ const lines = content.split("\n").slice(-50);
216
+ console.log(lines.join("\n"));
217
+ } catch (e) {
218
+ error(`Could not read logs: ${e.message}`);
219
+ }
220
+ }
221
+
222
+ async function restartServer() {
223
+ stopServer();
224
+ // Wait for port release
225
+ await new Promise(r => setTimeout(r, 1500));
226
+ await startServer();
227
+ }
228
+
229
+ function showHelp() {
230
+ console.log();
231
+ console.log(` ${BOLD}aRouter${RESET} — AI Model Router & MITM Proxy`);
232
+ console.log();
233
+ console.log(` ${BOLD}Usage:${RESET}`);
234
+ console.log(` ${CYAN}arouter${RESET} Start the server (background)`);
235
+ console.log(` ${CYAN}arouter start${RESET} Same as above`);
236
+ console.log(` ${CYAN}arouter stop${RESET} Stop the server`);
237
+ console.log(` ${CYAN}arouter restart${RESET} Restart the server`);
238
+ console.log(` ${CYAN}arouter status${RESET} Show server status`);
239
+ console.log(` ${CYAN}arouter logs${RESET} Show recent logs`);
240
+ console.log(` ${CYAN}arouter dev${RESET} Run in foreground (dev mode)`);
241
+ console.log(` ${CYAN}arouter build${RESET} Force rebuild`);
242
+ console.log(` ${CYAN}arouter help${RESET} Show this help`);
243
+ console.log();
244
+ console.log(` ${BOLD}Data:${RESET} ${DIM}${DATA_DIR}${RESET}`);
245
+ console.log(` ${BOLD}Port:${RESET} ${DIM}${PORT}${RESET}`);
246
+ console.log();
247
+ }
248
+
249
+ function devMode() {
250
+ log("Starting in dev mode (foreground)...");
251
+ const child = spawn(npmCommand(), ["run", "dev"], {
252
+ cwd: PROJECT_ROOT,
253
+ stdio: "inherit",
254
+ env: { ...process.env },
255
+ shell: IS_WIN,
256
+ });
257
+ child.on("exit", (code) => process.exit(code || 0));
258
+ }
259
+
260
+ async function forceBuild() {
261
+ log("Force rebuilding...");
262
+ const nextDir = resolve(PROJECT_ROOT, ".next");
263
+ try {
264
+ if (IS_WIN) {
265
+ execSync(`rmdir /s /q "${nextDir}"`, { cwd: PROJECT_ROOT, shell: true, stdio: "ignore" });
266
+ } else {
267
+ execSync(`rm -rf "${nextDir}"`, { cwd: PROJECT_ROOT, stdio: "ignore" });
268
+ }
269
+ } catch { /* ignore */ }
270
+ await buildIfNeeded();
271
+ }
272
+
273
+ // ─── Main ───────────────────────────────────────────────────────────────
274
+
275
+ const command = process.argv[2] || "start";
276
+
277
+ switch (command) {
278
+ case "start": await startServer(); break;
279
+ case "stop": stopServer(); break;
280
+ case "restart": await restartServer(); break;
281
+ case "status": showStatus(); break;
282
+ case "logs": showLogs(); break;
283
+ case "dev": devMode(); break;
284
+ case "build": await forceBuild(); break;
285
+ case "help":
286
+ case "--help":
287
+ case "-h": showHelp(); break;
288
+ default:
289
+ error(`Unknown command: ${command}`);
290
+ showHelp();
291
+ process.exit(1);
292
+ }