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.
- package/CHANGELOG.md +36 -8
- package/README.md +58 -10
- package/README.zh-CN.md +37 -0
- package/cli/app/.next-cli-build/BUILD_ID +1 -1
- package/cli/app/.next-cli-build/app-path-routes-manifest.json +25 -25
- package/cli/app/.next-cli-build/build-manifest.json +2 -2
- package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/automation/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/basic-chat/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/cli-tools/[toolId]/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/cli-tools/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/combos/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/console-log/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/context/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/endpoint/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/[kind]/[id]/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/[kind]/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/combo/[id]/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/web/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/mitm/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/playground/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/profile/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/providers/[id]/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/providers/new/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/providers/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/proxy-pools/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/pxpipe/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/quota/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/terminal/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/token-saver/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/translator/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/(dashboard)/dashboard/usage/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/_global-error.html +1 -1
- package/cli/app/.next-cli-build/server/app/_global-error.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/_not-found.html +1 -1
- package/cli/app/.next-cli-build/server/app/_not-found.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/_not-found.segments/_full.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/_not-found.segments/_index.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/api/models/route.js +1 -1
- package/cli/app/.next-cli-build/server/app/api/models/test/route.js +1 -1
- package/cli/app/.next-cli-build/server/app/api/oauth/antigravity/bulk-import/[jobId]/cancel/route.js.nft.json +1 -1
- package/cli/app/.next-cli-build/server/app/api/oauth/antigravity/bulk-import/[jobId]/manual/[workerId]/route.js.nft.json +1 -1
- package/cli/app/.next-cli-build/server/app/api/oauth/antigravity/bulk-import/[jobId]/route.js.nft.json +1 -1
- package/cli/app/.next-cli-build/server/app/api/oauth/antigravity/bulk-import/latest/route.js.nft.json +1 -1
- package/cli/app/.next-cli-build/server/app/api/oauth/antigravity/bulk-import/route.js.nft.json +1 -1
- package/cli/app/.next-cli-build/server/app/api/oauth/autoclaw/bulk-import/[jobId]/cancel/route.js.nft.json +1 -1
- package/cli/app/.next-cli-build/server/app/api/oauth/autoclaw/bulk-import/[jobId]/manual/[workerId]/route.js.nft.json +1 -1
- package/cli/app/.next-cli-build/server/app/api/oauth/autoclaw/bulk-import/[jobId]/route.js.nft.json +1 -1
- package/cli/app/.next-cli-build/server/app/api/oauth/autoclaw/bulk-import/latest/route.js.nft.json +1 -1
- package/cli/app/.next-cli-build/server/app/api/oauth/autoclaw/bulk-import/route.js.nft.json +1 -1
- package/cli/app/.next-cli-build/server/app/api/oauth/codebuddy/bulk-import/[jobId]/cancel/route.js.nft.json +1 -1
- package/cli/app/.next-cli-build/server/app/api/oauth/codebuddy/bulk-import/[jobId]/manual/[workerId]/route.js.nft.json +1 -1
- package/cli/app/.next-cli-build/server/app/api/oauth/codebuddy/bulk-import/[jobId]/route.js.nft.json +1 -1
- package/cli/app/.next-cli-build/server/app/api/oauth/codebuddy/bulk-import/latest/route.js.nft.json +1 -1
- package/cli/app/.next-cli-build/server/app/api/oauth/codebuddy/bulk-import/route.js.nft.json +1 -1
- package/cli/app/.next-cli-build/server/app/api/oauth/codebuddy-cn/bulk-import/[jobId]/cancel/route.js +1 -1
- package/cli/app/.next-cli-build/server/app/api/oauth/codebuddy-cn/bulk-import/[jobId]/cancel/route.js.nft.json +1 -1
- package/cli/app/.next-cli-build/server/app/api/oauth/codebuddy-cn/bulk-import/[jobId]/manual/[workerId]/route.js +1 -1
- package/cli/app/.next-cli-build/server/app/api/oauth/codebuddy-cn/bulk-import/[jobId]/manual/[workerId]/route.js.nft.json +1 -1
- package/cli/app/.next-cli-build/server/app/api/oauth/codebuddy-cn/bulk-import/[jobId]/route.js +1 -1
- package/cli/app/.next-cli-build/server/app/api/oauth/codebuddy-cn/bulk-import/[jobId]/route.js.nft.json +1 -1
- package/cli/app/.next-cli-build/server/app/api/oauth/codebuddy-cn/bulk-import/latest/route.js +1 -1
- package/cli/app/.next-cli-build/server/app/api/oauth/codebuddy-cn/bulk-import/latest/route.js.nft.json +1 -1
- package/cli/app/.next-cli-build/server/app/api/oauth/codebuddy-cn/bulk-import/route.js +1 -1
- package/cli/app/.next-cli-build/server/app/api/oauth/codebuddy-cn/bulk-import/route.js.nft.json +1 -1
- package/cli/app/.next-cli-build/server/app/api/oauth/grok-cli/bulk-import/[jobId]/cancel/route.js.nft.json +1 -1
- package/cli/app/.next-cli-build/server/app/api/oauth/grok-cli/bulk-import/[jobId]/manual/[workerId]/route.js.nft.json +1 -1
- package/cli/app/.next-cli-build/server/app/api/oauth/grok-cli/bulk-import/[jobId]/route.js.nft.json +1 -1
- package/cli/app/.next-cli-build/server/app/api/oauth/grok-cli/bulk-import/latest/route.js.nft.json +1 -1
- package/cli/app/.next-cli-build/server/app/api/oauth/grok-cli/bulk-import/route.js.nft.json +1 -1
- package/cli/app/.next-cli-build/server/app/api/oauth/kiro/bulk-import/[jobId]/cancel/route.js.nft.json +1 -1
- package/cli/app/.next-cli-build/server/app/api/oauth/kiro/bulk-import/[jobId]/manual/[workerId]/route.js.nft.json +1 -1
- package/cli/app/.next-cli-build/server/app/api/oauth/kiro/bulk-import/[jobId]/route.js.nft.json +1 -1
- package/cli/app/.next-cli-build/server/app/api/oauth/kiro/bulk-import/latest/route.js.nft.json +1 -1
- package/cli/app/.next-cli-build/server/app/api/oauth/kiro/bulk-import/route.js.nft.json +1 -1
- package/cli/app/.next-cli-build/server/app/api/oauth/kiro/import/route.js.nft.json +1 -1
- package/cli/app/.next-cli-build/server/app/api/oauth/qoder/bulk-import/[jobId]/cancel/route.js.nft.json +1 -1
- package/cli/app/.next-cli-build/server/app/api/oauth/qoder/bulk-import/[jobId]/manual/[workerId]/route.js.nft.json +1 -1
- package/cli/app/.next-cli-build/server/app/api/oauth/qoder/bulk-import/[jobId]/route.js.nft.json +1 -1
- package/cli/app/.next-cli-build/server/app/api/oauth/qoder/bulk-import/latest/route.js.nft.json +1 -1
- package/cli/app/.next-cli-build/server/app/api/oauth/qoder/bulk-import/route.js.nft.json +1 -1
- package/cli/app/.next-cli-build/server/app/api/providers/[id]/test-models/route.js +1 -1
- package/cli/app/.next-cli-build/server/app/api/providers/route.js +1 -1
- package/cli/app/.next-cli-build/server/app/api/providers/validate/route.js +1 -1
- package/cli/app/.next-cli-build/server/app/api/settings/database/route.js +1 -1
- package/cli/app/.next-cli-build/server/app/api/settings/route.js +1 -1
- package/cli/app/.next-cli-build/server/app/api/terminal/session/[id]/input/route.js.nft.json +1 -1
- package/cli/app/.next-cli-build/server/app/api/terminal/session/[id]/resize/route.js.nft.json +1 -1
- package/cli/app/.next-cli-build/server/app/api/terminal/session/[id]/route.js.nft.json +1 -1
- package/cli/app/.next-cli-build/server/app/api/terminal/session/[id]/stream/route.js.nft.json +1 -1
- package/cli/app/.next-cli-build/server/app/api/terminal/session/route.js.nft.json +1 -1
- package/cli/app/.next-cli-build/server/app/api/translator/console-logs/route.js +1 -1
- package/cli/app/.next-cli-build/server/app/api/translator/console-logs/stream/route.js +1 -1
- package/cli/app/.next-cli-build/server/app/api/version/route.js +1 -1
- package/cli/app/.next-cli-build/server/app/api/version/shutdown/route.js +1 -1
- package/cli/app/.next-cli-build/server/app/api/version/update/route.js +1 -1
- package/cli/app/.next-cli-build/server/app/callback/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/callback.html +1 -1
- package/cli/app/.next-cli-build/server/app/callback.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/callback.segments/_full.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/callback.segments/_head.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/callback.segments/_index.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/callback.segments/_tree.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/callback.segments/callback/__PAGE__.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/callback.segments/callback.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/automation.html +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/automation.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/automation.segments/!KGRhc2hib2FyZCk/dashboard/automation/__PAGE__.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/automation.segments/!KGRhc2hib2FyZCk/dashboard/automation.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/automation.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/automation.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/automation.segments/_full.segment.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/automation.segments/_head.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/automation.segments/_index.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/dashboard/automation.segments/_tree.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/basic-chat.html +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/basic-chat.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/basic-chat.segments/!KGRhc2hib2FyZCk/dashboard/basic-chat/__PAGE__.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/basic-chat.segments/!KGRhc2hib2FyZCk/dashboard/basic-chat.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/basic-chat.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/basic-chat.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/basic-chat.segments/_full.segment.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/basic-chat.segments/_head.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/basic-chat.segments/_index.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/dashboard/basic-chat.segments/_tree.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/cli-tools.html +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/cli-tools.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/cli-tools.segments/!KGRhc2hib2FyZCk/dashboard/cli-tools/__PAGE__.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/cli-tools.segments/!KGRhc2hib2FyZCk/dashboard/cli-tools.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/cli-tools.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/cli-tools.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/cli-tools.segments/_full.segment.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/cli-tools.segments/_head.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/cli-tools.segments/_index.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/dashboard/cli-tools.segments/_tree.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/combos.html +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/combos.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/combos.segments/!KGRhc2hib2FyZCk/dashboard/combos/__PAGE__.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/combos.segments/!KGRhc2hib2FyZCk/dashboard/combos.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/combos.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/combos.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/combos.segments/_full.segment.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/combos.segments/_head.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/combos.segments/_index.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/dashboard/combos.segments/_tree.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/context.html +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/context.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/context.segments/!KGRhc2hib2FyZCk/dashboard/context/__PAGE__.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/context.segments/!KGRhc2hib2FyZCk/dashboard/context.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/context.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/context.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/context.segments/_full.segment.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/context.segments/_head.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/context.segments/_index.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/dashboard/context.segments/_tree.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/endpoint.html +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/endpoint.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/endpoint.segments/!KGRhc2hib2FyZCk/dashboard/endpoint/__PAGE__.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/endpoint.segments/!KGRhc2hib2FyZCk/dashboard/endpoint.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/endpoint.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/endpoint.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/endpoint.segments/_full.segment.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/endpoint.segments/_head.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/endpoint.segments/_index.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/dashboard/endpoint.segments/_tree.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/media-providers/web.html +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/media-providers/web.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/!KGRhc2hib2FyZCk/dashboard/media-providers/web/__PAGE__.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/!KGRhc2hib2FyZCk/dashboard/media-providers/web.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/!KGRhc2hib2FyZCk/dashboard/media-providers.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/_full.segment.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/_head.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/_index.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/_tree.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/mitm.html +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/mitm.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/mitm.segments/!KGRhc2hib2FyZCk/dashboard/mitm/__PAGE__.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/mitm.segments/!KGRhc2hib2FyZCk/dashboard/mitm.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/mitm.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/mitm.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/mitm.segments/_full.segment.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/mitm.segments/_head.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/mitm.segments/_index.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/dashboard/mitm.segments/_tree.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/playground.html +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/playground.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/playground.segments/!KGRhc2hib2FyZCk/dashboard/playground/__PAGE__.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/playground.segments/!KGRhc2hib2FyZCk/dashboard/playground.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/playground.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/playground.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/playground.segments/_full.segment.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/playground.segments/_head.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/playground.segments/_index.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/dashboard/playground.segments/_tree.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/profile.html +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/profile.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/profile.segments/!KGRhc2hib2FyZCk/dashboard/profile/__PAGE__.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/profile.segments/!KGRhc2hib2FyZCk/dashboard/profile.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/profile.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/profile.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/profile.segments/_full.segment.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/profile.segments/_head.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/profile.segments/_index.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/dashboard/profile.segments/_tree.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/providers/new.html +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/providers/new.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/providers/new.segments/!KGRhc2hib2FyZCk/dashboard/providers/new/__PAGE__.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/providers/new.segments/!KGRhc2hib2FyZCk/dashboard/providers/new.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/providers/new.segments/!KGRhc2hib2FyZCk/dashboard/providers.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/providers/new.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/providers/new.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/providers/new.segments/_full.segment.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/providers/new.segments/_head.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/providers/new.segments/_index.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/dashboard/providers/new.segments/_tree.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/providers.html +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/providers.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/providers.segments/!KGRhc2hib2FyZCk/dashboard/providers/__PAGE__.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/providers.segments/!KGRhc2hib2FyZCk/dashboard/providers.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/providers.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/providers.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/providers.segments/_full.segment.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/providers.segments/_head.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/providers.segments/_index.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/dashboard/providers.segments/_tree.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/proxy-pools.html +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/proxy-pools.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/!KGRhc2hib2FyZCk/dashboard/proxy-pools/__PAGE__.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/!KGRhc2hib2FyZCk/dashboard/proxy-pools.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/_full.segment.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/_head.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/_index.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/_tree.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/pxpipe.html +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/pxpipe.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/pxpipe.segments/!KGRhc2hib2FyZCk/dashboard/pxpipe/__PAGE__.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/pxpipe.segments/!KGRhc2hib2FyZCk/dashboard/pxpipe.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/pxpipe.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/pxpipe.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/pxpipe.segments/_full.segment.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/pxpipe.segments/_head.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/pxpipe.segments/_index.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/dashboard/pxpipe.segments/_tree.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/quota.html +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/quota.rsc +6 -6
- package/cli/app/.next-cli-build/server/app/dashboard/quota.segments/!KGRhc2hib2FyZCk/dashboard/quota/__PAGE__.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/dashboard/quota.segments/!KGRhc2hib2FyZCk/dashboard/quota.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/quota.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/quota.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/quota.segments/_full.segment.rsc +6 -6
- package/cli/app/.next-cli-build/server/app/dashboard/quota.segments/_head.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/quota.segments/_index.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/dashboard/quota.segments/_tree.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/settings/pricing/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/settings/pricing.html +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/settings/pricing.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/_full.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/_head.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/_index.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/_tree.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/dashboard/settings/pricing/__PAGE__.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/dashboard/settings/pricing.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/dashboard/settings.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/dashboard.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/token-saver.html +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/token-saver.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/token-saver.segments/!KGRhc2hib2FyZCk/dashboard/token-saver/__PAGE__.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/token-saver.segments/!KGRhc2hib2FyZCk/dashboard/token-saver.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/token-saver.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/token-saver.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/token-saver.segments/_full.segment.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/token-saver.segments/_head.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/token-saver.segments/_index.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/dashboard/token-saver.segments/_tree.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/translator.html +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/translator.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/translator.segments/!KGRhc2hib2FyZCk/dashboard/translator/__PAGE__.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/translator.segments/!KGRhc2hib2FyZCk/dashboard/translator.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/translator.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/translator.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/translator.segments/_full.segment.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/translator.segments/_head.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/translator.segments/_index.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/dashboard/translator.segments/_tree.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/usage.html +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/usage.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/usage.segments/!KGRhc2hib2FyZCk/dashboard/usage/__PAGE__.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/usage.segments/!KGRhc2hib2FyZCk/dashboard/usage.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/usage.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/usage.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard/usage.segments/_full.segment.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard/usage.segments/_head.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard/usage.segments/_index.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/dashboard/usage.segments/_tree.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard.html +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard.segments/!KGRhc2hib2FyZCk/dashboard/__PAGE__.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard.segments/!KGRhc2hib2FyZCk/dashboard.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard.segments/!KGRhc2hib2FyZCk.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/dashboard.segments/_full.segment.rsc +5 -5
- package/cli/app/.next-cli-build/server/app/dashboard.segments/_head.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/dashboard.segments/_index.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/dashboard.segments/_tree.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/index.html +1 -1
- package/cli/app/.next-cli-build/server/app/index.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/index.segments/__PAGE__.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/index.segments/_full.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/index.segments/_head.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/index.segments/_index.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/index.segments/_tree.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/landing/page.js +1 -1
- package/cli/app/.next-cli-build/server/app/landing/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/landing.html +1 -1
- package/cli/app/.next-cli-build/server/app/landing.rsc +4 -4
- package/cli/app/.next-cli-build/server/app/landing.segments/_full.segment.rsc +4 -4
- package/cli/app/.next-cli-build/server/app/landing.segments/_head.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/landing.segments/_index.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/landing.segments/_tree.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/landing.segments/landing/__PAGE__.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/landing.segments/landing.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/login/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app/login.html +1 -1
- package/cli/app/.next-cli-build/server/app/login.rsc +4 -4
- package/cli/app/.next-cli-build/server/app/login.segments/_full.segment.rsc +4 -4
- package/cli/app/.next-cli-build/server/app/login.segments/_head.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/login.segments/_index.segment.rsc +3 -3
- package/cli/app/.next-cli-build/server/app/login.segments/_tree.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/login.segments/login/__PAGE__.segment.rsc +2 -2
- package/cli/app/.next-cli-build/server/app/login.segments/login.segment.rsc +1 -1
- package/cli/app/.next-cli-build/server/app/page_client-reference-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/app-paths-manifest.json +25 -25
- package/cli/app/.next-cli-build/server/chunks/3110.js +1 -1
- package/cli/app/.next-cli-build/server/chunks/3407.js +1 -1
- package/cli/app/.next-cli-build/server/chunks/4746.js +1 -1
- package/cli/app/.next-cli-build/server/chunks/5681.js +1 -1
- package/cli/app/.next-cli-build/server/chunks/5949.js +8 -3
- package/cli/app/.next-cli-build/server/chunks/6896.js +1 -1
- package/cli/app/.next-cli-build/server/chunks/7276.js +1 -1
- package/cli/app/.next-cli-build/server/chunks/8157.js +1 -1
- package/cli/app/.next-cli-build/server/chunks/8371.js +1 -1
- package/cli/app/.next-cli-build/server/middleware-build-manifest.js +1 -1
- package/cli/app/.next-cli-build/server/pages/404.html +1 -1
- package/cli/app/.next-cli-build/server/pages/500.html +1 -1
- package/cli/app/.next-cli-build/static/chunks/{3702-18f5f207de6e9eeb.js → 3702-a3e0eb456327db63.js} +1 -1
- package/cli/app/.next-cli-build/static/chunks/app/landing/page-6621ec8b157e77cc.js +1 -0
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- package/cli/app/cli/hooks/camoufoxRuntime.js +227 -24
- package/cli/app/cli/hooks/cloakbrowserRuntime.js +81 -31
- package/cli/app/cli/hooks/postinstall.js +3 -3
- package/cli/app/package.json +1 -1
- package/cli/app/src/lib/oauth/services/displayEnv.js +134 -0
- package/cli/hooks/camoufoxRuntime.js +227 -24
- package/cli/hooks/cloakbrowserRuntime.js +81 -31
- package/cli/hooks/postinstall.js +3 -3
- package/cli/package.json +1 -1
- package/i18n/README.ja-JP.md +19 -1191
- package/i18n/README.ru.md +19 -1293
- package/i18n/README.vi.md +19 -1292
- package/i18n/README.zh-CN.md +19 -1288
- package/open-sse/config/kiroConstants.js +1 -1
- package/package.json +1 -1
- package/src/app/landing/components/Features.js +2 -2
- package/src/app/landing/components/HeroSection.js +1 -1
- package/src/app/landing/components/HowItWorks.js +2 -2
- package/src/app/landing/page.js +3 -3
- package/src/lib/network/outboundProxy.js +37 -23
- package/src/lib/oauth/services/bulkImportBrowserEngine.js +220 -22
- package/src/lib/oauth/services/codebuddyCnBulkImportManager.js +161 -72
- package/src/lib/oauth/services/codebuddyCnPhoneAutomation.js +95 -41
- package/src/lib/oauth/services/kiroBulkImportManager.js +18 -13
- package/src/mitm/manager.js +1 -1
- package/src/shared/constants/providers.js +4 -4
- package/cli/app/.next-cli-build/static/chunks/app/landing/page-77b3f78b93a8d0c7.js +0 -1
- package/cli/app/src/lib/oauth/services/bulkImportBrowserEngine.js +0 -324
- /package/cli/app/.next-cli-build/static/{Fip2gTBHjVyX1dEyiiJZM → UogfdHPvWmU8zuWF5IR-t}/_buildManifest.js +0 -0
- /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
|
-
//
|
|
49
|
-
const CODEBUDDY_CN_DEFAULT_CONCURRENCY =
|
|
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(
|
|
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
|
|
91
|
-
return Math.min(
|
|
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).
|
|
144
|
-
//
|
|
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
|
|
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
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
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
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
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
|
-
|
|
381
|
-
|
|
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
|
-
|
|
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 ===
|
|
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}
|
|
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:
|
|
549
|
-
await page.waitForTimeout(
|
|
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(
|
|
627
|
+
await page.waitForTimeout(1_000);
|
|
555
628
|
}
|
|
556
629
|
|
|
557
630
|
// Prefer landing on console for the API probe
|
|
558
|
-
if (attempt >=
|
|
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:
|
|
634
|
+
timeout: 25_000,
|
|
562
635
|
}).catch(() => null);
|
|
563
|
-
await page.waitForTimeout(
|
|
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}
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
47
|
-
const
|
|
48
|
-
const
|
|
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 ??
|
|
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(
|
|
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:
|
|
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(
|
|
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:
|
|
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(
|
|
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:
|
|
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:
|
|
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
|
|
387
|
-
//
|
|
388
|
-
//
|
|
389
|
-
//
|
|
390
|
-
|
|
391
|
-
const
|
|
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: "
|
|
452
|
-
await waitForAnyVisible(page, SPA_READY_SELECTORS,
|
|
453
|
-
const phoneTabRetry = await waitForFirstVisibleLocator(page, PHONE_TAB_SELECTORS, { timeout:
|
|
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:
|
|
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
|
-
|
|
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:
|
|
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:
|
|
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:
|
|
648
|
-
|
|
649
|
-
//
|
|
650
|
-
const
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
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:
|
|
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
|