9router 0.2.71 → 0.2.73

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 (455) hide show
  1. package/app/.next/BUILD_ID +1 -1
  2. package/app/.next/app-path-routes-manifest.json +42 -40
  3. package/app/.next/build-manifest.json +2 -2
  4. package/app/.next/prerender-manifest.json +3 -3
  5. package/app/.next/routes-manifest.json +12 -0
  6. package/app/.next/server/app/(dashboard)/dashboard/cli-tools/page_client-reference-manifest.js +1 -1
  7. package/app/.next/server/app/(dashboard)/dashboard/combos/page_client-reference-manifest.js +1 -1
  8. package/app/.next/server/app/(dashboard)/dashboard/endpoint/page_client-reference-manifest.js +1 -1
  9. package/app/.next/server/app/(dashboard)/dashboard/page_client-reference-manifest.js +1 -1
  10. package/app/.next/server/app/(dashboard)/dashboard/profile/page.js +1 -1
  11. package/app/.next/server/app/(dashboard)/dashboard/profile/page_client-reference-manifest.js +1 -1
  12. package/app/.next/server/app/(dashboard)/dashboard/providers/[id]/page.js +1 -1
  13. package/app/.next/server/app/(dashboard)/dashboard/providers/[id]/page_client-reference-manifest.js +1 -1
  14. package/app/.next/server/app/(dashboard)/dashboard/providers/new/page_client-reference-manifest.js +1 -1
  15. package/app/.next/server/app/(dashboard)/dashboard/providers/page_client-reference-manifest.js +1 -1
  16. package/app/.next/server/app/(dashboard)/dashboard/translator/page_client-reference-manifest.js +1 -1
  17. package/app/.next/server/app/(dashboard)/dashboard/usage/page.js +2 -2
  18. package/app/.next/server/app/(dashboard)/dashboard/usage/page_client-reference-manifest.js +1 -1
  19. package/app/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  20. package/app/.next/server/app/_global-error.html +2 -2
  21. package/app/.next/server/app/_global-error.rsc +1 -1
  22. package/app/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  23. package/app/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  24. package/app/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  25. package/app/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  26. package/app/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  27. package/app/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  28. package/app/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  29. package/app/.next/server/app/_not-found.html +1 -1
  30. package/app/.next/server/app/_not-found.rsc +3 -3
  31. package/app/.next/server/app/_not-found.segments/_full.segment.rsc +3 -3
  32. package/app/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  33. package/app/.next/server/app/_not-found.segments/_index.segment.rsc +3 -3
  34. package/app/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  35. package/app/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  36. package/app/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  37. package/app/.next/server/app/api/auth/login/route.js +1 -1
  38. package/app/.next/server/app/api/auth/login/route_client-reference-manifest.js +1 -1
  39. package/app/.next/server/app/api/auth/logout/route_client-reference-manifest.js +1 -1
  40. package/app/.next/server/app/api/cli-tools/antigravity-mitm/alias/route.js +2 -2
  41. package/app/.next/server/app/api/cli-tools/antigravity-mitm/alias/route_client-reference-manifest.js +1 -1
  42. package/app/.next/server/app/api/cli-tools/antigravity-mitm/route.js +4 -5
  43. package/app/.next/server/app/api/cli-tools/antigravity-mitm/route_client-reference-manifest.js +1 -1
  44. package/app/.next/server/app/api/cli-tools/claude-settings/route.js +2 -2
  45. package/app/.next/server/app/api/cli-tools/claude-settings/route_client-reference-manifest.js +1 -1
  46. package/app/.next/server/app/api/cli-tools/codex-settings/route.js +1 -1
  47. package/app/.next/server/app/api/cli-tools/codex-settings/route_client-reference-manifest.js +1 -1
  48. package/app/.next/server/app/api/cli-tools/droid-settings/route.js +2 -2
  49. package/app/.next/server/app/api/cli-tools/droid-settings/route_client-reference-manifest.js +1 -1
  50. package/app/.next/server/app/api/cli-tools/openclaw-settings/route.js +2 -2
  51. package/app/.next/server/app/api/cli-tools/openclaw-settings/route_client-reference-manifest.js +1 -1
  52. package/app/.next/server/app/api/cloud/auth/route_client-reference-manifest.js +1 -1
  53. package/app/.next/server/app/api/cloud/credentials/update/route_client-reference-manifest.js +1 -1
  54. package/app/.next/server/app/api/cloud/model/resolve/route_client-reference-manifest.js +1 -1
  55. package/app/.next/server/app/api/cloud/models/alias/route.js +1 -1
  56. package/app/.next/server/app/api/cloud/models/alias/route_client-reference-manifest.js +1 -1
  57. package/app/.next/server/app/api/combos/[id]/route.js +1 -1
  58. package/app/.next/server/app/api/combos/[id]/route_client-reference-manifest.js +1 -1
  59. package/app/.next/server/app/api/combos/route.js +1 -1
  60. package/app/.next/server/app/api/combos/route_client-reference-manifest.js +1 -1
  61. package/app/.next/server/app/api/init/route_client-reference-manifest.js +1 -1
  62. package/app/.next/server/app/api/keys/[id]/route.js +1 -1
  63. package/app/.next/server/app/api/keys/[id]/route_client-reference-manifest.js +1 -1
  64. package/app/.next/server/app/api/keys/route.js +1 -1
  65. package/app/.next/server/app/api/keys/route_client-reference-manifest.js +1 -1
  66. package/app/.next/server/app/api/models/alias/route.js +1 -1
  67. package/app/.next/server/app/api/models/alias/route_client-reference-manifest.js +1 -1
  68. package/app/.next/server/app/api/models/route_client-reference-manifest.js +1 -1
  69. package/app/.next/server/app/api/oauth/[provider]/[action]/route.js +1 -1
  70. package/app/.next/server/app/api/oauth/[provider]/[action]/route_client-reference-manifest.js +1 -1
  71. package/app/.next/server/app/api/oauth/cursor/auto-import/route.js +1 -1
  72. package/app/.next/server/app/api/oauth/cursor/auto-import/route_client-reference-manifest.js +1 -1
  73. package/app/.next/server/app/api/oauth/cursor/import/route.js +1 -1
  74. package/app/.next/server/app/api/oauth/cursor/import/route_client-reference-manifest.js +1 -1
  75. package/app/.next/server/app/api/oauth/kiro/auto-import/route_client-reference-manifest.js +1 -1
  76. package/app/.next/server/app/api/oauth/kiro/import/route.js +1 -1
  77. package/app/.next/server/app/api/oauth/kiro/import/route_client-reference-manifest.js +1 -1
  78. package/app/.next/server/app/api/oauth/kiro/social-authorize/route_client-reference-manifest.js +1 -1
  79. package/app/.next/server/app/api/oauth/kiro/social-exchange/route.js +1 -1
  80. package/app/.next/server/app/api/oauth/kiro/social-exchange/route_client-reference-manifest.js +1 -1
  81. package/app/.next/server/app/api/pricing/route_client-reference-manifest.js +1 -1
  82. package/app/.next/server/app/api/provider-nodes/[id]/route_client-reference-manifest.js +1 -1
  83. package/app/.next/server/app/api/provider-nodes/route.js +1 -1
  84. package/app/.next/server/app/api/provider-nodes/route_client-reference-manifest.js +1 -1
  85. package/app/.next/server/app/api/provider-nodes/validate/route_client-reference-manifest.js +1 -1
  86. package/app/.next/server/app/api/providers/[id]/models/route.js +1 -1
  87. package/app/.next/server/app/api/providers/[id]/models/route_client-reference-manifest.js +1 -1
  88. package/app/.next/server/app/api/providers/[id]/route.js +1 -1
  89. package/app/.next/server/app/api/providers/[id]/route_client-reference-manifest.js +1 -1
  90. package/app/.next/server/app/api/providers/[id]/test/route.js +1 -1
  91. package/app/.next/server/app/api/providers/[id]/test/route_client-reference-manifest.js +1 -1
  92. package/app/.next/server/app/api/providers/client/route_client-reference-manifest.js +1 -1
  93. package/app/.next/server/app/api/providers/route.js +1 -1
  94. package/app/.next/server/app/api/providers/route_client-reference-manifest.js +1 -1
  95. package/app/.next/server/app/api/providers/validate/route.js +1 -1
  96. package/app/.next/server/app/api/providers/validate/route_client-reference-manifest.js +1 -1
  97. package/app/.next/server/app/api/settings/require-login/route.js +1 -1
  98. package/app/.next/server/app/api/settings/require-login/route_client-reference-manifest.js +1 -1
  99. package/app/.next/server/app/api/settings/route.js +1 -1
  100. package/app/.next/server/app/api/settings/route_client-reference-manifest.js +1 -1
  101. package/app/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
  102. package/app/.next/server/app/api/sync/cloud/route.js +1 -1
  103. package/app/.next/server/app/api/sync/cloud/route_client-reference-manifest.js +1 -1
  104. package/app/.next/server/app/api/sync/initialize/route_client-reference-manifest.js +1 -1
  105. package/app/.next/server/app/api/tags/route_client-reference-manifest.js +1 -1
  106. package/app/.next/server/app/api/translator/load/route_client-reference-manifest.js +1 -1
  107. package/app/.next/server/app/api/translator/save/route_client-reference-manifest.js +1 -1
  108. package/app/.next/server/app/api/translator/send/route.js +1 -1
  109. package/app/.next/server/app/api/translator/send/route.js.nft.json +1 -1
  110. package/app/.next/server/app/api/translator/send/route_client-reference-manifest.js +1 -1
  111. package/app/.next/server/app/api/translator/translate/route.js +1 -1
  112. package/app/.next/server/app/api/translator/translate/route.js.nft.json +1 -1
  113. package/app/.next/server/app/api/translator/translate/route_client-reference-manifest.js +1 -1
  114. package/app/.next/server/app/api/usage/[connectionId]/route.js +1 -1
  115. package/app/.next/server/app/api/usage/[connectionId]/route.js.nft.json +1 -1
  116. package/app/.next/server/app/api/usage/[connectionId]/route_client-reference-manifest.js +1 -1
  117. package/app/.next/server/app/api/usage/history/route.js +1 -2
  118. package/app/.next/server/app/api/usage/history/route.js.nft.json +1 -1
  119. package/app/.next/server/app/api/usage/history/route_client-reference-manifest.js +1 -1
  120. package/app/.next/server/app/api/usage/providers/route.js +45 -0
  121. package/app/.next/server/app/api/usage/providers/route.js.nft.json +1 -0
  122. package/app/.next/server/app/api/usage/providers/route_client-reference-manifest.js +1 -0
  123. package/app/.next/server/app/api/usage/request-details/route.js +1 -0
  124. package/app/.next/server/app/api/usage/request-details/route.js.nft.json +1 -0
  125. package/app/.next/server/app/api/usage/request-details/route_client-reference-manifest.js +1 -0
  126. package/app/.next/server/app/api/usage/request-logs/route.js +1 -2
  127. package/app/.next/server/app/api/usage/request-logs/route.js.nft.json +1 -1
  128. package/app/.next/server/app/api/usage/request-logs/route_client-reference-manifest.js +1 -1
  129. package/app/.next/server/app/api/v1/api/chat/route.js +1 -1
  130. package/app/.next/server/app/api/v1/api/chat/route.js.nft.json +1 -1
  131. package/app/.next/server/app/api/v1/api/chat/route_client-reference-manifest.js +1 -1
  132. package/app/.next/server/app/api/v1/chat/completions/route.js +1 -1
  133. package/app/.next/server/app/api/v1/chat/completions/route.js.nft.json +1 -1
  134. package/app/.next/server/app/api/v1/chat/completions/route_client-reference-manifest.js +1 -1
  135. package/app/.next/server/app/api/v1/messages/count_tokens/route_client-reference-manifest.js +1 -1
  136. package/app/.next/server/app/api/v1/messages/route.js +1 -1
  137. package/app/.next/server/app/api/v1/messages/route.js.nft.json +1 -1
  138. package/app/.next/server/app/api/v1/messages/route_client-reference-manifest.js +1 -1
  139. package/app/.next/server/app/api/v1/models/route.js +1 -1
  140. package/app/.next/server/app/api/v1/models/route_client-reference-manifest.js +1 -1
  141. package/app/.next/server/app/api/v1/responses/route.js +1 -1
  142. package/app/.next/server/app/api/v1/responses/route.js.nft.json +1 -1
  143. package/app/.next/server/app/api/v1/responses/route_client-reference-manifest.js +1 -1
  144. package/app/.next/server/app/api/v1/route_client-reference-manifest.js +1 -1
  145. package/app/.next/server/app/api/v1beta/models/[...path]/route.js +1 -1
  146. package/app/.next/server/app/api/v1beta/models/[...path]/route.js.nft.json +1 -1
  147. package/app/.next/server/app/api/v1beta/models/[...path]/route_client-reference-manifest.js +1 -1
  148. package/app/.next/server/app/api/v1beta/models/route.js +1 -1
  149. package/app/.next/server/app/api/v1beta/models/route_client-reference-manifest.js +1 -1
  150. package/app/.next/server/app/callback/page_client-reference-manifest.js +1 -1
  151. package/app/.next/server/app/callback.html +1 -1
  152. package/app/.next/server/app/callback.rsc +3 -3
  153. package/app/.next/server/app/callback.segments/_full.segment.rsc +3 -3
  154. package/app/.next/server/app/callback.segments/_head.segment.rsc +1 -1
  155. package/app/.next/server/app/callback.segments/_index.segment.rsc +3 -3
  156. package/app/.next/server/app/callback.segments/_tree.segment.rsc +2 -2
  157. package/app/.next/server/app/callback.segments/callback/__PAGE__.segment.rsc +1 -1
  158. package/app/.next/server/app/callback.segments/callback.segment.rsc +1 -1
  159. package/app/.next/server/app/dashboard/cli-tools.html +1 -1
  160. package/app/.next/server/app/dashboard/cli-tools.rsc +5 -5
  161. package/app/.next/server/app/dashboard/cli-tools.segments/!KGRhc2hib2FyZCk/dashboard/cli-tools/__PAGE__.segment.rsc +2 -2
  162. package/app/.next/server/app/dashboard/cli-tools.segments/!KGRhc2hib2FyZCk/dashboard/cli-tools.segment.rsc +1 -1
  163. package/app/.next/server/app/dashboard/cli-tools.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  164. package/app/.next/server/app/dashboard/cli-tools.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  165. package/app/.next/server/app/dashboard/cli-tools.segments/_full.segment.rsc +5 -5
  166. package/app/.next/server/app/dashboard/cli-tools.segments/_head.segment.rsc +1 -1
  167. package/app/.next/server/app/dashboard/cli-tools.segments/_index.segment.rsc +3 -3
  168. package/app/.next/server/app/dashboard/cli-tools.segments/_tree.segment.rsc +2 -2
  169. package/app/.next/server/app/dashboard/combos.html +1 -1
  170. package/app/.next/server/app/dashboard/combos.rsc +5 -5
  171. package/app/.next/server/app/dashboard/combos.segments/!KGRhc2hib2FyZCk/dashboard/combos/__PAGE__.segment.rsc +2 -2
  172. package/app/.next/server/app/dashboard/combos.segments/!KGRhc2hib2FyZCk/dashboard/combos.segment.rsc +1 -1
  173. package/app/.next/server/app/dashboard/combos.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  174. package/app/.next/server/app/dashboard/combos.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  175. package/app/.next/server/app/dashboard/combos.segments/_full.segment.rsc +5 -5
  176. package/app/.next/server/app/dashboard/combos.segments/_head.segment.rsc +1 -1
  177. package/app/.next/server/app/dashboard/combos.segments/_index.segment.rsc +3 -3
  178. package/app/.next/server/app/dashboard/combos.segments/_tree.segment.rsc +2 -2
  179. package/app/.next/server/app/dashboard/endpoint.html +1 -1
  180. package/app/.next/server/app/dashboard/endpoint.rsc +5 -5
  181. package/app/.next/server/app/dashboard/endpoint.segments/!KGRhc2hib2FyZCk/dashboard/endpoint/__PAGE__.segment.rsc +2 -2
  182. package/app/.next/server/app/dashboard/endpoint.segments/!KGRhc2hib2FyZCk/dashboard/endpoint.segment.rsc +1 -1
  183. package/app/.next/server/app/dashboard/endpoint.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  184. package/app/.next/server/app/dashboard/endpoint.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  185. package/app/.next/server/app/dashboard/endpoint.segments/_full.segment.rsc +5 -5
  186. package/app/.next/server/app/dashboard/endpoint.segments/_head.segment.rsc +1 -1
  187. package/app/.next/server/app/dashboard/endpoint.segments/_index.segment.rsc +3 -3
  188. package/app/.next/server/app/dashboard/endpoint.segments/_tree.segment.rsc +2 -2
  189. package/app/.next/server/app/dashboard/profile.html +1 -1
  190. package/app/.next/server/app/dashboard/profile.rsc +5 -5
  191. package/app/.next/server/app/dashboard/profile.segments/!KGRhc2hib2FyZCk/dashboard/profile/__PAGE__.segment.rsc +2 -2
  192. package/app/.next/server/app/dashboard/profile.segments/!KGRhc2hib2FyZCk/dashboard/profile.segment.rsc +1 -1
  193. package/app/.next/server/app/dashboard/profile.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  194. package/app/.next/server/app/dashboard/profile.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  195. package/app/.next/server/app/dashboard/profile.segments/_full.segment.rsc +5 -5
  196. package/app/.next/server/app/dashboard/profile.segments/_head.segment.rsc +1 -1
  197. package/app/.next/server/app/dashboard/profile.segments/_index.segment.rsc +3 -3
  198. package/app/.next/server/app/dashboard/profile.segments/_tree.segment.rsc +2 -2
  199. package/app/.next/server/app/dashboard/providers/new.html +1 -1
  200. package/app/.next/server/app/dashboard/providers/new.rsc +5 -5
  201. package/app/.next/server/app/dashboard/providers/new.segments/!KGRhc2hib2FyZCk/dashboard/providers/new/__PAGE__.segment.rsc +2 -2
  202. package/app/.next/server/app/dashboard/providers/new.segments/!KGRhc2hib2FyZCk/dashboard/providers/new.segment.rsc +1 -1
  203. package/app/.next/server/app/dashboard/providers/new.segments/!KGRhc2hib2FyZCk/dashboard/providers.segment.rsc +1 -1
  204. package/app/.next/server/app/dashboard/providers/new.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  205. package/app/.next/server/app/dashboard/providers/new.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  206. package/app/.next/server/app/dashboard/providers/new.segments/_full.segment.rsc +5 -5
  207. package/app/.next/server/app/dashboard/providers/new.segments/_head.segment.rsc +1 -1
  208. package/app/.next/server/app/dashboard/providers/new.segments/_index.segment.rsc +3 -3
  209. package/app/.next/server/app/dashboard/providers/new.segments/_tree.segment.rsc +2 -2
  210. package/app/.next/server/app/dashboard/providers.html +1 -1
  211. package/app/.next/server/app/dashboard/providers.rsc +5 -5
  212. package/app/.next/server/app/dashboard/providers.segments/!KGRhc2hib2FyZCk/dashboard/providers/__PAGE__.segment.rsc +2 -2
  213. package/app/.next/server/app/dashboard/providers.segments/!KGRhc2hib2FyZCk/dashboard/providers.segment.rsc +1 -1
  214. package/app/.next/server/app/dashboard/providers.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  215. package/app/.next/server/app/dashboard/providers.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  216. package/app/.next/server/app/dashboard/providers.segments/_full.segment.rsc +5 -5
  217. package/app/.next/server/app/dashboard/providers.segments/_head.segment.rsc +1 -1
  218. package/app/.next/server/app/dashboard/providers.segments/_index.segment.rsc +3 -3
  219. package/app/.next/server/app/dashboard/providers.segments/_tree.segment.rsc +2 -2
  220. package/app/.next/server/app/dashboard/settings/pricing/page_client-reference-manifest.js +1 -1
  221. package/app/.next/server/app/dashboard/settings/pricing.html +1 -1
  222. package/app/.next/server/app/dashboard/settings/pricing.rsc +3 -3
  223. package/app/.next/server/app/dashboard/settings/pricing.segments/_full.segment.rsc +3 -3
  224. package/app/.next/server/app/dashboard/settings/pricing.segments/_head.segment.rsc +1 -1
  225. package/app/.next/server/app/dashboard/settings/pricing.segments/_index.segment.rsc +3 -3
  226. package/app/.next/server/app/dashboard/settings/pricing.segments/_tree.segment.rsc +2 -2
  227. package/app/.next/server/app/dashboard/settings/pricing.segments/dashboard/settings/pricing/__PAGE__.segment.rsc +1 -1
  228. package/app/.next/server/app/dashboard/settings/pricing.segments/dashboard/settings/pricing.segment.rsc +1 -1
  229. package/app/.next/server/app/dashboard/settings/pricing.segments/dashboard/settings.segment.rsc +1 -1
  230. package/app/.next/server/app/dashboard/settings/pricing.segments/dashboard.segment.rsc +1 -1
  231. package/app/.next/server/app/dashboard/translator.html +1 -1
  232. package/app/.next/server/app/dashboard/translator.rsc +5 -5
  233. package/app/.next/server/app/dashboard/translator.segments/!KGRhc2hib2FyZCk/dashboard/translator/__PAGE__.segment.rsc +2 -2
  234. package/app/.next/server/app/dashboard/translator.segments/!KGRhc2hib2FyZCk/dashboard/translator.segment.rsc +1 -1
  235. package/app/.next/server/app/dashboard/translator.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  236. package/app/.next/server/app/dashboard/translator.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  237. package/app/.next/server/app/dashboard/translator.segments/_full.segment.rsc +5 -5
  238. package/app/.next/server/app/dashboard/translator.segments/_head.segment.rsc +1 -1
  239. package/app/.next/server/app/dashboard/translator.segments/_index.segment.rsc +3 -3
  240. package/app/.next/server/app/dashboard/translator.segments/_tree.segment.rsc +2 -2
  241. package/app/.next/server/app/dashboard/usage.html +1 -1
  242. package/app/.next/server/app/dashboard/usage.rsc +5 -5
  243. package/app/.next/server/app/dashboard/usage.segments/!KGRhc2hib2FyZCk/dashboard/usage/__PAGE__.segment.rsc +2 -2
  244. package/app/.next/server/app/dashboard/usage.segments/!KGRhc2hib2FyZCk/dashboard/usage.segment.rsc +1 -1
  245. package/app/.next/server/app/dashboard/usage.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  246. package/app/.next/server/app/dashboard/usage.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  247. package/app/.next/server/app/dashboard/usage.segments/_full.segment.rsc +5 -5
  248. package/app/.next/server/app/dashboard/usage.segments/_head.segment.rsc +1 -1
  249. package/app/.next/server/app/dashboard/usage.segments/_index.segment.rsc +3 -3
  250. package/app/.next/server/app/dashboard/usage.segments/_tree.segment.rsc +2 -2
  251. package/app/.next/server/app/dashboard.html +1 -1
  252. package/app/.next/server/app/dashboard.rsc +5 -5
  253. package/app/.next/server/app/dashboard.segments/!KGRhc2hib2FyZCk/dashboard/__PAGE__.segment.rsc +2 -2
  254. package/app/.next/server/app/dashboard.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  255. package/app/.next/server/app/dashboard.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  256. package/app/.next/server/app/dashboard.segments/_full.segment.rsc +5 -5
  257. package/app/.next/server/app/dashboard.segments/_head.segment.rsc +1 -1
  258. package/app/.next/server/app/dashboard.segments/_index.segment.rsc +3 -3
  259. package/app/.next/server/app/dashboard.segments/_tree.segment.rsc +2 -2
  260. package/app/.next/server/app/index.html +1 -1
  261. package/app/.next/server/app/index.rsc +3 -3
  262. package/app/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  263. package/app/.next/server/app/index.segments/_full.segment.rsc +3 -3
  264. package/app/.next/server/app/index.segments/_head.segment.rsc +1 -1
  265. package/app/.next/server/app/index.segments/_index.segment.rsc +3 -3
  266. package/app/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  267. package/app/.next/server/app/landing/page_client-reference-manifest.js +1 -1
  268. package/app/.next/server/app/landing.html +1 -1
  269. package/app/.next/server/app/landing.rsc +3 -3
  270. package/app/.next/server/app/landing.segments/_full.segment.rsc +3 -3
  271. package/app/.next/server/app/landing.segments/_head.segment.rsc +1 -1
  272. package/app/.next/server/app/landing.segments/_index.segment.rsc +3 -3
  273. package/app/.next/server/app/landing.segments/_tree.segment.rsc +2 -2
  274. package/app/.next/server/app/landing.segments/landing/__PAGE__.segment.rsc +1 -1
  275. package/app/.next/server/app/landing.segments/landing.segment.rsc +1 -1
  276. package/app/.next/server/app/login/page_client-reference-manifest.js +1 -1
  277. package/app/.next/server/app/login.html +1 -1
  278. package/app/.next/server/app/login.rsc +4 -4
  279. package/app/.next/server/app/login.segments/_full.segment.rsc +4 -4
  280. package/app/.next/server/app/login.segments/_head.segment.rsc +1 -1
  281. package/app/.next/server/app/login.segments/_index.segment.rsc +3 -3
  282. package/app/.next/server/app/login.segments/_tree.segment.rsc +2 -2
  283. package/app/.next/server/app/login.segments/login/__PAGE__.segment.rsc +2 -2
  284. package/app/.next/server/app/login.segments/login.segment.rsc +1 -1
  285. package/app/.next/server/app/page_client-reference-manifest.js +1 -1
  286. package/app/.next/server/app-paths-manifest.json +42 -40
  287. package/app/.next/server/chunks/3110.js +2 -2
  288. package/app/.next/server/chunks/3990.js +41 -0
  289. package/app/.next/server/chunks/412.js +4 -4
  290. package/app/.next/server/chunks/5330.js +2 -3
  291. package/app/.next/server/chunks/7647.js +1 -0
  292. package/app/.next/server/chunks/8152.js +1 -1
  293. package/app/.next/server/chunks/8954.js +1 -1
  294. package/app/.next/server/chunks/9718.js +1 -1
  295. package/app/.next/server/chunks/9862.js +1 -1
  296. package/app/.next/server/pages/404.html +1 -1
  297. package/app/.next/server/pages/500.html +2 -2
  298. package/app/.next/server/server-reference-manifest.js +1 -1
  299. package/app/.next/server/server-reference-manifest.json +1 -1
  300. package/app/.next/static/chunks/1393-ec22348a03d98802.js +1 -0
  301. package/app/.next/static/chunks/8729-30cb66f318ac2d23.js +1 -0
  302. package/app/.next/static/chunks/app/(dashboard)/dashboard/profile/page-738071ba2546b274.js +1 -0
  303. package/app/.next/static/chunks/app/(dashboard)/dashboard/providers/[id]/page-d48c3e28182c53fd.js +1 -0
  304. package/app/.next/static/chunks/app/(dashboard)/dashboard/usage/page-874d3494c011eaf2.js +1 -0
  305. package/app/.next/static/chunks/app/_global-error/page-1968aadfb379c0a3.js +1 -0
  306. package/app/.next/static/chunks/app/api/auth/login/route-1968aadfb379c0a3.js +1 -0
  307. package/app/.next/static/chunks/app/api/auth/logout/route-1968aadfb379c0a3.js +1 -0
  308. package/app/.next/static/chunks/app/api/cli-tools/antigravity-mitm/alias/route-1968aadfb379c0a3.js +1 -0
  309. package/app/.next/static/chunks/app/api/cli-tools/antigravity-mitm/route-1968aadfb379c0a3.js +1 -0
  310. package/app/.next/static/chunks/app/api/cli-tools/claude-settings/route-1968aadfb379c0a3.js +1 -0
  311. package/app/.next/static/chunks/app/api/cli-tools/codex-settings/route-1968aadfb379c0a3.js +1 -0
  312. package/app/.next/static/chunks/app/api/cli-tools/droid-settings/route-1968aadfb379c0a3.js +1 -0
  313. package/app/.next/static/chunks/app/api/cli-tools/openclaw-settings/route-1968aadfb379c0a3.js +1 -0
  314. package/app/.next/static/chunks/app/api/cloud/auth/route-1968aadfb379c0a3.js +1 -0
  315. package/app/.next/static/chunks/app/api/cloud/credentials/update/route-1968aadfb379c0a3.js +1 -0
  316. package/app/.next/static/chunks/app/api/cloud/model/resolve/route-1968aadfb379c0a3.js +1 -0
  317. package/app/.next/static/chunks/app/api/cloud/models/alias/route-1968aadfb379c0a3.js +1 -0
  318. package/app/.next/static/chunks/app/api/combos/[id]/route-1968aadfb379c0a3.js +1 -0
  319. package/app/.next/static/chunks/app/api/combos/route-1968aadfb379c0a3.js +1 -0
  320. package/app/.next/static/chunks/app/api/init/route-1968aadfb379c0a3.js +1 -0
  321. package/app/.next/static/chunks/app/api/keys/[id]/route-1968aadfb379c0a3.js +1 -0
  322. package/app/.next/static/chunks/app/api/keys/route-1968aadfb379c0a3.js +1 -0
  323. package/app/.next/static/chunks/app/api/models/alias/route-1968aadfb379c0a3.js +1 -0
  324. package/app/.next/static/chunks/app/api/models/route-1968aadfb379c0a3.js +1 -0
  325. package/app/.next/static/chunks/app/api/oauth/[provider]/[action]/route-1968aadfb379c0a3.js +1 -0
  326. package/app/.next/static/chunks/app/api/oauth/cursor/auto-import/route-1968aadfb379c0a3.js +1 -0
  327. package/app/.next/static/chunks/app/api/oauth/cursor/import/route-1968aadfb379c0a3.js +1 -0
  328. package/app/.next/static/chunks/app/api/oauth/kiro/auto-import/route-1968aadfb379c0a3.js +1 -0
  329. package/app/.next/static/chunks/app/api/oauth/kiro/import/route-1968aadfb379c0a3.js +1 -0
  330. package/app/.next/static/chunks/app/api/oauth/kiro/social-authorize/route-1968aadfb379c0a3.js +1 -0
  331. package/app/.next/static/chunks/app/api/oauth/kiro/social-exchange/route-1968aadfb379c0a3.js +1 -0
  332. package/app/.next/static/chunks/app/api/pricing/route-1968aadfb379c0a3.js +1 -0
  333. package/app/.next/static/chunks/app/api/provider-nodes/[id]/route-1968aadfb379c0a3.js +1 -0
  334. package/app/.next/static/chunks/app/api/provider-nodes/route-1968aadfb379c0a3.js +1 -0
  335. package/app/.next/static/chunks/app/api/provider-nodes/validate/route-1968aadfb379c0a3.js +1 -0
  336. package/app/.next/static/chunks/app/api/providers/[id]/models/route-1968aadfb379c0a3.js +1 -0
  337. package/app/.next/static/chunks/app/api/providers/[id]/route-1968aadfb379c0a3.js +1 -0
  338. package/app/.next/static/chunks/app/api/providers/[id]/test/route-1968aadfb379c0a3.js +1 -0
  339. package/app/.next/static/chunks/app/api/providers/client/route-1968aadfb379c0a3.js +1 -0
  340. package/app/.next/static/chunks/app/api/providers/route-1968aadfb379c0a3.js +1 -0
  341. package/app/.next/static/chunks/app/api/providers/validate/route-1968aadfb379c0a3.js +1 -0
  342. package/app/.next/static/chunks/app/api/settings/require-login/route-1968aadfb379c0a3.js +1 -0
  343. package/app/.next/static/chunks/app/api/settings/route-1968aadfb379c0a3.js +1 -0
  344. package/app/.next/static/chunks/app/api/shutdown/route-1968aadfb379c0a3.js +1 -0
  345. package/app/.next/static/chunks/app/api/sync/cloud/route-1968aadfb379c0a3.js +1 -0
  346. package/app/.next/static/chunks/app/api/sync/initialize/route-1968aadfb379c0a3.js +1 -0
  347. package/app/.next/static/chunks/app/api/tags/route-1968aadfb379c0a3.js +1 -0
  348. package/app/.next/static/chunks/app/api/translator/load/route-1968aadfb379c0a3.js +1 -0
  349. package/app/.next/static/chunks/app/api/translator/save/route-1968aadfb379c0a3.js +1 -0
  350. package/app/.next/static/chunks/app/api/translator/send/route-1968aadfb379c0a3.js +1 -0
  351. package/app/.next/static/chunks/app/api/translator/translate/route-1968aadfb379c0a3.js +1 -0
  352. package/app/.next/static/chunks/app/api/usage/[connectionId]/route-1968aadfb379c0a3.js +1 -0
  353. package/app/.next/static/chunks/app/api/usage/history/route-1968aadfb379c0a3.js +1 -0
  354. package/app/.next/static/chunks/app/api/usage/providers/route-1968aadfb379c0a3.js +1 -0
  355. package/app/.next/static/chunks/app/api/usage/request-details/route-1968aadfb379c0a3.js +1 -0
  356. package/app/.next/static/chunks/app/api/usage/request-logs/route-1968aadfb379c0a3.js +1 -0
  357. package/app/.next/static/chunks/app/api/v1/api/chat/route-1968aadfb379c0a3.js +1 -0
  358. package/app/.next/static/chunks/app/api/v1/chat/completions/route-1968aadfb379c0a3.js +1 -0
  359. package/app/.next/static/chunks/app/api/v1/messages/count_tokens/route-1968aadfb379c0a3.js +1 -0
  360. package/app/.next/static/chunks/app/api/v1/messages/route-1968aadfb379c0a3.js +1 -0
  361. package/app/.next/static/chunks/app/api/v1/models/route-1968aadfb379c0a3.js +1 -0
  362. package/app/.next/static/chunks/app/api/v1/responses/route-1968aadfb379c0a3.js +1 -0
  363. package/app/.next/static/chunks/app/api/v1/route-1968aadfb379c0a3.js +1 -0
  364. package/app/.next/static/chunks/app/api/v1beta/models/[...path]/route-1968aadfb379c0a3.js +1 -0
  365. package/app/.next/static/chunks/app/api/v1beta/models/route-1968aadfb379c0a3.js +1 -0
  366. package/app/.next/static/chunks/app/page-1968aadfb379c0a3.js +1 -0
  367. package/app/.next/static/chunks/next/dist/client/components/builtin/app-error-1968aadfb379c0a3.js +1 -0
  368. package/app/.next/static/chunks/next/dist/client/components/builtin/forbidden-1968aadfb379c0a3.js +1 -0
  369. package/app/.next/static/chunks/next/dist/client/components/builtin/not-found-1968aadfb379c0a3.js +1 -0
  370. package/app/.next/static/chunks/next/dist/client/components/builtin/unauthorized-1968aadfb379c0a3.js +1 -0
  371. package/app/.next/static/css/e4a2c774b676c378.css +3 -0
  372. package/app/.next/static/jnuJ7xmQaeiHg9oUUDqGs/_buildManifest.js +1 -0
  373. package/app/package.json +1 -1
  374. package/app/public/providers/glm-cn.png +0 -0
  375. package/app/src/mitm/cert/generate.js +44 -0
  376. package/app/src/mitm/cert/install.js +136 -0
  377. package/app/src/mitm/dns/dnsConfig.js +130 -0
  378. package/app/src/mitm/manager.js +227 -0
  379. package/cli.js +110 -144
  380. package/package.json +1 -1
  381. package/src/cli/utils/input.js +7 -1
  382. package/src/cli/utils/menuHelper.js +2 -1
  383. package/app/.next/server/chunks/9707.js +0 -1
  384. package/app/.next/static/FcGNHUA9390qBi1g02a_v/_buildManifest.js +0 -1
  385. package/app/.next/static/chunks/1393-3fdad0258c0b525c.js +0 -1
  386. package/app/.next/static/chunks/8729-9d273189141eb6fb.js +0 -1
  387. package/app/.next/static/chunks/app/(dashboard)/dashboard/profile/page-b61f704bc7de9783.js +0 -1
  388. package/app/.next/static/chunks/app/(dashboard)/dashboard/providers/[id]/page-e8509c35110f8541.js +0 -1
  389. package/app/.next/static/chunks/app/(dashboard)/dashboard/usage/page-15eac98ba6db9df4.js +0 -1
  390. package/app/.next/static/chunks/app/_global-error/page-901ec69b71429e39.js +0 -1
  391. package/app/.next/static/chunks/app/api/auth/login/route-901ec69b71429e39.js +0 -1
  392. package/app/.next/static/chunks/app/api/auth/logout/route-901ec69b71429e39.js +0 -1
  393. package/app/.next/static/chunks/app/api/cli-tools/antigravity-mitm/alias/route-901ec69b71429e39.js +0 -1
  394. package/app/.next/static/chunks/app/api/cli-tools/antigravity-mitm/route-901ec69b71429e39.js +0 -1
  395. package/app/.next/static/chunks/app/api/cli-tools/claude-settings/route-901ec69b71429e39.js +0 -1
  396. package/app/.next/static/chunks/app/api/cli-tools/codex-settings/route-901ec69b71429e39.js +0 -1
  397. package/app/.next/static/chunks/app/api/cli-tools/droid-settings/route-901ec69b71429e39.js +0 -1
  398. package/app/.next/static/chunks/app/api/cli-tools/openclaw-settings/route-901ec69b71429e39.js +0 -1
  399. package/app/.next/static/chunks/app/api/cloud/auth/route-901ec69b71429e39.js +0 -1
  400. package/app/.next/static/chunks/app/api/cloud/credentials/update/route-901ec69b71429e39.js +0 -1
  401. package/app/.next/static/chunks/app/api/cloud/model/resolve/route-901ec69b71429e39.js +0 -1
  402. package/app/.next/static/chunks/app/api/cloud/models/alias/route-901ec69b71429e39.js +0 -1
  403. package/app/.next/static/chunks/app/api/combos/[id]/route-901ec69b71429e39.js +0 -1
  404. package/app/.next/static/chunks/app/api/combos/route-901ec69b71429e39.js +0 -1
  405. package/app/.next/static/chunks/app/api/init/route-901ec69b71429e39.js +0 -1
  406. package/app/.next/static/chunks/app/api/keys/[id]/route-901ec69b71429e39.js +0 -1
  407. package/app/.next/static/chunks/app/api/keys/route-901ec69b71429e39.js +0 -1
  408. package/app/.next/static/chunks/app/api/models/alias/route-901ec69b71429e39.js +0 -1
  409. package/app/.next/static/chunks/app/api/models/route-901ec69b71429e39.js +0 -1
  410. package/app/.next/static/chunks/app/api/oauth/[provider]/[action]/route-901ec69b71429e39.js +0 -1
  411. package/app/.next/static/chunks/app/api/oauth/cursor/auto-import/route-901ec69b71429e39.js +0 -1
  412. package/app/.next/static/chunks/app/api/oauth/cursor/import/route-901ec69b71429e39.js +0 -1
  413. package/app/.next/static/chunks/app/api/oauth/kiro/auto-import/route-901ec69b71429e39.js +0 -1
  414. package/app/.next/static/chunks/app/api/oauth/kiro/import/route-901ec69b71429e39.js +0 -1
  415. package/app/.next/static/chunks/app/api/oauth/kiro/social-authorize/route-901ec69b71429e39.js +0 -1
  416. package/app/.next/static/chunks/app/api/oauth/kiro/social-exchange/route-901ec69b71429e39.js +0 -1
  417. package/app/.next/static/chunks/app/api/pricing/route-901ec69b71429e39.js +0 -1
  418. package/app/.next/static/chunks/app/api/provider-nodes/[id]/route-901ec69b71429e39.js +0 -1
  419. package/app/.next/static/chunks/app/api/provider-nodes/route-901ec69b71429e39.js +0 -1
  420. package/app/.next/static/chunks/app/api/provider-nodes/validate/route-901ec69b71429e39.js +0 -1
  421. package/app/.next/static/chunks/app/api/providers/[id]/models/route-901ec69b71429e39.js +0 -1
  422. package/app/.next/static/chunks/app/api/providers/[id]/route-901ec69b71429e39.js +0 -1
  423. package/app/.next/static/chunks/app/api/providers/[id]/test/route-901ec69b71429e39.js +0 -1
  424. package/app/.next/static/chunks/app/api/providers/client/route-901ec69b71429e39.js +0 -1
  425. package/app/.next/static/chunks/app/api/providers/route-901ec69b71429e39.js +0 -1
  426. package/app/.next/static/chunks/app/api/providers/validate/route-901ec69b71429e39.js +0 -1
  427. package/app/.next/static/chunks/app/api/settings/require-login/route-901ec69b71429e39.js +0 -1
  428. package/app/.next/static/chunks/app/api/settings/route-901ec69b71429e39.js +0 -1
  429. package/app/.next/static/chunks/app/api/shutdown/route-901ec69b71429e39.js +0 -1
  430. package/app/.next/static/chunks/app/api/sync/cloud/route-901ec69b71429e39.js +0 -1
  431. package/app/.next/static/chunks/app/api/sync/initialize/route-901ec69b71429e39.js +0 -1
  432. package/app/.next/static/chunks/app/api/tags/route-901ec69b71429e39.js +0 -1
  433. package/app/.next/static/chunks/app/api/translator/load/route-901ec69b71429e39.js +0 -1
  434. package/app/.next/static/chunks/app/api/translator/save/route-901ec69b71429e39.js +0 -1
  435. package/app/.next/static/chunks/app/api/translator/send/route-901ec69b71429e39.js +0 -1
  436. package/app/.next/static/chunks/app/api/translator/translate/route-901ec69b71429e39.js +0 -1
  437. package/app/.next/static/chunks/app/api/usage/[connectionId]/route-901ec69b71429e39.js +0 -1
  438. package/app/.next/static/chunks/app/api/usage/history/route-901ec69b71429e39.js +0 -1
  439. package/app/.next/static/chunks/app/api/usage/request-logs/route-901ec69b71429e39.js +0 -1
  440. package/app/.next/static/chunks/app/api/v1/api/chat/route-901ec69b71429e39.js +0 -1
  441. package/app/.next/static/chunks/app/api/v1/chat/completions/route-901ec69b71429e39.js +0 -1
  442. package/app/.next/static/chunks/app/api/v1/messages/count_tokens/route-901ec69b71429e39.js +0 -1
  443. package/app/.next/static/chunks/app/api/v1/messages/route-901ec69b71429e39.js +0 -1
  444. package/app/.next/static/chunks/app/api/v1/models/route-901ec69b71429e39.js +0 -1
  445. package/app/.next/static/chunks/app/api/v1/responses/route-901ec69b71429e39.js +0 -1
  446. package/app/.next/static/chunks/app/api/v1/route-901ec69b71429e39.js +0 -1
  447. package/app/.next/static/chunks/app/api/v1beta/models/[...path]/route-901ec69b71429e39.js +0 -1
  448. package/app/.next/static/chunks/app/api/v1beta/models/route-901ec69b71429e39.js +0 -1
  449. package/app/.next/static/chunks/app/page-901ec69b71429e39.js +0 -1
  450. package/app/.next/static/chunks/next/dist/client/components/builtin/app-error-901ec69b71429e39.js +0 -1
  451. package/app/.next/static/chunks/next/dist/client/components/builtin/forbidden-901ec69b71429e39.js +0 -1
  452. package/app/.next/static/chunks/next/dist/client/components/builtin/not-found-901ec69b71429e39.js +0 -1
  453. package/app/.next/static/chunks/next/dist/client/components/builtin/unauthorized-901ec69b71429e39.js +0 -1
  454. package/app/.next/static/css/69b23ffd995e0cf4.css +0 -3
  455. /package/app/.next/static/{FcGNHUA9390qBi1g02a_v → jnuJ7xmQaeiHg9oUUDqGs}/_ssgManifest.js +0 -0
package/app/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "9router-app",
3
- "version": "0.2.71",
3
+ "version": "0.2.73",
4
4
  "description": "9Router web dashboard",
5
5
  "private": true,
6
6
  "scripts": {
Binary file
@@ -0,0 +1,44 @@
1
+ const path = require("path");
2
+ const fs = require("fs");
3
+ const os = require("os");
4
+
5
+ const TARGET_HOST = "daily-cloudcode-pa.googleapis.com";
6
+
7
+ /**
8
+ * Generate self-signed SSL certificate using selfsigned (pure JS, no openssl needed)
9
+ */
10
+ async function generateCert() {
11
+ const certDir = path.join(os.homedir(), ".9router", "mitm");
12
+ const keyPath = path.join(certDir, "server.key");
13
+ const certPath = path.join(certDir, "server.crt");
14
+
15
+ if (fs.existsSync(keyPath) && fs.existsSync(certPath)) {
16
+ console.log("✅ SSL certificate already exists");
17
+ return { key: keyPath, cert: certPath };
18
+ }
19
+
20
+ if (!fs.existsSync(certDir)) {
21
+ fs.mkdirSync(certDir, { recursive: true });
22
+ }
23
+
24
+ const selfsigned = require("selfsigned");
25
+ const attrs = [{ name: "commonName", value: TARGET_HOST }];
26
+ const notAfter = new Date();
27
+ notAfter.setFullYear(notAfter.getFullYear() + 1);
28
+ const pems = await selfsigned.generate(attrs, {
29
+ keySize: 2048,
30
+ algorithm: "sha256",
31
+ notAfterDate: notAfter,
32
+ extensions: [
33
+ { name: "subjectAltName", altNames: [{ type: 2, value: TARGET_HOST }] }
34
+ ]
35
+ });
36
+
37
+ fs.writeFileSync(keyPath, pems.private);
38
+ fs.writeFileSync(certPath, pems.cert);
39
+
40
+ console.log(`✅ Generated SSL certificate for ${TARGET_HOST}`);
41
+ return { key: keyPath, cert: certPath };
42
+ }
43
+
44
+ module.exports = { generateCert };
@@ -0,0 +1,136 @@
1
+ const fs = require("fs");
2
+ const crypto = require("crypto");
3
+ const { exec } = require("child_process");
4
+ const { execWithPassword } = require("../dns/dnsConfig.js");
5
+
6
+ const IS_WIN = process.platform === "win32";
7
+
8
+ // Get SHA1 fingerprint from cert file using Node.js crypto
9
+ function getCertFingerprint(certPath) {
10
+ const pem = fs.readFileSync(certPath, "utf-8");
11
+ const der = Buffer.from(pem.replace(/-----[^-]+-----/g, "").replace(/\s/g, ""), "base64");
12
+ return crypto.createHash("sha1").update(der).digest("hex").toUpperCase().match(/.{2}/g).join(":");
13
+ }
14
+
15
+ /**
16
+ * Check if certificate is already installed in system store
17
+ */
18
+ async function checkCertInstalled(certPath) {
19
+ if (IS_WIN) {
20
+ return checkCertInstalledWindows(certPath);
21
+ }
22
+ return checkCertInstalledMac(certPath);
23
+ }
24
+
25
+ function checkCertInstalledMac(certPath) {
26
+ return new Promise((resolve) => {
27
+ try {
28
+ const fingerprint = getCertFingerprint(certPath);
29
+ exec(`security find-certificate -a -Z /Library/Keychains/System.keychain | grep -i "${fingerprint}"`, (error) => {
30
+ resolve(!error);
31
+ });
32
+ } catch {
33
+ resolve(false);
34
+ }
35
+ });
36
+ }
37
+
38
+ function checkCertInstalledWindows(certPath) {
39
+ return new Promise((resolve) => {
40
+ // Check Root store for our cert by subject name
41
+ exec("certutil -store Root daily-cloudcode-pa.googleapis.com", (error) => {
42
+ resolve(!error);
43
+ });
44
+ });
45
+ }
46
+
47
+ /**
48
+ * Install SSL certificate to system trust store
49
+ */
50
+ async function installCert(sudoPassword, certPath) {
51
+ if (!fs.existsSync(certPath)) {
52
+ throw new Error(`Certificate file not found: ${certPath}`);
53
+ }
54
+
55
+ const isInstalled = await checkCertInstalled(certPath);
56
+ if (isInstalled) {
57
+ console.log("✅ Certificate already installed");
58
+ return;
59
+ }
60
+
61
+ if (IS_WIN) {
62
+ await installCertWindows(certPath);
63
+ } else {
64
+ await installCertMac(sudoPassword, certPath);
65
+ }
66
+ }
67
+
68
+ async function installCertMac(sudoPassword, certPath) {
69
+ const command = `security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain "${certPath}"`;
70
+ try {
71
+ await execWithPassword(command, sudoPassword);
72
+ console.log(`✅ Installed certificate to system keychain: ${certPath}`);
73
+ } catch (error) {
74
+ const msg = error.message?.includes("canceled") ? "User canceled authorization" : "Certificate install failed";
75
+ throw new Error(msg);
76
+ }
77
+ }
78
+
79
+ async function installCertWindows(certPath) {
80
+ // Use PowerShell elevated to add cert to Root store
81
+ const psCommand = `Start-Process certutil -ArgumentList '-addstore','Root','${certPath.replace(/'/g, "''")}' -Verb RunAs -Wait`;
82
+ return new Promise((resolve, reject) => {
83
+ exec(`powershell -Command "${psCommand}"`, (error) => {
84
+ if (error) {
85
+ reject(new Error(`Failed to install certificate: ${error.message}`));
86
+ } else {
87
+ console.log(`✅ Installed certificate to Windows Root store`);
88
+ resolve();
89
+ }
90
+ });
91
+ });
92
+ }
93
+
94
+ /**
95
+ * Uninstall SSL certificate from system store
96
+ */
97
+ async function uninstallCert(sudoPassword, certPath) {
98
+ const isInstalled = await checkCertInstalled(certPath);
99
+ if (!isInstalled) {
100
+ console.log("Certificate not found in system store");
101
+ return;
102
+ }
103
+
104
+ if (IS_WIN) {
105
+ await uninstallCertWindows();
106
+ } else {
107
+ await uninstallCertMac(sudoPassword, certPath);
108
+ }
109
+ }
110
+
111
+ async function uninstallCertMac(sudoPassword, certPath) {
112
+ const fingerprint = getCertFingerprint(certPath).replace(/:/g, "");
113
+ const command = `security delete-certificate -Z "${fingerprint}" /Library/Keychains/System.keychain`;
114
+ try {
115
+ await execWithPassword(command, sudoPassword);
116
+ console.log("✅ Uninstalled certificate from system keychain");
117
+ } catch (err) {
118
+ throw new Error("Failed to uninstall certificate");
119
+ }
120
+ }
121
+
122
+ async function uninstallCertWindows() {
123
+ const psCommand = `Start-Process certutil -ArgumentList '-delstore','Root','daily-cloudcode-pa.googleapis.com' -Verb RunAs -Wait`;
124
+ return new Promise((resolve, reject) => {
125
+ exec(`powershell -Command "${psCommand}"`, (error) => {
126
+ if (error) {
127
+ reject(new Error(`Failed to uninstall certificate: ${error.message}`));
128
+ } else {
129
+ console.log("✅ Uninstalled certificate from Windows Root store");
130
+ resolve();
131
+ }
132
+ });
133
+ });
134
+ }
135
+
136
+ module.exports = { installCert, uninstallCert, checkCertInstalled };
@@ -0,0 +1,130 @@
1
+ const { exec, spawn } = require("child_process");
2
+ const fs = require("fs");
3
+ const path = require("path");
4
+
5
+ const TARGET_HOST = "daily-cloudcode-pa.googleapis.com";
6
+ const IS_WIN = process.platform === "win32";
7
+ const HOSTS_FILE = IS_WIN
8
+ ? path.join(process.env.SystemRoot || "C:\\Windows", "System32", "drivers", "etc", "hosts")
9
+ : "/etc/hosts";
10
+
11
+ /**
12
+ * Execute command with sudo password via stdin (macOS/Linux only)
13
+ */
14
+ function execWithPassword(command, password) {
15
+ return new Promise((resolve, reject) => {
16
+ const child = spawn("sudo", ["-S", "sh", "-c", command], {
17
+ stdio: ["pipe", "pipe", "pipe"]
18
+ });
19
+
20
+ let stdout = "";
21
+ let stderr = "";
22
+ child.stdout.on("data", (d) => { stdout += d; });
23
+ child.stderr.on("data", (d) => { stderr += d; });
24
+
25
+ child.on("close", (code) => {
26
+ if (code === 0) resolve(stdout);
27
+ else reject(new Error(stderr || `Exit code ${code}`));
28
+ });
29
+
30
+ child.stdin.write(`${password}\n`);
31
+ child.stdin.end();
32
+ });
33
+ }
34
+
35
+ /**
36
+ * Execute elevated command on Windows via PowerShell RunAs
37
+ */
38
+ function execElevatedWindows(command) {
39
+ return new Promise((resolve, reject) => {
40
+ const psCommand = `Start-Process cmd -ArgumentList '/c','${command.replace(/'/g, "''")}' -Verb RunAs -Wait`;
41
+ exec(`powershell -Command "${psCommand}"`, (error, stdout, stderr) => {
42
+ if (error) {
43
+ reject(new Error(`Elevated command failed: ${error.message}\n${stderr}`));
44
+ } else {
45
+ resolve(stdout);
46
+ }
47
+ });
48
+ });
49
+ }
50
+
51
+ /**
52
+ * Check if DNS entry already exists
53
+ */
54
+ function checkDNSEntry() {
55
+ try {
56
+ const hostsContent = fs.readFileSync(HOSTS_FILE, "utf8");
57
+ return hostsContent.includes(TARGET_HOST);
58
+ } catch {
59
+ return false;
60
+ }
61
+ }
62
+
63
+ /**
64
+ * Add DNS entry to hosts file
65
+ */
66
+ async function addDNSEntry(sudoPassword) {
67
+ if (checkDNSEntry()) {
68
+ console.log(`DNS entry for ${TARGET_HOST} already exists`);
69
+ return;
70
+ }
71
+
72
+ const entry = `127.0.0.1 ${TARGET_HOST}`;
73
+
74
+ try {
75
+ if (IS_WIN) {
76
+ // Windows: use elevated echo >> hosts
77
+ await execElevatedWindows(`echo ${entry} >> "${HOSTS_FILE}"`);
78
+ } else {
79
+ await execWithPassword(`echo "${entry}" >> ${HOSTS_FILE}`, sudoPassword);
80
+ }
81
+ // Flush DNS cache
82
+ if (IS_WIN) {
83
+ await execElevatedWindows("ipconfig /flushdns");
84
+ } else {
85
+ await execWithPassword("dscacheutil -flushcache && killall -HUP mDNSResponder", sudoPassword);
86
+ }
87
+ console.log(`✅ Added DNS entry: ${entry}`);
88
+ } catch (error) {
89
+ const msg = error.message?.includes("incorrect password") ? "Wrong sudo password" : "Failed to add DNS entry";
90
+ throw new Error(msg);
91
+ }
92
+ }
93
+
94
+ /**
95
+ * Remove DNS entry from hosts file
96
+ */
97
+ async function removeDNSEntry(sudoPassword) {
98
+ if (!checkDNSEntry()) {
99
+ console.log(`DNS entry for ${TARGET_HOST} does not exist`);
100
+ return;
101
+ }
102
+
103
+ try {
104
+ if (IS_WIN) {
105
+ // Windows: read, filter, write back via elevated PowerShell
106
+ const psScript = `(Get-Content '${HOSTS_FILE}') | Where-Object { $_ -notmatch '${TARGET_HOST}' } | Set-Content '${HOSTS_FILE}'`;
107
+ const psCommand = `Start-Process powershell -ArgumentList '-Command','${psScript.replace(/'/g, "''")}' -Verb RunAs -Wait`;
108
+ await new Promise((resolve, reject) => {
109
+ exec(`powershell -Command "${psCommand}"`, (error) => {
110
+ if (error) reject(new Error(`Failed to remove DNS entry: ${error.message}`));
111
+ else resolve();
112
+ });
113
+ });
114
+ } else {
115
+ await execWithPassword(`sed -i '' '/${TARGET_HOST}/d' ${HOSTS_FILE}`, sudoPassword);
116
+ }
117
+ // Flush DNS cache
118
+ if (IS_WIN) {
119
+ await execElevatedWindows("ipconfig /flushdns");
120
+ } else {
121
+ await execWithPassword("dscacheutil -flushcache && killall -HUP mDNSResponder", sudoPassword);
122
+ }
123
+ console.log(`✅ Removed DNS entry for ${TARGET_HOST}`);
124
+ } catch (error) {
125
+ const msg = error.message?.includes("incorrect password") ? "Wrong sudo password" : "Failed to remove DNS entry";
126
+ throw new Error(msg);
127
+ }
128
+ }
129
+
130
+ module.exports = { addDNSEntry, removeDNSEntry, execWithPassword, checkDNSEntry };
@@ -0,0 +1,227 @@
1
+ const { spawn } = require("child_process");
2
+ const path = require("path");
3
+ const fs = require("fs");
4
+ const os = require("os");
5
+ const { addDNSEntry, removeDNSEntry } = require("./dns/dnsConfig");
6
+ const { generateCert } = require("./cert/generate");
7
+ const { installCert } = require("./cert/install");
8
+
9
+ // Store server process
10
+ let serverProcess = null;
11
+ let serverPid = null;
12
+ // Persist across Next.js hot reloads
13
+ function getCachedPassword() { return globalThis.__mitmSudoPassword || null; }
14
+ function setCachedPassword(pwd) { globalThis.__mitmSudoPassword = pwd; }
15
+
16
+ // server.js is in same directory as this file
17
+ const PID_FILE = path.join(os.homedir(), ".9router", "mitm", ".mitm.pid");
18
+
19
+ // Check if a PID is alive
20
+ function isProcessAlive(pid) {
21
+ try {
22
+ process.kill(pid, 0);
23
+ return true;
24
+ } catch {
25
+ return false;
26
+ }
27
+ }
28
+
29
+ /**
30
+ * Get MITM status
31
+ */
32
+ async function getMitmStatus() {
33
+ // Check in-memory process first, then fallback to PID file
34
+ let running = serverProcess !== null && !serverProcess.killed;
35
+ let pid = serverPid;
36
+
37
+ if (!running) {
38
+ try {
39
+ if (fs.existsSync(PID_FILE)) {
40
+ const savedPid = parseInt(fs.readFileSync(PID_FILE, "utf-8").trim(), 10);
41
+ if (savedPid && isProcessAlive(savedPid)) {
42
+ running = true;
43
+ pid = savedPid;
44
+ } else {
45
+ // Stale PID file, clean up
46
+ fs.unlinkSync(PID_FILE);
47
+ }
48
+ }
49
+ } catch {
50
+ // Ignore
51
+ }
52
+ }
53
+
54
+ // Check DNS configuration
55
+ let dnsConfigured = false;
56
+ try {
57
+ const hostsContent = fs.readFileSync("/etc/hosts", "utf-8");
58
+ dnsConfigured = hostsContent.includes("daily-cloudcode-pa.googleapis.com");
59
+ } catch {
60
+ // Ignore
61
+ }
62
+
63
+ // Check cert
64
+ const certDir = path.join(os.homedir(), ".9router", "mitm");
65
+ const certExists = fs.existsSync(path.join(certDir, "server.crt"));
66
+
67
+ return { running, pid, dnsConfigured, certExists };
68
+ }
69
+
70
+ /**
71
+ * Start MITM proxy
72
+ * @param {string} apiKey - 9Router API key
73
+ * @param {string} sudoPassword - Sudo password for DNS/cert operations
74
+ */
75
+ async function startMitm(apiKey, sudoPassword) {
76
+ // Check if already running
77
+ if (serverProcess && !serverProcess.killed) {
78
+ throw new Error("MITM proxy is already running");
79
+ }
80
+
81
+ // 1. Generate SSL certificate if not exists
82
+ const certPath = path.join(os.homedir(), ".9router", "mitm", "server.crt");
83
+ if (!fs.existsSync(certPath)) {
84
+ console.log("Generating SSL certificate...");
85
+ await generateCert();
86
+ }
87
+
88
+ // 2. Install certificate to system keychain
89
+ await installCert(sudoPassword, certPath);
90
+
91
+ // 3. Add DNS entry
92
+ console.log("Adding DNS entry...");
93
+ await addDNSEntry(sudoPassword);
94
+
95
+ // 4. Start MITM server
96
+ console.log("Starting MITM server...");
97
+ const serverPath = path.join(process.cwd(), "src/mitm/server.js");
98
+ serverProcess = spawn("node", [serverPath], {
99
+ env: {
100
+ ...process.env,
101
+ ROUTER_API_KEY: apiKey,
102
+ NODE_ENV: "production"
103
+ },
104
+ detached: false,
105
+ stdio: ["ignore", "pipe", "pipe"]
106
+ });
107
+
108
+ serverPid = serverProcess.pid;
109
+
110
+ // Save PID to file
111
+ fs.writeFileSync(PID_FILE, String(serverPid));
112
+
113
+ // Log server output
114
+ serverProcess.stdout.on("data", (data) => {
115
+ console.log(`[MITM Server] ${data.toString().trim()}`);
116
+ });
117
+
118
+ serverProcess.stderr.on("data", (data) => {
119
+ console.error(`[MITM Server Error] ${data.toString().trim()}`);
120
+ });
121
+
122
+ serverProcess.on("exit", (code) => {
123
+ console.log(`MITM server exited with code ${code}`);
124
+ serverProcess = null;
125
+ serverPid = null;
126
+
127
+ // Remove PID file
128
+ try {
129
+ fs.unlinkSync(PID_FILE);
130
+ } catch (error) {
131
+ // Ignore
132
+ }
133
+ });
134
+
135
+ // Wait and verify server actually started
136
+ const started = await new Promise((resolve) => {
137
+ let resolved = false;
138
+ const timeout = setTimeout(() => {
139
+ if (!resolved) { resolved = true; resolve(true); }
140
+ }, 2000);
141
+
142
+ serverProcess.on("exit", (code) => {
143
+ clearTimeout(timeout);
144
+ if (!resolved) { resolved = true; resolve(false); }
145
+ });
146
+
147
+ // Check stderr for error messages
148
+ serverProcess.stderr.on("data", (data) => {
149
+ const msg = data.toString().trim();
150
+ if (msg.includes("Port") && msg.includes("already in use")) {
151
+ clearTimeout(timeout);
152
+ if (!resolved) { resolved = true; resolve(false); }
153
+ }
154
+ });
155
+ });
156
+
157
+ if (!started) {
158
+ throw new Error("MITM server failed to start (port 443 may be in use)");
159
+ }
160
+
161
+ return {
162
+ running: true,
163
+ pid: serverPid
164
+ };
165
+ }
166
+
167
+ /**
168
+ * Stop MITM proxy
169
+ * @param {string} sudoPassword - Sudo password for DNS cleanup
170
+ */
171
+ async function stopMitm(sudoPassword) {
172
+ // 1. Kill server process (in-memory or from PID file)
173
+ const proc = serverProcess;
174
+ if (proc && !proc.killed) {
175
+ console.log("Stopping MITM server...");
176
+ proc.kill("SIGTERM");
177
+ await new Promise(resolve => setTimeout(resolve, 1000));
178
+ if (!proc.killed) {
179
+ proc.kill("SIGKILL");
180
+ }
181
+ serverProcess = null;
182
+ serverPid = null;
183
+ } else {
184
+ // Fallback: kill by PID file
185
+ try {
186
+ if (fs.existsSync(PID_FILE)) {
187
+ const savedPid = parseInt(fs.readFileSync(PID_FILE, "utf-8").trim(), 10);
188
+ if (savedPid && isProcessAlive(savedPid)) {
189
+ console.log(`Killing MITM server (PID: ${savedPid})...`);
190
+ process.kill(savedPid, "SIGTERM");
191
+ await new Promise(resolve => setTimeout(resolve, 1000));
192
+ if (isProcessAlive(savedPid)) {
193
+ process.kill(savedPid, "SIGKILL");
194
+ }
195
+ }
196
+ }
197
+ } catch {
198
+ // Ignore
199
+ }
200
+ serverProcess = null;
201
+ serverPid = null;
202
+ }
203
+
204
+ // 2. Remove DNS entry
205
+ console.log("Removing DNS entry...");
206
+ await removeDNSEntry(sudoPassword);
207
+
208
+ // 3. Remove PID file
209
+ try {
210
+ fs.unlinkSync(PID_FILE);
211
+ } catch (error) {
212
+ // Ignore
213
+ }
214
+
215
+ return {
216
+ running: false,
217
+ pid: null
218
+ };
219
+ }
220
+
221
+ module.exports = {
222
+ getMitmStatus,
223
+ startMitm,
224
+ stopMitm,
225
+ getCachedPassword,
226
+ setCachedPassword
227
+ };