zevairouter 1.0.61 → 1.0.65

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 (403) hide show
  1. package/CHANGELOG.md +36 -8
  2. package/README.md +58 -10
  3. package/README.zh-CN.md +37 -0
  4. package/cli/app/.next-cli-build/BUILD_ID +1 -1
  5. package/cli/app/.next-cli-build/app-path-routes-manifest.json +25 -25
  6. package/cli/app/.next-cli-build/build-manifest.json +2 -2
  7. package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/automation/page_client-reference-manifest.js +1 -1
  8. package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/basic-chat/page_client-reference-manifest.js +1 -1
  9. package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/cli-tools/[toolId]/page_client-reference-manifest.js +1 -1
  10. package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/cli-tools/page_client-reference-manifest.js +1 -1
  11. package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/combos/page_client-reference-manifest.js +1 -1
  12. package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/console-log/page_client-reference-manifest.js +1 -1
  13. package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/context/page_client-reference-manifest.js +1 -1
  14. package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/endpoint/page_client-reference-manifest.js +1 -1
  15. package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/[kind]/[id]/page_client-reference-manifest.js +1 -1
  16. package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/[kind]/page_client-reference-manifest.js +1 -1
  17. package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/combo/[id]/page_client-reference-manifest.js +1 -1
  18. package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/web/page_client-reference-manifest.js +1 -1
  19. package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/mitm/page_client-reference-manifest.js +1 -1
  20. package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/page_client-reference-manifest.js +1 -1
  21. package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/playground/page_client-reference-manifest.js +1 -1
  22. package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/profile/page_client-reference-manifest.js +1 -1
  23. package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/providers/[id]/page_client-reference-manifest.js +1 -1
  24. package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/providers/new/page_client-reference-manifest.js +1 -1
  25. package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/providers/page_client-reference-manifest.js +1 -1
  26. package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/proxy-pools/page_client-reference-manifest.js +1 -1
  27. package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/pxpipe/page_client-reference-manifest.js +1 -1
  28. package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/quota/page_client-reference-manifest.js +1 -1
  29. package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/terminal/page_client-reference-manifest.js +1 -1
  30. package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/token-saver/page_client-reference-manifest.js +1 -1
  31. package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/translator/page_client-reference-manifest.js +1 -1
  32. package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/usage/page_client-reference-manifest.js +1 -1
  33. package/cli/app/.next-cli-build/server/app/_global-error/page_client-reference-manifest.js +1 -1
  34. package/cli/app/.next-cli-build/server/app/_global-error.html +1 -1
  35. package/cli/app/.next-cli-build/server/app/_global-error.rsc +1 -1
  36. package/cli/app/.next-cli-build/server/app/_global-error.segments/_full.segment.rsc +1 -1
  37. package/cli/app/.next-cli-build/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  38. package/cli/app/.next-cli-build/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  39. package/cli/app/.next-cli-build/server/app/_global-error.segments/_head.segment.rsc +1 -1
  40. package/cli/app/.next-cli-build/server/app/_global-error.segments/_index.segment.rsc +1 -1
  41. package/cli/app/.next-cli-build/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  42. package/cli/app/.next-cli-build/server/app/_not-found/page_client-reference-manifest.js +1 -1
  43. package/cli/app/.next-cli-build/server/app/_not-found.html +1 -1
  44. package/cli/app/.next-cli-build/server/app/_not-found.rsc +3 -3
  45. package/cli/app/.next-cli-build/server/app/_not-found.segments/_full.segment.rsc +3 -3
  46. package/cli/app/.next-cli-build/server/app/_not-found.segments/_head.segment.rsc +1 -1
  47. package/cli/app/.next-cli-build/server/app/_not-found.segments/_index.segment.rsc +3 -3
  48. package/cli/app/.next-cli-build/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  49. package/cli/app/.next-cli-build/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  50. package/cli/app/.next-cli-build/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  51. package/cli/app/.next-cli-build/server/app/api/models/route.js +1 -1
  52. package/cli/app/.next-cli-build/server/app/api/models/test/route.js +1 -1
  53. package/cli/app/.next-cli-build/server/app/api/oauth/antigravity/bulk-import/[jobId]/cancel/route.js.nft.json +1 -1
  54. package/cli/app/.next-cli-build/server/app/api/oauth/antigravity/bulk-import/[jobId]/manual/[workerId]/route.js.nft.json +1 -1
  55. package/cli/app/.next-cli-build/server/app/api/oauth/antigravity/bulk-import/[jobId]/route.js.nft.json +1 -1
  56. package/cli/app/.next-cli-build/server/app/api/oauth/antigravity/bulk-import/latest/route.js.nft.json +1 -1
  57. package/cli/app/.next-cli-build/server/app/api/oauth/antigravity/bulk-import/route.js.nft.json +1 -1
  58. package/cli/app/.next-cli-build/server/app/api/oauth/autoclaw/bulk-import/[jobId]/cancel/route.js.nft.json +1 -1
  59. package/cli/app/.next-cli-build/server/app/api/oauth/autoclaw/bulk-import/[jobId]/manual/[workerId]/route.js.nft.json +1 -1
  60. package/cli/app/.next-cli-build/server/app/api/oauth/autoclaw/bulk-import/[jobId]/route.js.nft.json +1 -1
  61. package/cli/app/.next-cli-build/server/app/api/oauth/autoclaw/bulk-import/latest/route.js.nft.json +1 -1
  62. package/cli/app/.next-cli-build/server/app/api/oauth/autoclaw/bulk-import/route.js.nft.json +1 -1
  63. package/cli/app/.next-cli-build/server/app/api/oauth/codebuddy/bulk-import/[jobId]/cancel/route.js.nft.json +1 -1
  64. package/cli/app/.next-cli-build/server/app/api/oauth/codebuddy/bulk-import/[jobId]/manual/[workerId]/route.js.nft.json +1 -1
  65. package/cli/app/.next-cli-build/server/app/api/oauth/codebuddy/bulk-import/[jobId]/route.js.nft.json +1 -1
  66. package/cli/app/.next-cli-build/server/app/api/oauth/codebuddy/bulk-import/latest/route.js.nft.json +1 -1
  67. package/cli/app/.next-cli-build/server/app/api/oauth/codebuddy/bulk-import/route.js.nft.json +1 -1
  68. package/cli/app/.next-cli-build/server/app/api/oauth/codebuddy-cn/bulk-import/[jobId]/cancel/route.js +1 -1
  69. package/cli/app/.next-cli-build/server/app/api/oauth/codebuddy-cn/bulk-import/[jobId]/cancel/route.js.nft.json +1 -1
  70. package/cli/app/.next-cli-build/server/app/api/oauth/codebuddy-cn/bulk-import/[jobId]/manual/[workerId]/route.js +1 -1
  71. package/cli/app/.next-cli-build/server/app/api/oauth/codebuddy-cn/bulk-import/[jobId]/manual/[workerId]/route.js.nft.json +1 -1
  72. package/cli/app/.next-cli-build/server/app/api/oauth/codebuddy-cn/bulk-import/[jobId]/route.js +1 -1
  73. package/cli/app/.next-cli-build/server/app/api/oauth/codebuddy-cn/bulk-import/[jobId]/route.js.nft.json +1 -1
  74. package/cli/app/.next-cli-build/server/app/api/oauth/codebuddy-cn/bulk-import/latest/route.js +1 -1
  75. package/cli/app/.next-cli-build/server/app/api/oauth/codebuddy-cn/bulk-import/latest/route.js.nft.json +1 -1
  76. package/cli/app/.next-cli-build/server/app/api/oauth/codebuddy-cn/bulk-import/route.js +1 -1
  77. package/cli/app/.next-cli-build/server/app/api/oauth/codebuddy-cn/bulk-import/route.js.nft.json +1 -1
  78. package/cli/app/.next-cli-build/server/app/api/oauth/grok-cli/bulk-import/[jobId]/cancel/route.js.nft.json +1 -1
  79. package/cli/app/.next-cli-build/server/app/api/oauth/grok-cli/bulk-import/[jobId]/manual/[workerId]/route.js.nft.json +1 -1
  80. package/cli/app/.next-cli-build/server/app/api/oauth/grok-cli/bulk-import/[jobId]/route.js.nft.json +1 -1
  81. package/cli/app/.next-cli-build/server/app/api/oauth/grok-cli/bulk-import/latest/route.js.nft.json +1 -1
  82. package/cli/app/.next-cli-build/server/app/api/oauth/grok-cli/bulk-import/route.js.nft.json +1 -1
  83. package/cli/app/.next-cli-build/server/app/api/oauth/kiro/bulk-import/[jobId]/cancel/route.js.nft.json +1 -1
  84. package/cli/app/.next-cli-build/server/app/api/oauth/kiro/bulk-import/[jobId]/manual/[workerId]/route.js.nft.json +1 -1
  85. package/cli/app/.next-cli-build/server/app/api/oauth/kiro/bulk-import/[jobId]/route.js.nft.json +1 -1
  86. package/cli/app/.next-cli-build/server/app/api/oauth/kiro/bulk-import/latest/route.js.nft.json +1 -1
  87. package/cli/app/.next-cli-build/server/app/api/oauth/kiro/bulk-import/route.js.nft.json +1 -1
  88. package/cli/app/.next-cli-build/server/app/api/oauth/kiro/import/route.js.nft.json +1 -1
  89. package/cli/app/.next-cli-build/server/app/api/oauth/qoder/bulk-import/[jobId]/cancel/route.js.nft.json +1 -1
  90. package/cli/app/.next-cli-build/server/app/api/oauth/qoder/bulk-import/[jobId]/manual/[workerId]/route.js.nft.json +1 -1
  91. package/cli/app/.next-cli-build/server/app/api/oauth/qoder/bulk-import/[jobId]/route.js.nft.json +1 -1
  92. package/cli/app/.next-cli-build/server/app/api/oauth/qoder/bulk-import/latest/route.js.nft.json +1 -1
  93. package/cli/app/.next-cli-build/server/app/api/oauth/qoder/bulk-import/route.js.nft.json +1 -1
  94. package/cli/app/.next-cli-build/server/app/api/providers/[id]/test-models/route.js +1 -1
  95. package/cli/app/.next-cli-build/server/app/api/providers/route.js +1 -1
  96. package/cli/app/.next-cli-build/server/app/api/providers/validate/route.js +1 -1
  97. package/cli/app/.next-cli-build/server/app/api/settings/database/route.js +1 -1
  98. package/cli/app/.next-cli-build/server/app/api/settings/route.js +1 -1
  99. package/cli/app/.next-cli-build/server/app/api/terminal/session/[id]/input/route.js.nft.json +1 -1
  100. package/cli/app/.next-cli-build/server/app/api/terminal/session/[id]/resize/route.js.nft.json +1 -1
  101. package/cli/app/.next-cli-build/server/app/api/terminal/session/[id]/route.js.nft.json +1 -1
  102. package/cli/app/.next-cli-build/server/app/api/terminal/session/[id]/stream/route.js.nft.json +1 -1
  103. package/cli/app/.next-cli-build/server/app/api/terminal/session/route.js.nft.json +1 -1
  104. package/cli/app/.next-cli-build/server/app/api/translator/console-logs/route.js +1 -1
  105. package/cli/app/.next-cli-build/server/app/api/translator/console-logs/stream/route.js +1 -1
  106. package/cli/app/.next-cli-build/server/app/api/version/route.js +1 -1
  107. package/cli/app/.next-cli-build/server/app/api/version/shutdown/route.js +1 -1
  108. package/cli/app/.next-cli-build/server/app/api/version/update/route.js +1 -1
  109. package/cli/app/.next-cli-build/server/app/callback/page_client-reference-manifest.js +1 -1
  110. package/cli/app/.next-cli-build/server/app/callback.html +1 -1
  111. package/cli/app/.next-cli-build/server/app/callback.rsc +3 -3
  112. package/cli/app/.next-cli-build/server/app/callback.segments/_full.segment.rsc +3 -3
  113. package/cli/app/.next-cli-build/server/app/callback.segments/_head.segment.rsc +1 -1
  114. package/cli/app/.next-cli-build/server/app/callback.segments/_index.segment.rsc +3 -3
  115. package/cli/app/.next-cli-build/server/app/callback.segments/_tree.segment.rsc +1 -1
  116. package/cli/app/.next-cli-build/server/app/callback.segments/callback/__PAGE__.segment.rsc +1 -1
  117. package/cli/app/.next-cli-build/server/app/callback.segments/callback.segment.rsc +1 -1
  118. package/cli/app/.next-cli-build/server/app/dashboard/automation.html +1 -1
  119. package/cli/app/.next-cli-build/server/app/dashboard/automation.rsc +5 -5
  120. package/cli/app/.next-cli-build/server/app/dashboard/automation.segments/!KGRhc2hib2FyZCk/dashboard/automation/__PAGE__.segment.rsc +2 -2
  121. package/cli/app/.next-cli-build/server/app/dashboard/automation.segments/!KGRhc2hib2FyZCk/dashboard/automation.segment.rsc +1 -1
  122. package/cli/app/.next-cli-build/server/app/dashboard/automation.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  123. package/cli/app/.next-cli-build/server/app/dashboard/automation.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  124. package/cli/app/.next-cli-build/server/app/dashboard/automation.segments/_full.segment.rsc +5 -5
  125. package/cli/app/.next-cli-build/server/app/dashboard/automation.segments/_head.segment.rsc +1 -1
  126. package/cli/app/.next-cli-build/server/app/dashboard/automation.segments/_index.segment.rsc +3 -3
  127. package/cli/app/.next-cli-build/server/app/dashboard/automation.segments/_tree.segment.rsc +1 -1
  128. package/cli/app/.next-cli-build/server/app/dashboard/basic-chat.html +1 -1
  129. package/cli/app/.next-cli-build/server/app/dashboard/basic-chat.rsc +5 -5
  130. package/cli/app/.next-cli-build/server/app/dashboard/basic-chat.segments/!KGRhc2hib2FyZCk/dashboard/basic-chat/__PAGE__.segment.rsc +2 -2
  131. package/cli/app/.next-cli-build/server/app/dashboard/basic-chat.segments/!KGRhc2hib2FyZCk/dashboard/basic-chat.segment.rsc +1 -1
  132. package/cli/app/.next-cli-build/server/app/dashboard/basic-chat.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  133. package/cli/app/.next-cli-build/server/app/dashboard/basic-chat.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  134. package/cli/app/.next-cli-build/server/app/dashboard/basic-chat.segments/_full.segment.rsc +5 -5
  135. package/cli/app/.next-cli-build/server/app/dashboard/basic-chat.segments/_head.segment.rsc +1 -1
  136. package/cli/app/.next-cli-build/server/app/dashboard/basic-chat.segments/_index.segment.rsc +3 -3
  137. package/cli/app/.next-cli-build/server/app/dashboard/basic-chat.segments/_tree.segment.rsc +1 -1
  138. package/cli/app/.next-cli-build/server/app/dashboard/cli-tools.html +1 -1
  139. package/cli/app/.next-cli-build/server/app/dashboard/cli-tools.rsc +5 -5
  140. package/cli/app/.next-cli-build/server/app/dashboard/cli-tools.segments/!KGRhc2hib2FyZCk/dashboard/cli-tools/__PAGE__.segment.rsc +2 -2
  141. package/cli/app/.next-cli-build/server/app/dashboard/cli-tools.segments/!KGRhc2hib2FyZCk/dashboard/cli-tools.segment.rsc +1 -1
  142. package/cli/app/.next-cli-build/server/app/dashboard/cli-tools.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  143. package/cli/app/.next-cli-build/server/app/dashboard/cli-tools.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  144. package/cli/app/.next-cli-build/server/app/dashboard/cli-tools.segments/_full.segment.rsc +5 -5
  145. package/cli/app/.next-cli-build/server/app/dashboard/cli-tools.segments/_head.segment.rsc +1 -1
  146. package/cli/app/.next-cli-build/server/app/dashboard/cli-tools.segments/_index.segment.rsc +3 -3
  147. package/cli/app/.next-cli-build/server/app/dashboard/cli-tools.segments/_tree.segment.rsc +1 -1
  148. package/cli/app/.next-cli-build/server/app/dashboard/combos.html +1 -1
  149. package/cli/app/.next-cli-build/server/app/dashboard/combos.rsc +5 -5
  150. package/cli/app/.next-cli-build/server/app/dashboard/combos.segments/!KGRhc2hib2FyZCk/dashboard/combos/__PAGE__.segment.rsc +2 -2
  151. package/cli/app/.next-cli-build/server/app/dashboard/combos.segments/!KGRhc2hib2FyZCk/dashboard/combos.segment.rsc +1 -1
  152. package/cli/app/.next-cli-build/server/app/dashboard/combos.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  153. package/cli/app/.next-cli-build/server/app/dashboard/combos.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  154. package/cli/app/.next-cli-build/server/app/dashboard/combos.segments/_full.segment.rsc +5 -5
  155. package/cli/app/.next-cli-build/server/app/dashboard/combos.segments/_head.segment.rsc +1 -1
  156. package/cli/app/.next-cli-build/server/app/dashboard/combos.segments/_index.segment.rsc +3 -3
  157. package/cli/app/.next-cli-build/server/app/dashboard/combos.segments/_tree.segment.rsc +1 -1
  158. package/cli/app/.next-cli-build/server/app/dashboard/context.html +1 -1
  159. package/cli/app/.next-cli-build/server/app/dashboard/context.rsc +5 -5
  160. package/cli/app/.next-cli-build/server/app/dashboard/context.segments/!KGRhc2hib2FyZCk/dashboard/context/__PAGE__.segment.rsc +2 -2
  161. package/cli/app/.next-cli-build/server/app/dashboard/context.segments/!KGRhc2hib2FyZCk/dashboard/context.segment.rsc +1 -1
  162. package/cli/app/.next-cli-build/server/app/dashboard/context.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  163. package/cli/app/.next-cli-build/server/app/dashboard/context.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  164. package/cli/app/.next-cli-build/server/app/dashboard/context.segments/_full.segment.rsc +5 -5
  165. package/cli/app/.next-cli-build/server/app/dashboard/context.segments/_head.segment.rsc +1 -1
  166. package/cli/app/.next-cli-build/server/app/dashboard/context.segments/_index.segment.rsc +3 -3
  167. package/cli/app/.next-cli-build/server/app/dashboard/context.segments/_tree.segment.rsc +1 -1
  168. package/cli/app/.next-cli-build/server/app/dashboard/endpoint.html +1 -1
  169. package/cli/app/.next-cli-build/server/app/dashboard/endpoint.rsc +5 -5
  170. package/cli/app/.next-cli-build/server/app/dashboard/endpoint.segments/!KGRhc2hib2FyZCk/dashboard/endpoint/__PAGE__.segment.rsc +2 -2
  171. package/cli/app/.next-cli-build/server/app/dashboard/endpoint.segments/!KGRhc2hib2FyZCk/dashboard/endpoint.segment.rsc +1 -1
  172. package/cli/app/.next-cli-build/server/app/dashboard/endpoint.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  173. package/cli/app/.next-cli-build/server/app/dashboard/endpoint.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  174. package/cli/app/.next-cli-build/server/app/dashboard/endpoint.segments/_full.segment.rsc +5 -5
  175. package/cli/app/.next-cli-build/server/app/dashboard/endpoint.segments/_head.segment.rsc +1 -1
  176. package/cli/app/.next-cli-build/server/app/dashboard/endpoint.segments/_index.segment.rsc +3 -3
  177. package/cli/app/.next-cli-build/server/app/dashboard/endpoint.segments/_tree.segment.rsc +1 -1
  178. package/cli/app/.next-cli-build/server/app/dashboard/media-providers/web.html +1 -1
  179. package/cli/app/.next-cli-build/server/app/dashboard/media-providers/web.rsc +5 -5
  180. package/cli/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/!KGRhc2hib2FyZCk/dashboard/media-providers/web/__PAGE__.segment.rsc +2 -2
  181. package/cli/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/!KGRhc2hib2FyZCk/dashboard/media-providers/web.segment.rsc +1 -1
  182. package/cli/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/!KGRhc2hib2FyZCk/dashboard/media-providers.segment.rsc +1 -1
  183. package/cli/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  184. package/cli/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  185. package/cli/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/_full.segment.rsc +5 -5
  186. package/cli/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/_head.segment.rsc +1 -1
  187. package/cli/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/_index.segment.rsc +3 -3
  188. package/cli/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/_tree.segment.rsc +1 -1
  189. package/cli/app/.next-cli-build/server/app/dashboard/mitm.html +1 -1
  190. package/cli/app/.next-cli-build/server/app/dashboard/mitm.rsc +5 -5
  191. package/cli/app/.next-cli-build/server/app/dashboard/mitm.segments/!KGRhc2hib2FyZCk/dashboard/mitm/__PAGE__.segment.rsc +2 -2
  192. package/cli/app/.next-cli-build/server/app/dashboard/mitm.segments/!KGRhc2hib2FyZCk/dashboard/mitm.segment.rsc +1 -1
  193. package/cli/app/.next-cli-build/server/app/dashboard/mitm.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  194. package/cli/app/.next-cli-build/server/app/dashboard/mitm.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  195. package/cli/app/.next-cli-build/server/app/dashboard/mitm.segments/_full.segment.rsc +5 -5
  196. package/cli/app/.next-cli-build/server/app/dashboard/mitm.segments/_head.segment.rsc +1 -1
  197. package/cli/app/.next-cli-build/server/app/dashboard/mitm.segments/_index.segment.rsc +3 -3
  198. package/cli/app/.next-cli-build/server/app/dashboard/mitm.segments/_tree.segment.rsc +1 -1
  199. package/cli/app/.next-cli-build/server/app/dashboard/playground.html +1 -1
  200. package/cli/app/.next-cli-build/server/app/dashboard/playground.rsc +5 -5
  201. package/cli/app/.next-cli-build/server/app/dashboard/playground.segments/!KGRhc2hib2FyZCk/dashboard/playground/__PAGE__.segment.rsc +2 -2
  202. package/cli/app/.next-cli-build/server/app/dashboard/playground.segments/!KGRhc2hib2FyZCk/dashboard/playground.segment.rsc +1 -1
  203. package/cli/app/.next-cli-build/server/app/dashboard/playground.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  204. package/cli/app/.next-cli-build/server/app/dashboard/playground.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  205. package/cli/app/.next-cli-build/server/app/dashboard/playground.segments/_full.segment.rsc +5 -5
  206. package/cli/app/.next-cli-build/server/app/dashboard/playground.segments/_head.segment.rsc +1 -1
  207. package/cli/app/.next-cli-build/server/app/dashboard/playground.segments/_index.segment.rsc +3 -3
  208. package/cli/app/.next-cli-build/server/app/dashboard/playground.segments/_tree.segment.rsc +1 -1
  209. package/cli/app/.next-cli-build/server/app/dashboard/profile.html +1 -1
  210. package/cli/app/.next-cli-build/server/app/dashboard/profile.rsc +5 -5
  211. package/cli/app/.next-cli-build/server/app/dashboard/profile.segments/!KGRhc2hib2FyZCk/dashboard/profile/__PAGE__.segment.rsc +2 -2
  212. package/cli/app/.next-cli-build/server/app/dashboard/profile.segments/!KGRhc2hib2FyZCk/dashboard/profile.segment.rsc +1 -1
  213. package/cli/app/.next-cli-build/server/app/dashboard/profile.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  214. package/cli/app/.next-cli-build/server/app/dashboard/profile.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  215. package/cli/app/.next-cli-build/server/app/dashboard/profile.segments/_full.segment.rsc +5 -5
  216. package/cli/app/.next-cli-build/server/app/dashboard/profile.segments/_head.segment.rsc +1 -1
  217. package/cli/app/.next-cli-build/server/app/dashboard/profile.segments/_index.segment.rsc +3 -3
  218. package/cli/app/.next-cli-build/server/app/dashboard/profile.segments/_tree.segment.rsc +1 -1
  219. package/cli/app/.next-cli-build/server/app/dashboard/providers/new.html +1 -1
  220. package/cli/app/.next-cli-build/server/app/dashboard/providers/new.rsc +5 -5
  221. package/cli/app/.next-cli-build/server/app/dashboard/providers/new.segments/!KGRhc2hib2FyZCk/dashboard/providers/new/__PAGE__.segment.rsc +2 -2
  222. package/cli/app/.next-cli-build/server/app/dashboard/providers/new.segments/!KGRhc2hib2FyZCk/dashboard/providers/new.segment.rsc +1 -1
  223. package/cli/app/.next-cli-build/server/app/dashboard/providers/new.segments/!KGRhc2hib2FyZCk/dashboard/providers.segment.rsc +1 -1
  224. package/cli/app/.next-cli-build/server/app/dashboard/providers/new.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  225. package/cli/app/.next-cli-build/server/app/dashboard/providers/new.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  226. package/cli/app/.next-cli-build/server/app/dashboard/providers/new.segments/_full.segment.rsc +5 -5
  227. package/cli/app/.next-cli-build/server/app/dashboard/providers/new.segments/_head.segment.rsc +1 -1
  228. package/cli/app/.next-cli-build/server/app/dashboard/providers/new.segments/_index.segment.rsc +3 -3
  229. package/cli/app/.next-cli-build/server/app/dashboard/providers/new.segments/_tree.segment.rsc +1 -1
  230. package/cli/app/.next-cli-build/server/app/dashboard/providers.html +1 -1
  231. package/cli/app/.next-cli-build/server/app/dashboard/providers.rsc +5 -5
  232. package/cli/app/.next-cli-build/server/app/dashboard/providers.segments/!KGRhc2hib2FyZCk/dashboard/providers/__PAGE__.segment.rsc +2 -2
  233. package/cli/app/.next-cli-build/server/app/dashboard/providers.segments/!KGRhc2hib2FyZCk/dashboard/providers.segment.rsc +1 -1
  234. package/cli/app/.next-cli-build/server/app/dashboard/providers.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  235. package/cli/app/.next-cli-build/server/app/dashboard/providers.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  236. package/cli/app/.next-cli-build/server/app/dashboard/providers.segments/_full.segment.rsc +5 -5
  237. package/cli/app/.next-cli-build/server/app/dashboard/providers.segments/_head.segment.rsc +1 -1
  238. package/cli/app/.next-cli-build/server/app/dashboard/providers.segments/_index.segment.rsc +3 -3
  239. package/cli/app/.next-cli-build/server/app/dashboard/providers.segments/_tree.segment.rsc +1 -1
  240. package/cli/app/.next-cli-build/server/app/dashboard/proxy-pools.html +1 -1
  241. package/cli/app/.next-cli-build/server/app/dashboard/proxy-pools.rsc +5 -5
  242. package/cli/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/!KGRhc2hib2FyZCk/dashboard/proxy-pools/__PAGE__.segment.rsc +2 -2
  243. package/cli/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/!KGRhc2hib2FyZCk/dashboard/proxy-pools.segment.rsc +1 -1
  244. package/cli/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  245. package/cli/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  246. package/cli/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/_full.segment.rsc +5 -5
  247. package/cli/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/_head.segment.rsc +1 -1
  248. package/cli/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/_index.segment.rsc +3 -3
  249. package/cli/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/_tree.segment.rsc +1 -1
  250. package/cli/app/.next-cli-build/server/app/dashboard/pxpipe.html +1 -1
  251. package/cli/app/.next-cli-build/server/app/dashboard/pxpipe.rsc +5 -5
  252. package/cli/app/.next-cli-build/server/app/dashboard/pxpipe.segments/!KGRhc2hib2FyZCk/dashboard/pxpipe/__PAGE__.segment.rsc +2 -2
  253. package/cli/app/.next-cli-build/server/app/dashboard/pxpipe.segments/!KGRhc2hib2FyZCk/dashboard/pxpipe.segment.rsc +1 -1
  254. package/cli/app/.next-cli-build/server/app/dashboard/pxpipe.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  255. package/cli/app/.next-cli-build/server/app/dashboard/pxpipe.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  256. package/cli/app/.next-cli-build/server/app/dashboard/pxpipe.segments/_full.segment.rsc +5 -5
  257. package/cli/app/.next-cli-build/server/app/dashboard/pxpipe.segments/_head.segment.rsc +1 -1
  258. package/cli/app/.next-cli-build/server/app/dashboard/pxpipe.segments/_index.segment.rsc +3 -3
  259. package/cli/app/.next-cli-build/server/app/dashboard/pxpipe.segments/_tree.segment.rsc +1 -1
  260. package/cli/app/.next-cli-build/server/app/dashboard/quota.html +2 -2
  261. package/cli/app/.next-cli-build/server/app/dashboard/quota.rsc +6 -6
  262. package/cli/app/.next-cli-build/server/app/dashboard/quota.segments/!KGRhc2hib2FyZCk/dashboard/quota/__PAGE__.segment.rsc +3 -3
  263. package/cli/app/.next-cli-build/server/app/dashboard/quota.segments/!KGRhc2hib2FyZCk/dashboard/quota.segment.rsc +1 -1
  264. package/cli/app/.next-cli-build/server/app/dashboard/quota.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  265. package/cli/app/.next-cli-build/server/app/dashboard/quota.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  266. package/cli/app/.next-cli-build/server/app/dashboard/quota.segments/_full.segment.rsc +6 -6
  267. package/cli/app/.next-cli-build/server/app/dashboard/quota.segments/_head.segment.rsc +1 -1
  268. package/cli/app/.next-cli-build/server/app/dashboard/quota.segments/_index.segment.rsc +3 -3
  269. package/cli/app/.next-cli-build/server/app/dashboard/quota.segments/_tree.segment.rsc +1 -1
  270. package/cli/app/.next-cli-build/server/app/dashboard/settings/pricing/page_client-reference-manifest.js +1 -1
  271. package/cli/app/.next-cli-build/server/app/dashboard/settings/pricing.html +1 -1
  272. package/cli/app/.next-cli-build/server/app/dashboard/settings/pricing.rsc +3 -3
  273. package/cli/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/_full.segment.rsc +3 -3
  274. package/cli/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/_head.segment.rsc +1 -1
  275. package/cli/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/_index.segment.rsc +3 -3
  276. package/cli/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/_tree.segment.rsc +1 -1
  277. package/cli/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/dashboard/settings/pricing/__PAGE__.segment.rsc +1 -1
  278. package/cli/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/dashboard/settings/pricing.segment.rsc +1 -1
  279. package/cli/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/dashboard/settings.segment.rsc +1 -1
  280. package/cli/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/dashboard.segment.rsc +1 -1
  281. package/cli/app/.next-cli-build/server/app/dashboard/token-saver.html +1 -1
  282. package/cli/app/.next-cli-build/server/app/dashboard/token-saver.rsc +5 -5
  283. package/cli/app/.next-cli-build/server/app/dashboard/token-saver.segments/!KGRhc2hib2FyZCk/dashboard/token-saver/__PAGE__.segment.rsc +2 -2
  284. package/cli/app/.next-cli-build/server/app/dashboard/token-saver.segments/!KGRhc2hib2FyZCk/dashboard/token-saver.segment.rsc +1 -1
  285. package/cli/app/.next-cli-build/server/app/dashboard/token-saver.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  286. package/cli/app/.next-cli-build/server/app/dashboard/token-saver.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  287. package/cli/app/.next-cli-build/server/app/dashboard/token-saver.segments/_full.segment.rsc +5 -5
  288. package/cli/app/.next-cli-build/server/app/dashboard/token-saver.segments/_head.segment.rsc +1 -1
  289. package/cli/app/.next-cli-build/server/app/dashboard/token-saver.segments/_index.segment.rsc +3 -3
  290. package/cli/app/.next-cli-build/server/app/dashboard/token-saver.segments/_tree.segment.rsc +1 -1
  291. package/cli/app/.next-cli-build/server/app/dashboard/translator.html +1 -1
  292. package/cli/app/.next-cli-build/server/app/dashboard/translator.rsc +5 -5
  293. package/cli/app/.next-cli-build/server/app/dashboard/translator.segments/!KGRhc2hib2FyZCk/dashboard/translator/__PAGE__.segment.rsc +2 -2
  294. package/cli/app/.next-cli-build/server/app/dashboard/translator.segments/!KGRhc2hib2FyZCk/dashboard/translator.segment.rsc +1 -1
  295. package/cli/app/.next-cli-build/server/app/dashboard/translator.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  296. package/cli/app/.next-cli-build/server/app/dashboard/translator.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  297. package/cli/app/.next-cli-build/server/app/dashboard/translator.segments/_full.segment.rsc +5 -5
  298. package/cli/app/.next-cli-build/server/app/dashboard/translator.segments/_head.segment.rsc +1 -1
  299. package/cli/app/.next-cli-build/server/app/dashboard/translator.segments/_index.segment.rsc +3 -3
  300. package/cli/app/.next-cli-build/server/app/dashboard/translator.segments/_tree.segment.rsc +1 -1
  301. package/cli/app/.next-cli-build/server/app/dashboard/usage.html +1 -1
  302. package/cli/app/.next-cli-build/server/app/dashboard/usage.rsc +5 -5
  303. package/cli/app/.next-cli-build/server/app/dashboard/usage.segments/!KGRhc2hib2FyZCk/dashboard/usage/__PAGE__.segment.rsc +2 -2
  304. package/cli/app/.next-cli-build/server/app/dashboard/usage.segments/!KGRhc2hib2FyZCk/dashboard/usage.segment.rsc +1 -1
  305. package/cli/app/.next-cli-build/server/app/dashboard/usage.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  306. package/cli/app/.next-cli-build/server/app/dashboard/usage.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  307. package/cli/app/.next-cli-build/server/app/dashboard/usage.segments/_full.segment.rsc +5 -5
  308. package/cli/app/.next-cli-build/server/app/dashboard/usage.segments/_head.segment.rsc +1 -1
  309. package/cli/app/.next-cli-build/server/app/dashboard/usage.segments/_index.segment.rsc +3 -3
  310. package/cli/app/.next-cli-build/server/app/dashboard/usage.segments/_tree.segment.rsc +1 -1
  311. package/cli/app/.next-cli-build/server/app/dashboard.html +1 -1
  312. package/cli/app/.next-cli-build/server/app/dashboard.rsc +5 -5
  313. package/cli/app/.next-cli-build/server/app/dashboard.segments/!KGRhc2hib2FyZCk/dashboard/__PAGE__.segment.rsc +2 -2
  314. package/cli/app/.next-cli-build/server/app/dashboard.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
  315. package/cli/app/.next-cli-build/server/app/dashboard.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
  316. package/cli/app/.next-cli-build/server/app/dashboard.segments/_full.segment.rsc +5 -5
  317. package/cli/app/.next-cli-build/server/app/dashboard.segments/_head.segment.rsc +1 -1
  318. package/cli/app/.next-cli-build/server/app/dashboard.segments/_index.segment.rsc +3 -3
  319. package/cli/app/.next-cli-build/server/app/dashboard.segments/_tree.segment.rsc +1 -1
  320. package/cli/app/.next-cli-build/server/app/index.html +1 -1
  321. package/cli/app/.next-cli-build/server/app/index.rsc +3 -3
  322. package/cli/app/.next-cli-build/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  323. package/cli/app/.next-cli-build/server/app/index.segments/_full.segment.rsc +3 -3
  324. package/cli/app/.next-cli-build/server/app/index.segments/_head.segment.rsc +1 -1
  325. package/cli/app/.next-cli-build/server/app/index.segments/_index.segment.rsc +3 -3
  326. package/cli/app/.next-cli-build/server/app/index.segments/_tree.segment.rsc +1 -1
  327. package/cli/app/.next-cli-build/server/app/landing/page.js +1 -1
  328. package/cli/app/.next-cli-build/server/app/landing/page_client-reference-manifest.js +1 -1
  329. package/cli/app/.next-cli-build/server/app/landing.html +1 -1
  330. package/cli/app/.next-cli-build/server/app/landing.rsc +4 -4
  331. package/cli/app/.next-cli-build/server/app/landing.segments/_full.segment.rsc +4 -4
  332. package/cli/app/.next-cli-build/server/app/landing.segments/_head.segment.rsc +1 -1
  333. package/cli/app/.next-cli-build/server/app/landing.segments/_index.segment.rsc +3 -3
  334. package/cli/app/.next-cli-build/server/app/landing.segments/_tree.segment.rsc +1 -1
  335. package/cli/app/.next-cli-build/server/app/landing.segments/landing/__PAGE__.segment.rsc +2 -2
  336. package/cli/app/.next-cli-build/server/app/landing.segments/landing.segment.rsc +1 -1
  337. package/cli/app/.next-cli-build/server/app/login/page_client-reference-manifest.js +1 -1
  338. package/cli/app/.next-cli-build/server/app/login.html +1 -1
  339. package/cli/app/.next-cli-build/server/app/login.rsc +4 -4
  340. package/cli/app/.next-cli-build/server/app/login.segments/_full.segment.rsc +4 -4
  341. package/cli/app/.next-cli-build/server/app/login.segments/_head.segment.rsc +1 -1
  342. package/cli/app/.next-cli-build/server/app/login.segments/_index.segment.rsc +3 -3
  343. package/cli/app/.next-cli-build/server/app/login.segments/_tree.segment.rsc +1 -1
  344. package/cli/app/.next-cli-build/server/app/login.segments/login/__PAGE__.segment.rsc +2 -2
  345. package/cli/app/.next-cli-build/server/app/login.segments/login.segment.rsc +1 -1
  346. package/cli/app/.next-cli-build/server/app/page_client-reference-manifest.js +1 -1
  347. package/cli/app/.next-cli-build/server/app-paths-manifest.json +25 -25
  348. package/cli/app/.next-cli-build/server/chunks/3110.js +1 -1
  349. package/cli/app/.next-cli-build/server/chunks/3407.js +1 -1
  350. package/cli/app/.next-cli-build/server/chunks/4746.js +1 -1
  351. package/cli/app/.next-cli-build/server/chunks/5681.js +1 -1
  352. package/cli/app/.next-cli-build/server/chunks/5949.js +8 -3
  353. package/cli/app/.next-cli-build/server/chunks/6896.js +1 -1
  354. package/cli/app/.next-cli-build/server/chunks/7276.js +1 -1
  355. package/cli/app/.next-cli-build/server/chunks/8157.js +1 -1
  356. package/cli/app/.next-cli-build/server/chunks/8371.js +1 -1
  357. package/cli/app/.next-cli-build/server/middleware-build-manifest.js +1 -1
  358. package/cli/app/.next-cli-build/server/pages/404.html +1 -1
  359. package/cli/app/.next-cli-build/server/pages/500.html +1 -1
  360. package/cli/app/.next-cli-build/static/chunks/{3702-18f5f207de6e9eeb.js → 3702-a3e0eb456327db63.js} +1 -1
  361. package/cli/app/.next-cli-build/static/chunks/app/landing/page-6621ec8b157e77cc.js +1 -0
  362. package/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/src/lib/terminal/ptyBridge.py +163 -0
  363. package/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/src/lib/terminal/ptyBridge.py +163 -0
  364. package/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/src/lib/terminal/ptyBridge.py +163 -0
  365. package/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/src/lib/terminal/ptyBridge.py +163 -0
  366. package/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/src/lib/terminal/ptyBridge.py +163 -0
  367. package/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/src/lib/terminal/ptyBridge.py +163 -0
  368. package/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/src/lib/terminal/ptyBridge.py +163 -0
  369. package/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/src/lib/terminal/ptyBridge.py +163 -0
  370. package/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/src/lib/terminal/ptyBridge.py +163 -0
  371. package/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/src/lib/terminal/ptyBridge.py +163 -0
  372. package/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/src/lib/terminal/ptyBridge.py +163 -0
  373. package/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/cli/app/src/lib/terminal/ptyBridge.py +163 -0
  374. package/cli/app/cli/hooks/camoufoxRuntime.js +227 -24
  375. package/cli/app/cli/hooks/cloakbrowserRuntime.js +81 -31
  376. package/cli/app/cli/hooks/postinstall.js +3 -3
  377. package/cli/app/package.json +1 -1
  378. package/cli/app/src/lib/oauth/services/displayEnv.js +134 -0
  379. package/cli/hooks/camoufoxRuntime.js +227 -24
  380. package/cli/hooks/cloakbrowserRuntime.js +81 -31
  381. package/cli/hooks/postinstall.js +3 -3
  382. package/cli/package.json +1 -1
  383. package/i18n/README.ja-JP.md +19 -1191
  384. package/i18n/README.ru.md +19 -1293
  385. package/i18n/README.vi.md +19 -1292
  386. package/i18n/README.zh-CN.md +19 -1288
  387. package/open-sse/config/kiroConstants.js +1 -1
  388. package/package.json +1 -1
  389. package/src/app/landing/components/Features.js +2 -2
  390. package/src/app/landing/components/HeroSection.js +1 -1
  391. package/src/app/landing/components/HowItWorks.js +2 -2
  392. package/src/app/landing/page.js +3 -3
  393. package/src/lib/network/outboundProxy.js +37 -23
  394. package/src/lib/oauth/services/bulkImportBrowserEngine.js +220 -22
  395. package/src/lib/oauth/services/codebuddyCnBulkImportManager.js +161 -72
  396. package/src/lib/oauth/services/codebuddyCnPhoneAutomation.js +95 -41
  397. package/src/lib/oauth/services/kiroBulkImportManager.js +18 -13
  398. package/src/mitm/manager.js +1 -1
  399. package/src/shared/constants/providers.js +4 -4
  400. package/cli/app/.next-cli-build/static/chunks/app/landing/page-77b3f78b93a8d0c7.js +0 -1
  401. package/cli/app/src/lib/oauth/services/bulkImportBrowserEngine.js +0 -324
  402. /package/cli/app/.next-cli-build/static/{Fip2gTBHjVyX1dEyiiJZM → UogfdHPvWmU8zuWF5IR-t}/_buildManifest.js +0 -0
  403. /package/cli/app/.next-cli-build/static/{Fip2gTBHjVyX1dEyiiJZM → UogfdHPvWmU8zuWF5IR-t}/_ssgManifest.js +0 -0
@@ -31,7 +31,7 @@ import {
31
31
  } from "./kiroBulkImportManager.js";
32
32
  import { getProxyPools, getProxyPoolById } from "../../../models/index.js";
33
33
  import { getSettings } from "../../localDb.js";
34
- import { getOptimalWorkerCount, isAutoConcurrencyValue } from "../../systemSpecs.js";
34
+ import { getOptimalWorkerCount, getSystemSpecs, isAutoConcurrencyValue } from "../../systemSpecs.js";
35
35
  import { CODEBUDDY_CN_CONFIG } from "../constants/oauth.js";
36
36
  import { FiveSimClient, FiveSimTimeoutError } from "./fiveSimClient.js";
37
37
  import { runCodeBuddyCnPhoneRegistration } from "./codebuddyCnPhoneAutomation.js";
@@ -40,15 +40,18 @@ import {
40
40
  defaultPollForToken,
41
41
  fetchCodeBuddyLoginAccount,
42
42
  } from "./codebuddyBulkImportManager.js";
43
+ import { forceCloseBrowser } from "./bulkImportBrowserEngine.js";
43
44
 
44
45
  const CODEBUDDY_CN_PROVIDER_ID = "codebuddy-cn";
45
46
  const CODEBUDDY_CN_LABEL = "CodeBuddy CN";
46
47
  const CODEBUDDY_CN_DOMAIN = "www.codebuddy.cn";
47
48
 
48
- // Override default concurrency to 2 (5sim rating system keep buys conservative)
49
- const CODEBUDDY_CN_DEFAULT_CONCURRENCY = 2;
49
+ // Default concurrency 1 Camoufox alone can pin a 2GB VPS; multi-worker OOM/hang.
50
+ const CODEBUDDY_CN_DEFAULT_CONCURRENCY = 1;
50
51
  const CODEBUDDY_CN_MAX_CONCURRENCY = 8;
51
52
  const CODEBUDDY_CN_MIN_CONCURRENCY = 1;
53
+ // Hosts under this RAM hard-cap concurrency at 1 (typical cheap VPS = 1.9–2GB).
54
+ const CODEBUDDY_CN_LOW_MEM_GB = 3;
52
55
 
53
56
  // Cap on count per job (bound cost/rate)
54
57
  const CODEBUDDY_CN_MAX_COUNT = 200;
@@ -61,6 +64,13 @@ const CODEBUDDY_CN_POLL_TIMEOUT_MS = 15 * 60_000;
61
64
  // input phone, click send code takes ~15-20s before SMS is actually requested).
62
65
  const CODEBUDDY_CN_SMS_TIMEOUT_MS = 90_000;
63
66
 
67
+ // Hard wall-clock per account (nav + form + SMS + API key). Prevents infinite
68
+ // Camoufox spin when proxy/nav blackholes and Playwright timeouts do not fire.
69
+ const CODEBUDDY_CN_ACCOUNT_HARD_TIMEOUT_MS = Number.parseInt(
70
+ process.env.ZEVAI_CN_ACCOUNT_TIMEOUT_MS || "",
71
+ 10,
72
+ ) || 12 * 60_000;
73
+
64
74
  // Supported 5sim regions
65
75
  const SUPPORTED_REGIONS = new Set(["hongkong", "china", "any"]);
66
76
  const DEFAULT_REGION = "hongkong";
@@ -81,14 +91,26 @@ function defaultPhoneFormatter(phone) {
81
91
  return String(phone || "").trim();
82
92
  }
83
93
 
94
+ function isLowMemHost() {
95
+ try {
96
+ const { totalMemGb } = getSystemSpecs();
97
+ return Number.isFinite(totalMemGb) && totalMemGb > 0 && totalMemGb < CODEBUDDY_CN_LOW_MEM_GB;
98
+ } catch {
99
+ return false;
100
+ }
101
+ }
102
+
84
103
  function clampCnConcurrency(value) {
104
+ const lowMem = isLowMemHost();
105
+ const hardMax = lowMem ? 1 : CODEBUDDY_CN_MAX_CONCURRENCY;
106
+ const def = lowMem ? 1 : CODEBUDDY_CN_DEFAULT_CONCURRENCY;
85
107
  if (isAutoConcurrencyValue(value)) {
86
108
  const optimal = getOptimalWorkerCount();
87
- return Math.min(CODEBUDDY_CN_MAX_CONCURRENCY, Math.max(CODEBUDDY_CN_MIN_CONCURRENCY, optimal));
109
+ return Math.min(hardMax, Math.max(CODEBUDDY_CN_MIN_CONCURRENCY, optimal));
88
110
  }
89
111
  const parsed = Number.parseInt(value, 10);
90
- if (!Number.isFinite(parsed)) return CODEBUDDY_CN_DEFAULT_CONCURRENCY;
91
- return Math.min(CODEBUDDY_CN_MAX_CONCURRENCY, Math.max(CODEBUDDY_CN_MIN_CONCURRENCY, parsed));
112
+ if (!Number.isFinite(parsed)) return Math.min(hardMax, def);
113
+ return Math.min(hardMax, Math.max(CODEBUDDY_CN_MIN_CONCURRENCY, parsed));
92
114
  }
93
115
 
94
116
  /**
@@ -140,17 +162,23 @@ export class CodeBuddyCnBulkImportManager extends KiroBulkImportManager {
140
162
  pollIntervalMs = CODEBUDDY_CN_CONFIG.pollInterval,
141
163
  storageName = "codebuddy-cn-bulk-import",
142
164
  } = {}) {
143
- // Camoufox needs proxy on browser launch (not context-only). Headed small
144
- // window so operator can watch like other bulk automations (not fullscreen).
165
+ // Camoufox needs proxy on browser launch (not context-only).
166
+ // Linux VPS: default headless to cut RAM/CPU (2GB boxes OOM on headed+Xvfb).
167
+ // Desktop (macOS/Windows): headed so the operator can watch / solve captcha.
168
+ // Override: ZEVAI_CN_HEADLESS=0|1
145
169
  const cnBrowserLauncher = browserLauncher || (async (job) => {
146
170
  const { launchBulkImportBrowser } = await import("./bulkImportBrowserEngine.js");
147
171
  const proxyUrl = Array.isArray(job?.proxyUrls) && job.proxyUrls.length
148
172
  ? job.proxyUrls[0]
149
173
  : null;
174
+ const envHeadless = process.env.ZEVAI_CN_HEADLESS;
175
+ let headless = process.platform === "linux";
176
+ if (envHeadless === "0" || envHeadless === "false") headless = false;
177
+ if (envHeadless === "1" || envHeadless === "true") headless = true;
150
178
  return launchBulkImportBrowser({
151
179
  engine: job?.engine || "camoufox",
152
180
  proxyUrl,
153
- headless: false,
181
+ headless,
154
182
  windowSize: { width: 900, height: 700 },
155
183
  });
156
184
  });
@@ -338,60 +366,94 @@ export class CodeBuddyCnBulkImportManager extends KiroBulkImportManager {
338
366
  this.setAccountStep(account, "registering", "Running phone registration on CodeBuddy CN");
339
367
  await this.persistJobSnapshot(job, { forcePreview: true });
340
368
 
341
- const automationResult = await this.phoneAutomation({
342
- page,
343
- resolvePhone: async () => {
344
- if (job.cancelRequested) {
345
- throw new Error("Job cancelled before ordering phone number");
346
- }
347
- this.setAccountStep(
348
- account,
349
- "ordering_number",
350
- `Form ready — ordering ${job.region} phone from 5sim (single buy)`,
351
- );
352
- await this.persistJobSnapshot(job, { forcePreview: true });
369
+ // Page-level timeouts so a stuck network never outlives the hard wall-clock.
370
+ try {
371
+ page.setDefaultTimeout(20_000);
372
+ page.setDefaultNavigationTimeout(45_000);
373
+ } catch {
374
+ // older playwright builds may not expose these
375
+ }
353
376
 
354
- const numberData = await fiveSimClient.buyNumber({
355
- country: job.region,
356
- product: "codebuddy",
357
- allowProductFallback: false,
358
- });
359
- fiveSimOrderId = numberData.id;
360
- account.phone = numberData.phone;
361
- account.fiveSimOrderId = numberData.id;
362
- account.fiveSimActivationId = numberData.id;
363
- this.setAccountStep(
364
- account,
365
- "number_ordered",
366
- `Phone number ordered: ${numberData.phone} (1 buy, no re-order)`,
367
- );
368
- await this.persistJobSnapshot(job, { forcePreview: true });
369
- return numberData.phone;
370
- },
371
- waitForSms: async () => {
372
- if (!fiveSimOrderId) {
373
- throw new Error("Cannot poll SMS — no 5sim order id");
374
- }
375
- this.setAccountStep(
376
- account,
377
- "sms_poll_started",
378
- `SMS poll started (full ${CODEBUDDY_CN_SMS_TIMEOUT_MS / 1000}s window after send-code)`,
377
+ const hardTimeoutMs = CODEBUDDY_CN_ACCOUNT_HARD_TIMEOUT_MS;
378
+ let hardTimer = null;
379
+ const hardTimeoutPromise = new Promise((_, reject) => {
380
+ hardTimer = setTimeout(() => {
381
+ reject(
382
+ Object.assign(
383
+ new Error(
384
+ `CodeBuddy CN account hard timeout after ${Math.round(hardTimeoutMs / 1000)}s (browser will be force-closed)`,
385
+ ),
386
+ { code: "CN_ACCOUNT_HARD_TIMEOUT" },
387
+ ),
379
388
  );
380
- await this.persistJobSnapshot(job, { forcePreview: false });
381
- const code = await fiveSimClient.pollCode(fiveSimOrderId, {
382
- timeoutMs: CODEBUDDY_CN_SMS_TIMEOUT_MS,
383
- signal: account.abortController?.signal,
384
- });
385
- smsReceived = true;
386
- return code;
387
- },
388
- onStep: (step, message) => {
389
- this.setAccountStep(account, step, message);
390
- void this.persistJobSnapshot(job, { forcePreview: false });
391
- },
392
- phoneFormatter: this.phoneFormatter,
389
+ }, hardTimeoutMs);
390
+ if (typeof hardTimer.unref === "function") hardTimer.unref();
393
391
  });
394
392
 
393
+ let automationResult;
394
+ try {
395
+ automationResult = await Promise.race([
396
+ this.phoneAutomation({
397
+ page,
398
+ signal: account.abortController?.signal,
399
+ isCancelled: () => job.cancelRequested === true,
400
+ resolvePhone: async () => {
401
+ if (job.cancelRequested) {
402
+ throw new Error("Job cancelled before ordering phone number");
403
+ }
404
+ this.setAccountStep(
405
+ account,
406
+ "ordering_number",
407
+ `Form ready — ordering ${job.region} phone from 5sim (single buy)`,
408
+ );
409
+ await this.persistJobSnapshot(job, { forcePreview: true });
410
+
411
+ const numberData = await fiveSimClient.buyNumber({
412
+ country: job.region,
413
+ product: "codebuddy",
414
+ allowProductFallback: false,
415
+ });
416
+ fiveSimOrderId = numberData.id;
417
+ account.phone = numberData.phone;
418
+ account.fiveSimOrderId = numberData.id;
419
+ account.fiveSimActivationId = numberData.id;
420
+ this.setAccountStep(
421
+ account,
422
+ "number_ordered",
423
+ `Phone number ordered: ${numberData.phone} (1 buy, no re-order)`,
424
+ );
425
+ await this.persistJobSnapshot(job, { forcePreview: true });
426
+ return numberData.phone;
427
+ },
428
+ waitForSms: async () => {
429
+ if (!fiveSimOrderId) {
430
+ throw new Error("Cannot poll SMS — no 5sim order id");
431
+ }
432
+ this.setAccountStep(
433
+ account,
434
+ "sms_poll_started",
435
+ `SMS poll started (full ${CODEBUDDY_CN_SMS_TIMEOUT_MS / 1000}s window after send-code)`,
436
+ );
437
+ await this.persistJobSnapshot(job, { forcePreview: false });
438
+ const code = await fiveSimClient.pollCode(fiveSimOrderId, {
439
+ timeoutMs: CODEBUDDY_CN_SMS_TIMEOUT_MS,
440
+ signal: account.abortController?.signal,
441
+ });
442
+ smsReceived = true;
443
+ return code;
444
+ },
445
+ onStep: (step, message) => {
446
+ this.setAccountStep(account, step, message);
447
+ void this.persistJobSnapshot(job, { forcePreview: false });
448
+ },
449
+ phoneFormatter: this.phoneFormatter,
450
+ }),
451
+ hardTimeoutPromise,
452
+ ]);
453
+ } finally {
454
+ if (hardTimer) clearTimeout(hardTimer);
455
+ }
456
+
395
457
  // Step 6: Try API key capture only if automation reached at least the submit step.
396
458
  // If automation failed early (e.g. page.goto timeout), the session won't be logged in
397
459
  // and API key creation will 401 — so don't waste time. Only try bypass if automation
@@ -446,6 +508,15 @@ export class CodeBuddyCnBulkImportManager extends KiroBulkImportManager {
446
508
  }
447
509
  account.runtimeSession = null;
448
510
  if (context) await context.close().catch(() => null);
511
+ // Hard timeout / blackhole nav: kill the shared browser so the worker unblocks
512
+ // and Camoufox cannot pin 100% CPU on a 2GB VPS until reboot.
513
+ if (error?.code === "CN_ACCOUNT_HARD_TIMEOUT" || job.cancelRequested) {
514
+ if (job.browser) {
515
+ const b = job.browser;
516
+ job.browser = null;
517
+ await forceCloseBrowser(b).catch(() => null);
518
+ }
519
+ }
449
520
  await this.persistJobSnapshot(job, { forcePreview: true });
450
521
  }
451
522
  }
@@ -527,7 +598,9 @@ export class CodeBuddyCnBulkImportManager extends KiroBulkImportManager {
527
598
  let accountsProbe = null;
528
599
  let sessionReady = false;
529
600
 
530
- for (let attempt = 0; attempt < 18; attempt += 1) {
601
+ // Cap OIDC nudge loop 18 × multi-second waits was too long on 2GB VPS.
602
+ const OIDC_MAX_ATTEMPTS = 8;
603
+ for (let attempt = 0; attempt < OIDC_MAX_ATTEMPTS; attempt += 1) {
531
604
  if (job.cancelRequested) {
532
605
  throw new Error("Job cancelled while establishing session");
533
606
  }
@@ -538,29 +611,29 @@ export class CodeBuddyCnBulkImportManager extends KiroBulkImportManager {
538
611
 
539
612
  // Progressive navigation to complete half-finished Keycloak login
540
613
  const path = oIDCNudgePaths[Math.min(attempt, oIDCNudgePaths.length - 1)];
541
- if (attempt === 0 || attempt === 2 || attempt === 5 || attempt === 8 || attempt === 12) {
614
+ if (attempt === 0 || attempt === 2 || attempt === 4 || attempt === 6) {
542
615
  this.setAccountStep(
543
616
  account,
544
617
  "waiting_session",
545
- `OIDC handoff attempt ${attempt + 1}/18 → ${path} (cookies: ${strong ? "KEYCLOAK" : soft ? "soft-session" : "weak"})`,
618
+ `OIDC handoff attempt ${attempt + 1}/${OIDC_MAX_ATTEMPTS} → ${path} (cookies: ${strong ? "KEYCLOAK" : soft ? "soft-session" : "weak"})`,
546
619
  );
547
620
  await this.persistJobSnapshot(job, { forcePreview: false });
548
- await page.goto(path, { waitUntil: "domcontentloaded", timeout: 45_000 }).catch(() => null);
549
- await page.waitForTimeout(2_500);
621
+ await page.goto(path, { waitUntil: "domcontentloaded", timeout: 25_000 }).catch(() => null);
622
+ await page.waitForTimeout(1_500);
550
623
 
551
624
  // If Keycloak login iframe reappears, user session is not complete —
552
625
  // don't treat blank SPA as success; keep probing.
553
626
  } else {
554
- await page.waitForTimeout(1_500);
627
+ await page.waitForTimeout(1_000);
555
628
  }
556
629
 
557
630
  // Prefer landing on console for the API probe
558
- if (attempt >= 3 && !String(page.url() || "").includes("/console")) {
631
+ if (attempt >= 2 && !String(page.url() || "").includes("/console")) {
559
632
  await page.goto("https://www.codebuddy.cn/console", {
560
633
  waitUntil: "domcontentloaded",
561
- timeout: 45_000,
634
+ timeout: 25_000,
562
635
  }).catch(() => null);
563
- await page.waitForTimeout(1_500);
636
+ await page.waitForTimeout(1_000);
564
637
  }
565
638
 
566
639
  accountsProbe = await probeConsoleAccounts();
@@ -579,7 +652,7 @@ export class CodeBuddyCnBulkImportManager extends KiroBulkImportManager {
579
652
  this.setAccountStep(
580
653
  account,
581
654
  "resolving_enterprise",
582
- `Console not ready (HTTP ${accountsProbe?.status || 0}) — retry ${attempt + 1}/18`,
655
+ `Console not ready (HTTP ${accountsProbe?.status || 0}) — retry ${attempt + 1}/${OIDC_MAX_ATTEMPTS}`,
583
656
  );
584
657
  await this.persistJobSnapshot(job, { forcePreview: false });
585
658
  }
@@ -854,7 +927,8 @@ export class CodeBuddyCnBulkImportManager extends KiroBulkImportManager {
854
927
  }
855
928
 
856
929
  /**
857
- * Override cancelJob to abort in-flight 5sim polls and clean up orders.
930
+ * Override cancelJob to abort in-flight 5sim polls AND force-close the browser.
931
+ * Previous CN override only aborted controllers — Camoufox kept spinning (VPS hang).
858
932
  */
859
933
  cancelJob(jobId) {
860
934
  const job = this.jobs.get(jobId);
@@ -862,11 +936,24 @@ export class CodeBuddyCnBulkImportManager extends KiroBulkImportManager {
862
936
 
863
937
  job.cancelRequested = true;
864
938
 
865
- // Abort in-flight 5sim polls for all running accounts
939
+ // Abort in-flight 5sim polls + close per-account contexts
866
940
  for (const account of job.accounts) {
867
941
  if (account.abortController && !account.abortController.signal.aborted) {
868
942
  account.abortController.abort();
869
943
  }
944
+ const ctx = account.runtimeSession?.context;
945
+ if (ctx) {
946
+ void ctx.close().catch(() => null);
947
+ }
948
+ account.runtimeSession = null;
949
+ account.manualSession = null;
950
+ }
951
+
952
+ // CRITICAL: force-kill Camoufox/Chromium. Graceful close alone hangs when nav is stuck.
953
+ if (job.browser) {
954
+ const browser = job.browser;
955
+ job.browser = null;
956
+ void forceCloseBrowser(browser).catch(() => null);
870
957
  }
871
958
 
872
959
  if (job.status === "queued") {
@@ -876,7 +963,9 @@ export class CodeBuddyCnBulkImportManager extends KiroBulkImportManager {
876
963
  if (account.status === "queued") account.status = "cancelled";
877
964
  });
878
965
  }
879
- return job;
966
+
967
+ void this.persistJobSnapshot(job, { forcePreview: true });
968
+ return sanitizeCnJob(job);
880
969
  }
881
970
  }
882
971
 
@@ -43,9 +43,10 @@ const CODEBUDDY_CN_LOGIN_URL_FALLBACKS = [
43
43
  "https://www.codebuddy.cn/register/",
44
44
  "https://copilot.tencent.com/login/",
45
45
  ];
46
- const NAV_MAX_ATTEMPTS = 5;
47
- const NAV_TIMEOUT_MS = 60_000;
48
- const SPA_TIMEOUT_MS = 60_000;
46
+ // Keep short on VPS so a blackholed proxy cannot pin CPU for many minutes.
47
+ const NAV_MAX_ATTEMPTS = 2;
48
+ const NAV_TIMEOUT_MS = 30_000;
49
+ const SPA_TIMEOUT_MS = 25_000;
49
50
 
50
51
  // Main page selectors (outside iframe)
51
52
  const PHONE_TAB_SELECTORS = [
@@ -139,17 +140,34 @@ export async function runCodeBuddyCnPhoneRegistration({
139
140
  onStep,
140
141
  phoneFormatter = (p) => p,
141
142
  timeouts = {},
143
+ signal = null,
144
+ isCancelled = null,
142
145
  }) {
143
- const nav = timeouts.nav ?? 90_000;
146
+ const nav = timeouts.nav ?? NAV_TIMEOUT_MS;
144
147
  const action = timeouts.action ?? 15_000;
145
148
  const codeWait = timeouts.codeWait ?? 900_000;
146
149
  const postSubmit = timeouts.postSubmit ?? 10_000;
147
150
 
148
151
  const reportStep = (step, message) => onStep?.(step, message);
152
+ const throwIfCancelled = () => {
153
+ if (signal?.aborted || (typeof isCancelled === "function" && isCancelled())) {
154
+ const err = new Error("Job cancelled");
155
+ err.code = "JOB_CANCELLED";
156
+ throw err;
157
+ }
158
+ };
149
159
 
150
160
  try {
151
161
  // Step 1: Navigate — rotating proxy often fails first try; retry until SPA boots
152
162
  reportStep("cn_opening_login_page", "Opening CodeBuddy CN login page");
163
+ throwIfCancelled();
164
+
165
+ try {
166
+ page.setDefaultNavigationTimeout(nav);
167
+ page.setDefaultTimeout(action);
168
+ } catch {
169
+ // ignore
170
+ }
153
171
 
154
172
  // ponytail: China residential proxies hang on Google tracker CONNECT; abort them so SPA can boot
155
173
  try {
@@ -166,6 +184,7 @@ export async function runCodeBuddyCnPhoneRegistration({
166
184
 
167
185
  let phoneFrame = null;
168
186
  for (let navAttempt = 1; navAttempt <= NAV_MAX_ATTEMPTS; navAttempt++) {
187
+ throwIfCancelled();
169
188
  try {
170
189
  const targetUrl = CODEBUDDY_CN_LOGIN_URL_FALLBACKS[(navAttempt - 1) % CODEBUDDY_CN_LOGIN_URL_FALLBACKS.length];
171
190
  reportStep("cn_nav_attempt", `Navigation attempt ${navAttempt}/${NAV_MAX_ATTEMPTS} → ${targetUrl}`);
@@ -173,20 +192,23 @@ export async function runCodeBuddyCnPhoneRegistration({
173
192
  // Between retries, hard-reload by clearing cookies for codebuddy so CDN/session glitches reset
174
193
  if (navAttempt > 1) {
175
194
  await page.context().clearCookies().catch(() => {});
176
- await page.waitForTimeout(1_500);
195
+ await page.waitForTimeout(800);
177
196
  }
178
197
 
179
198
  // commit only — domcontentloaded stalls when any subresource (ads/CDN) hangs via proxy
180
199
  await page.goto(targetUrl, {
181
200
  waitUntil: "commit",
182
- timeout: NAV_TIMEOUT_MS,
201
+ timeout: nav,
183
202
  });
203
+ throwIfCancelled();
184
204
 
185
205
  // Give the SPA a short moment to mount React/Vue after document commit
186
- await page.waitForTimeout(2_500);
206
+ await page.waitForTimeout(1_500);
207
+ throwIfCancelled();
187
208
 
188
209
  // SPA shell loads first; wait for any login UI marker (not networkidle — long-lived sockets)
189
210
  const spaReady = await waitForAnyVisible(page, SPA_READY_SELECTORS, SPA_TIMEOUT_MS);
211
+ throwIfCancelled();
190
212
  if (!spaReady) {
191
213
  const bodyText = await page.locator("body").innerText().catch(() => "");
192
214
  const htmlLen = await page.evaluate(() => document.documentElement?.outerHTML?.length || 0).catch(() => 0);
@@ -204,23 +226,23 @@ export async function runCodeBuddyCnPhoneRegistration({
204
226
 
205
227
  // Step 2: Switch to phone-number tab
206
228
  reportStep("cn_selecting_phone_tab", "Selecting phone-number tab");
207
- const phoneTab = await waitForFirstVisibleLocator(page, PHONE_TAB_SELECTORS, { timeout: 15_000 });
229
+ const phoneTab = await waitForFirstVisibleLocator(page, PHONE_TAB_SELECTORS, { timeout: 12_000 });
208
230
  if (phoneTab) {
209
231
  await phoneTab.click().catch(() => {});
210
232
  reportStep("cn_phone_tab_selected", "Phone tab selected");
211
- await page.waitForTimeout(1_000);
233
+ await page.waitForTimeout(800);
212
234
  } else {
213
235
  reportStep("cn_phone_tab_not_found", "Phone tab not found — checking if iframe already present");
214
236
  }
215
237
 
216
238
  // Step 3: Wait for Keycloak phone iframe
217
239
  reportStep("cn_waiting_for_iframe", "Waiting for phone iframe to load");
218
- await page.locator(PHONE_IFRAME_SELECTOR).waitFor({ state: "attached", timeout: 25_000 }).catch(() => {});
240
+ await page.locator(PHONE_IFRAME_SELECTOR).waitFor({ state: "attached", timeout: 18_000 }).catch(() => {});
219
241
  phoneFrame = await getPhoneFrame(page);
220
242
  if (phoneFrame) {
221
243
  // Confirm phone input is actually inside the iframe
222
244
  const phoneInputReady = await phoneFrame
223
- .waitForSelector(IFRAME_PHONE_INPUT, { state: "visible", timeout: 20_000 })
245
+ .waitForSelector(IFRAME_PHONE_INPUT, { state: "visible", timeout: 15_000 })
224
246
  .then(() => true)
225
247
  .catch(() => false);
226
248
  if (phoneInputReady) {
@@ -233,6 +255,7 @@ export async function runCodeBuddyCnPhoneRegistration({
233
255
  reportStep("cn_iframe_missing", `No #phone-iframe (attempt ${navAttempt}/${NAV_MAX_ATTEMPTS})`);
234
256
  }
235
257
  } catch (navErr) {
258
+ if (navErr?.code === "JOB_CANCELLED") throw navErr;
236
259
  reportStep(
237
260
  "cn_nav_retry",
238
261
  `Navigation attempt ${navAttempt}/${NAV_MAX_ATTEMPTS} failed: ${String(navErr.message || navErr).slice(0, 120)}`,
@@ -383,13 +406,12 @@ export async function runCodeBuddyCnPhoneRegistration({
383
406
  reportStep("cn_code_entered", "Verification code entered");
384
407
 
385
408
  // Step 9: Click submit (#kc-login)
386
- // Retry up to 3 times if "account restricted" (账号访问受限) is shown —
387
- // refresh + re-enter phone + code each time (SMS code valid for 5 min).
388
- // After a clean submit, poll up to SESSION_WAIT_MS for Keycloak cookies
389
- // China residential proxies often leave a blank SPA shell for 5–15s before
390
- // the OIDC handoff sets KEYCLOAK_IDENTITY (previous 2s check was too short).
391
- const MAX_SUBMIT_RETRIES = 3;
392
- const SESSION_WAIT_MS = Math.max(postSubmit, 20_000);
409
+ // Retry a couple times if "account restricted" (账号访问受限) is shown —
410
+ // but do not thrash: datacenter/VPS IPs usually stay restricted until a real
411
+ // residential CN proxy is used. Keep the loop short so Camoufox cannot pin RAM.
412
+ // After a clean submit, poll for Keycloak cookies (China proxy SPA shell lag).
413
+ const MAX_SUBMIT_RETRIES = 2;
414
+ const SESSION_WAIT_MS = Math.max(postSubmit, 12_000);
393
415
  let submitSuccess = false;
394
416
  for (let retry = 0; retry < MAX_SUBMIT_RETRIES; retry++) {
395
417
  reportStep("cn_submitting", `Clicking submit button (attempt ${retry + 1}/${MAX_SUBMIT_RETRIES})`);
@@ -447,13 +469,20 @@ export async function runCodeBuddyCnPhoneRegistration({
447
469
  // Check for "account restricted" (账号访问受限)
448
470
  const restrictionDetected = await checkAccountRestricted(currentFrame);
449
471
  if (restrictionDetected) {
472
+ if (retry >= MAX_SUBMIT_RETRIES - 1) {
473
+ return {
474
+ status: "failed",
475
+ error:
476
+ "Account restricted (账号访问受限) after submit. Datacenter/VPS IP is usually blocked — use a residential CN proxy pool (proxyPoolMode=single) and retry.",
477
+ };
478
+ }
450
479
  reportStep("cn_account_restricted", `Account restricted (attempt ${retry + 1}) — refreshing page and retrying`);
451
- await page.reload({ waitUntil: "domcontentloaded", timeout: nav }).catch(() => {});
452
- await waitForAnyVisible(page, SPA_READY_SELECTORS, 20_000);
453
- const phoneTabRetry = await waitForFirstVisibleLocator(page, PHONE_TAB_SELECTORS, { timeout: action });
480
+ await page.reload({ waitUntil: "commit", timeout: nav }).catch(() => {});
481
+ await waitForAnyVisible(page, SPA_READY_SELECTORS, 12_000);
482
+ const phoneTabRetry = await waitForFirstVisibleLocator(page, PHONE_TAB_SELECTORS, { timeout: 8_000 });
454
483
  if (phoneTabRetry) {
455
484
  await phoneTabRetry.click().catch(() => {});
456
- await page.locator(PHONE_IFRAME_SELECTOR).waitFor({ state: "attached", timeout: 10_000 }).catch(() => {});
485
+ await page.locator(PHONE_IFRAME_SELECTOR).waitFor({ state: "attached", timeout: 8_000 }).catch(() => {});
457
486
  }
458
487
  continue; // Retry submit
459
488
  }
@@ -622,14 +651,19 @@ function parsePhoneNumber(phone) {
622
651
  /**
623
652
  * Select the country code in the Keycloak form dropdown.
624
653
  * If the current country code already matches, do nothing.
654
+ *
655
+ * IMPORTANT: Keycloak country lists are 200+ rows. Never scan options.nth(i) in a
656
+ * loop — that pinned Camoufox for ~80s on retry after account-restricted. Prefer
657
+ * :has-text / getByText with a hard wall-clock.
625
658
  */
626
659
  async function selectCountry(frame, targetCountryCode, actionTimeout, reportStep) {
627
660
  if (!targetCountryCode) return; // No specific country to select
628
661
 
629
- try {
662
+ const budgetMs = Math.min(Number(actionTimeout) || 15_000, 10_000);
663
+ const run = async () => {
630
664
  // Check current country code
631
665
  const currentCodeEl = frame.locator(iframeSelector(IFRAME_COUNTRY_CODE_TEXT)).first();
632
- const currentCode = await currentCodeEl.textContent({ timeout: 5_000 }).catch(() => "");
666
+ const currentCode = await currentCodeEl.textContent({ timeout: 3_000 }).catch(() => "");
633
667
  const trimmedCode = String(currentCode).trim();
634
668
 
635
669
  if (trimmedCode === targetCountryCode) {
@@ -640,35 +674,55 @@ async function selectCountry(frame, targetCountryCode, actionTimeout, reportStep
640
674
  // Click the country selector to open dropdown
641
675
  reportStep?.("cn_opening_country_dropdown", `Opening country dropdown (current: ${trimmedCode}, target: ${targetCountryCode})`);
642
676
  const selector = frame.locator(iframeSelector(IFRAME_COUNTRY_SELECTOR)).first();
643
- await selector.waitFor({ state: "visible", timeout: actionTimeout });
644
- await selector.click().catch(() => {});
677
+ await selector.waitFor({ state: "visible", timeout: Math.min(budgetMs, 5_000) });
678
+ await selector.click({ timeout: 3_000 }).catch(() => {});
645
679
  // Wait for dropdown options to appear
646
680
  await frame.locator(iframeSelector(IFRAME_COUNTRY_OPTIONS)).first()
647
- .waitFor({ state: "visible", timeout: 5_000 }).catch(() => {});
648
-
649
- // Find the option matching the target country code
650
- const options = frame.locator(iframeSelector(IFRAME_COUNTRY_OPTIONS));
651
- const count = await options.count();
652
-
653
- for (let i = 0; i < count; i++) {
654
- const option = options.nth(i);
655
- const optionText = await option.textContent().catch(() => "");
656
- if (String(optionText).includes(targetCountryCode)) {
657
- await option.click().catch(() => {});
658
- // Confirm selection applied
681
+ .waitFor({ state: "visible", timeout: 3_000 }).catch(() => {});
682
+
683
+ // Direct label matches first (HK is the default 5sim region for CN bulk)
684
+ const preferredLabels = {
685
+ "+852": ["中国香港", "香港", "Hong Kong", "+852"],
686
+ "+86": ["中国大陆", "中国", "China", "+86"],
687
+ "+853": ["中国澳门", "澳门", "Macau", "+853"],
688
+ "+886": ["中国台湾", "台湾", "Taiwan", "+886"],
689
+ };
690
+ const labels = preferredLabels[targetCountryCode] || [targetCountryCode];
691
+
692
+ for (const label of labels) {
693
+ // Prefer scoped option rows; fall back to any text match inside the frame
694
+ const candidates = [
695
+ frame.locator(`${iframeSelector(IFRAME_COUNTRY_OPTIONS)}:has-text("${label}")`).first(),
696
+ frame.getByText(label, { exact: false }).first(),
697
+ ];
698
+ for (const option of candidates) {
699
+ const visible = await option.isVisible({ timeout: 1_500 }).catch(() => false);
700
+ if (!visible) continue;
701
+ const optionText = await option.textContent({ timeout: 1_500 }).catch(() => label);
702
+ await option.click({ timeout: 2_000 }).catch(() => {});
659
703
  await frame.locator(iframeSelector(IFRAME_COUNTRY_CODE_TEXT))
660
704
  .filter({ hasText: targetCountryCode })
661
705
  .first()
662
- .waitFor({ state: "visible", timeout: 3_000 })
706
+ .waitFor({ state: "visible", timeout: 2_000 })
663
707
  .catch(() => {});
664
- reportStep?.("cn_country_selected", `Country selected: ${String(optionText).trim()}`);
708
+ reportStep?.("cn_country_selected", `Country selected: ${String(optionText || label).trim()}`);
665
709
  return;
666
710
  }
667
711
  }
668
712
 
669
713
  // If no matching option found, close dropdown by clicking elsewhere
670
714
  reportStep?.("cn_country_not_found", `Country code ${targetCountryCode} not found in dropdown; using default`);
671
- await frame.locator("body").click().catch(() => {});
715
+ await frame.locator("body").click({ timeout: 1_000 }).catch(() => {});
716
+ };
717
+
718
+ try {
719
+ await Promise.race([
720
+ run(),
721
+ new Promise((_, reject) => {
722
+ const t = setTimeout(() => reject(new Error(`selectCountry timed out after ${budgetMs}ms`)), budgetMs);
723
+ if (typeof t.unref === "function") t.unref();
724
+ }),
725
+ ]);
672
726
  } catch (err) {
673
727
  reportStep?.("cn_country_select_error", `Country selection error: ${err.message}`);
674
728
  // Non-fatal — continue with default country