9router-imagefix 0.5.94 → 0.5.95
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/app/.next-cli-build/BUILD_ID +1 -1
- package/app/.next-cli-build/app-path-routes-manifest.json +6 -6
- package/app/.next-cli-build/build-manifest.json +2 -2
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/basic-chat/page.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/basic-chat/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/cli-tools/[toolId]/page.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/cli-tools/[toolId]/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/cli-tools/page.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/cli-tools/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/combos/page.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/combos/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/console-log/page.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/console-log/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/endpoint/page.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/endpoint/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/[kind]/[id]/page.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/[kind]/[id]/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/[kind]/page.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/[kind]/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/combo/[id]/page.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/combo/[id]/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/web/page.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/web/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/mitm/page.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/mitm/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/page.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/profile/page.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/profile/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/providers/[id]/page.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/providers/[id]/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/providers/new/page.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/providers/new/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/providers/page.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/providers/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/proxy-pools/page.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/proxy-pools/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/pxpipe/page.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/pxpipe/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/quota/page.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/quota/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/skills/page.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/skills/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/token-saver/page.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/token-saver/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/translator/page.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/translator/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/usage/page.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/(dashboard)/dashboard/usage/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/_global-error/page.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/_global-error.html +1 -1
- package/app/.next-cli-build/server/app/_global-error.rsc +1 -1
- package/app/.next-cli-build/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/_not-found/page.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/_not-found.html +1 -1
- package/app/.next-cli-build/server/app/_not-found.rsc +4 -4
- package/app/.next-cli-build/server/app/_not-found.segments/_full.segment.rsc +4 -4
- package/app/.next-cli-build/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +4 -4
- package/app/.next-cli-build/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/api/auth/login/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/auth/logout/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/auth/oidc/callback/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/auth/oidc/start/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/auth/oidc/test/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/auth/reset-password/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/auth/saml/acs/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/auth/saml/metadata/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/auth/saml/start/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/auth/saml/test/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/auth/status/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/cli-tools/all-statuses/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/cli-tools/antigravity-mitm/alias/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/cli-tools/antigravity-mitm/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/cli-tools/claude-settings/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/cli-tools/cline-settings/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/cli-tools/codex-settings/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/cli-tools/copilot-settings/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/cli-tools/cowork-mcp-registry/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/cli-tools/cowork-mcp-tools/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/cli-tools/cowork-settings/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/cli-tools/deepseek-tui-settings/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/cli-tools/devin-settings/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/cli-tools/droid-settings/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/cli-tools/grok-build-settings/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/cli-tools/hermes-settings/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/cli-tools/jcode-settings/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/cli-tools/kilo-settings/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/cli-tools/openclaw-settings/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/cli-tools/opencode-settings/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/combos/[id]/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/combos/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/headroom/extras/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/headroom/proxy/[...path]/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/headroom/restart/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/headroom/start/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/headroom/status/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/headroom/stop/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/health/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/init/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/keys/[id]/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/keys/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/locale/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/mcp/[plugin]/message/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/mcp/[plugin]/sse/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/media-providers/tts/deepgram/voices/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/media-providers/tts/elevenlabs/voices/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/media-providers/tts/inworld/voices/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/media-providers/tts/minimax/voices/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/media-providers/tts/voices/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/models/alias/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/models/availability/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/models/catalog-sync/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/models/custom/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/models/disabled/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/models/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/models/test/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/oauth/[provider]/[action]/route.js +1 -1
- package/app/.next-cli-build/server/app/api/oauth/[provider]/[action]/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/oauth/codex/bulk-import/route.js +1 -1
- package/app/.next-cli-build/server/app/api/oauth/codex/bulk-import/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/oauth/codex/import-token/route.js +1 -1
- package/app/.next-cli-build/server/app/api/oauth/codex/import-token/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/oauth/cursor/auto-import/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/oauth/cursor/import/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/oauth/gitlab/pat/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/oauth/grok-cli/bulk-import/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/oauth/iflow/cookie/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/oauth/kiro/api-key/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/oauth/kiro/auto-import/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/oauth/kiro/import/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/oauth/kiro/import-cli-proxy/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/oauth/kiro/social-authorize/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/oauth/kiro/social-exchange/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/pricing/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/provider-nodes/[id]/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/provider-nodes/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/provider-nodes/validate/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/providers/[id]/models/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/providers/[id]/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/providers/[id]/test/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/providers/[id]/test-models/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/providers/client/route.js +1 -1
- package/app/.next-cli-build/server/app/api/providers/client/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/providers/kilo/free-models/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/providers/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/providers/suggested-models/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/providers/test-batch/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/providers/validate/route.js +1 -1
- package/app/.next-cli-build/server/app/api/providers/validate/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/proxy-pools/[id]/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/proxy-pools/[id]/test/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/proxy-pools/cloudflare-deploy/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/proxy-pools/deno-deploy/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/proxy-pools/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/proxy-pools/vercel-deploy/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/pxpipe/health/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/pxpipe/install/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/pxpipe/logs/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/pxpipe/restart/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/pxpipe/start/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/pxpipe/stats/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/pxpipe/status/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/pxpipe/stop/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/settings/database/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/settings/proxy-test/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/settings/require-login/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/settings/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/shutdown/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/tags/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/translator/console-logs/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/translator/console-logs/stream/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/translator/load/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/translator/save/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/translator/send/route.js +1 -1
- package/app/.next-cli-build/server/app/api/translator/send/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/translator/translate/route.js +1 -1
- package/app/.next-cli-build/server/app/api/translator/translate/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/tunnel/disable/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/tunnel/enable/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/tunnel/status/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/tunnel/tailscale-check/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/tunnel/tailscale-disable/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/tunnel/tailscale-enable/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/tunnel/tailscale-install/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/usage/[connectionId]/codex-reset-credits/route.js +1 -1
- package/app/.next-cli-build/server/app/api/usage/[connectionId]/codex-reset-credits/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/usage/[connectionId]/route.js +1 -1
- package/app/.next-cli-build/server/app/api/usage/[connectionId]/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/usage/backup/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/usage/chart/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/usage/history/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/usage/logs/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/usage/providers/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/usage/request-details/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/usage/request-logs/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/usage/stats/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/usage/stream/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/v1/api/chat/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/v1/audio/speech/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/v1/audio/transcriptions/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/v1/audio/voices/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/v1/chat/completions/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/v1/embeddings/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/v1/images/generations/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/v1/messages/count_tokens/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/v1/messages/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/v1/models/[kind]/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/v1/models/info/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/v1/models/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/v1/responses/compact/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/v1/responses/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/v1/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/v1/search/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/v1/videos/[id]/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/v1/videos/edits/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/v1/videos/extensions/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/v1/videos/generations/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/v1/web/fetch/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/v1beta/models/[...path]/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/v1beta/models/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/version/route.js +1 -1
- package/app/.next-cli-build/server/app/api/version/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/version/shutdown/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/api/version/update/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/callback/page.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/callback/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/callback.html +1 -1
- package/app/.next-cli-build/server/app/callback.rsc +4 -4
- package/app/.next-cli-build/server/app/callback.segments/_full.segment.rsc +4 -4
- package/app/.next-cli-build/server/app/callback.segments/_tree.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/callback.segments/callback/__PAGE__.segment.rsc +4 -4
- package/app/.next-cli-build/server/app/dashboard/basic-chat.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/basic-chat.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/basic-chat.segments/!KGRhc2hib2FyZCk/dashboard/basic-chat/__PAGE__.segment.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/basic-chat.segments/_full.segment.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/basic-chat.segments/_tree.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/cli-tools.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/cli-tools.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/cli-tools.segments/!KGRhc2hib2FyZCk/dashboard/cli-tools/__PAGE__.segment.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/cli-tools.segments/_full.segment.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/cli-tools.segments/_tree.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/combos.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/combos.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/combos.segments/!KGRhc2hib2FyZCk/dashboard/combos/__PAGE__.segment.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/combos.segments/_full.segment.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/combos.segments/_tree.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/endpoint.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/endpoint.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/endpoint.segments/!KGRhc2hib2FyZCk/dashboard/endpoint/__PAGE__.segment.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/endpoint.segments/_full.segment.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/endpoint.segments/_tree.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/media-providers/web.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/media-providers/web.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/!KGRhc2hib2FyZCk/dashboard/media-providers/web/__PAGE__.segment.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/_full.segment.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/_tree.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/mitm.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/mitm.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/mitm.segments/!KGRhc2hib2FyZCk/dashboard/mitm/__PAGE__.segment.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/mitm.segments/_full.segment.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/mitm.segments/_tree.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/profile.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/profile.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/profile.segments/!KGRhc2hib2FyZCk/dashboard/profile/__PAGE__.segment.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/profile.segments/_full.segment.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/profile.segments/_tree.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/providers/new.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/providers/new.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/providers/new.segments/!KGRhc2hib2FyZCk/dashboard/providers/new/__PAGE__.segment.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/providers/new.segments/_full.segment.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/providers/new.segments/_tree.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/providers.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/providers.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/providers.segments/!KGRhc2hib2FyZCk/dashboard/providers/__PAGE__.segment.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/providers.segments/_full.segment.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/providers.segments/_tree.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/proxy-pools.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/proxy-pools.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/!KGRhc2hib2FyZCk/dashboard/proxy-pools/__PAGE__.segment.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/_full.segment.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/_tree.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/pxpipe.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/pxpipe.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/pxpipe.segments/!KGRhc2hib2FyZCk/dashboard/pxpipe/__PAGE__.segment.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/pxpipe.segments/_full.segment.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/pxpipe.segments/_tree.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/quota.html +2 -2
- package/app/.next-cli-build/server/app/dashboard/quota.rsc +7 -7
- package/app/.next-cli-build/server/app/dashboard/quota.segments/!KGRhc2hib2FyZCk/dashboard/quota/__PAGE__.segment.rsc +7 -7
- package/app/.next-cli-build/server/app/dashboard/quota.segments/_full.segment.rsc +7 -7
- package/app/.next-cli-build/server/app/dashboard/quota.segments/_tree.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/settings/pricing/page.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/dashboard/settings/pricing/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/dashboard/settings/pricing.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/settings/pricing.rsc +4 -4
- package/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/_full.segment.rsc +4 -4
- package/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/_tree.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/dashboard/settings/pricing/__PAGE__.segment.rsc +4 -4
- package/app/.next-cli-build/server/app/dashboard/skills.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/skills.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/skills.segments/!KGRhc2hib2FyZCk/dashboard/skills/__PAGE__.segment.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/skills.segments/_full.segment.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/skills.segments/_tree.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/token-saver.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/token-saver.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/token-saver.segments/!KGRhc2hib2FyZCk/dashboard/token-saver/__PAGE__.segment.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/token-saver.segments/_full.segment.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/token-saver.segments/_tree.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/translator.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/translator.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/translator.segments/!KGRhc2hib2FyZCk/dashboard/translator/__PAGE__.segment.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/translator.segments/_full.segment.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/translator.segments/_tree.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard/usage.html +1 -1
- package/app/.next-cli-build/server/app/dashboard/usage.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/usage.segments/!KGRhc2hib2FyZCk/dashboard/usage/__PAGE__.segment.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/usage.segments/_full.segment.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard/usage.segments/_tree.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/dashboard.html +1 -1
- package/app/.next-cli-build/server/app/dashboard.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard.segments/!KGRhc2hib2FyZCk/dashboard/__PAGE__.segment.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard.segments/_full.segment.rsc +6 -6
- package/app/.next-cli-build/server/app/dashboard.segments/_tree.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/favicon.ico/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/index.html +1 -1
- package/app/.next-cli-build/server/app/index.rsc +4 -4
- package/app/.next-cli-build/server/app/index.segments/__PAGE__.segment.rsc +4 -4
- package/app/.next-cli-build/server/app/index.segments/_full.segment.rsc +4 -4
- package/app/.next-cli-build/server/app/index.segments/_tree.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/landing/page.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/landing/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/landing.html +1 -1
- package/app/.next-cli-build/server/app/landing.rsc +4 -4
- package/app/.next-cli-build/server/app/landing.segments/_full.segment.rsc +4 -4
- package/app/.next-cli-build/server/app/landing.segments/_tree.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/landing.segments/landing/__PAGE__.segment.rsc +4 -4
- package/app/.next-cli-build/server/app/login/page.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/login/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app/login.html +1 -1
- package/app/.next-cli-build/server/app/login.rsc +5 -5
- package/app/.next-cli-build/server/app/login.segments/_full.segment.rsc +5 -5
- package/app/.next-cli-build/server/app/login.segments/_tree.segment.rsc +1 -1
- package/app/.next-cli-build/server/app/login.segments/login/__PAGE__.segment.rsc +5 -5
- package/app/.next-cli-build/server/app/manifest.webmanifest/route.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/page.js.nft.json +1 -1
- package/app/.next-cli-build/server/app/page_client-reference-manifest.js +1 -1
- package/app/.next-cli-build/server/app-paths-manifest.json +6 -6
- package/app/.next-cli-build/server/chunks/4037.js +1 -1
- package/app/.next-cli-build/server/chunks/6197.js +2 -2
- package/app/.next-cli-build/server/chunks/6922.js +1 -1
- package/app/.next-cli-build/server/chunks/7807.js +1 -1
- package/app/.next-cli-build/server/chunks/827.js +1 -1
- package/app/.next-cli-build/server/chunks/869.js +1 -1
- package/app/.next-cli-build/server/chunks/8847.js +1 -1
- package/app/.next-cli-build/server/chunks/8908.js +1 -1
- package/app/.next-cli-build/server/chunks/929.js +1 -1
- package/app/.next-cli-build/server/instrumentation.js.nft.json +1 -1
- package/app/.next-cli-build/server/middleware-build-manifest.js +1 -1
- package/app/.next-cli-build/server/middleware.js.nft.json +1 -1
- package/app/.next-cli-build/server/pages/404.html +1 -1
- package/app/.next-cli-build/server/pages/500.html +1 -1
- package/app/.next-cli-build/static/chunks/{1321-99f21e82349549e2.js → 1321-d944715e4f202568.js} +1 -1
- package/app/cli/.build-home/AppData/Roaming/9router/db/data.sqlite-shm +0 -0
- package/app/cli/.build-home/AppData/Roaming/9router/db/data.sqlite-wal +0 -0
- package/app/package.json +1 -1
- package/package.json +1 -1
- package/app/.next-cli-build/server/chunks/3666.js +0 -1
- package/app/src/sse/services/antigravityDomainBreaker.js +0 -262
- /package/app/.next-cli-build/static/{wMINFKWtJh3B20iNYsV48 → txTR0vPqJvVPhcaTOv3GX}/_buildManifest.js +0 -0
- /package/app/.next-cli-build/static/{wMINFKWtJh3B20iNYsV48 → txTR0vPqJvVPhcaTOv3GX}/_ssgManifest.js +0 -0
|
Binary file
|
|
Binary file
|
package/app/package.json
CHANGED
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";exports.id=3666,exports.ids=[3666],exports.modules={63666:(a,b,c)=>{c.d(b,{isPermanentAntigravityAuthFailure:()=>j,maybeBreakAntigravityDomain:()=>l});var d=c(89718),e=c(7803);let f=new Set(["gmail.com","googlemail.com"]),g=new Set;function h(a){if(!a||"string"!=typeof a)return"";let b=a.lastIndexOf("@");return -1===b?"":a.slice(b+1).trim().toLowerCase()}let i=[/invalid_grant/i,/PERMISSION_DENIED/i,/UNAUTHENTICATED/i,/account.*(?:deleted|disabled|not found|suspended|does not exist)/i,/user.*(?:deleted|disabled|not found|suspended)/i,/Bad Request/i,/NO_CREDENTIALS/i,/401/i,/unauthorized/i];function j(a,b){if(400!==a&&401!==a&&403!==a)return!1;if(401===a)return!0;let c=String(b||"");return c?i.some(a=>a.test(c)):401===a}async function k(a,b=null){let d=new Map,e=[...a],f=b||(async a=>{let{refreshTokenByProvider:b}=await Promise.resolve().then(c.bind(c,8521));return b("antigravity",a,null)});async function g(){for(;e.length;){let a=e.shift();if(a?.refreshToken)try{let b=await Promise.race([f({refreshToken:a.refreshToken,email:a.email}),new Promise((a,b)=>setTimeout(()=>b(Error("verify timeout")),15e3))]);d.set(a.id,!b?.accessToken)}catch(c){let b=String(c?.message||c||"");/invalid_grant|account.*(?:deleted|disabled|suspended|not found)|unauthorized_client/i.test(b)&&d.set(a.id,!0)}}}return await Promise.all(Array.from({length:Math.min(8,e.length)},g)),d}async function l(a,b,c={}){let i,j,m,n,o=h(a);if(!o)return{broken:!1,domain:"",disabledCount:0};if(b&&"antigravity"!==b||f.has(o)||g.has(o))return{broken:!1,domain:o,disabledCount:0};try{i=(await (0,d.getProviderConnections)({provider:"antigravity",isActive:!0})).filter(a=>h(a.email)===o)}catch{return{broken:!1,domain:o,disabledCount:0}}let p=i.length;if(0===p)return{broken:!1,domain:o,disabledCount:0};try{j=(await (0,d.getProviderConnections)({provider:"antigravity"})).filter(a=>h(a.email)===o)}catch{j=i}let q=j.length-p+1;m=p<3?1:p<=15?2:Math.max(2,Math.ceil(.3*j.length));let r=j.length>=6&&q/j.length>=.35;if(!(q>=m||r))return{broken:!1,domain:o,disabledCount:0};try{n=await k(i,c?.refreshFn||null)}catch{return e.warn("AG_DOMAIN_BREAKER",`${o} | verification failed; leaving ${p} accounts active`),{broken:!1,domain:o,disabledCount:0}}let s=i.filter(a=>!0===n.get(a.id)),t=i.filter(a=>!1===n.get(a.id)),u=i.filter(a=>!n.has(a.id));if(!s.length)return e.info("AG_DOMAIN_BREAKER",`${o} | threshold hit but 0/${p} accounts failed verification — not disabling`),{broken:!1,domain:o,disabledCount:0};g.add(o);let v=0,w=`domain_dead:${o}`,x=new Date().toISOString();for(let a of s)try{let b=a.data&&"object"==typeof a.data?{...a.data}:{};b.disabledReason=w,b.disabledAt=x,await (0,d.updateProviderConnection)(a.id,{isActive:!1,data:b,testStatus:"unavailable",lastError:`Domain ${o} auto-disabled: ${s.length}/${p} accounts failed token verification`,errorCode:400,lastErrorAt:x}),v++}catch{}return e.warn("AG_DOMAIN_BREAKER",`${o} | verified ${p} accounts: ${s.length} dead, ${t.length} alive (kept), ${u.length} unknown (kept) -> disabled ${v} (${w})`),{broken:!0,domain:o,disabledCount:v,deadCount:s.length,aliveCount:t.length,unknownCount:u.length}}}};
|
|
@@ -1,262 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Antigravity Domain Circuit Breaker — dynamic, no hard-coded domain list.
|
|
3
|
-
*
|
|
4
|
-
* When a GSuite seller deletes/suspends a whole domain (@gmilil.my.id,
|
|
5
|
-
* @gmosel.com, @any-random-domain.my.id ...), Google returns the same
|
|
6
|
-
* permanent 400/401/403 for EVERY account on that domain. Testing them one
|
|
7
|
-
* by one costs N × timeout before the router reaches a healthy domain.
|
|
8
|
-
*
|
|
9
|
-
* This module auto-detects a domain that is dying and bulk-disables it so the
|
|
10
|
-
* next getProviderCredentials() call skips it entirely (< 50 ms).
|
|
11
|
-
*
|
|
12
|
-
* Safe: gmail.com / googlemail.com are whitelisted — only per-account lock
|
|
13
|
-
* ever applies to them. Threshold is adaptive so a single typo does not
|
|
14
|
-
* nuke a healthy domain.
|
|
15
|
-
*
|
|
16
|
-
* PER-ACCOUNT VERIFICATION (added after a live false-positive):
|
|
17
|
-
*
|
|
18
|
-
* The ratio heuristic alone bulk-disabled 60 HEALTHY accounts. A seller had
|
|
19
|
-
* delivered two batches on the same domain — 60 `hww*` accounts that Google
|
|
20
|
-
* had deleted, and 60 `zvc*` accounts that were brand new and working. The
|
|
21
|
-
* dead batch pushed the domain past the 30% threshold, so the breaker swept
|
|
22
|
-
* the live batch with it. Verified afterwards by refreshing every token
|
|
23
|
-
* directly against Google: 60/60 of the "disabled" accounts returned a valid
|
|
24
|
-
* access_token.
|
|
25
|
-
*
|
|
26
|
-
* The lesson: a domain is a BILLING grouping, not a proxy for "this account
|
|
27
|
-
* is dead". Sellers ship multiple batches on one domain, so a dead batch says
|
|
28
|
-
* nothing about its neighbours.
|
|
29
|
-
*
|
|
30
|
-
* The ratio still earns its keep as a TRIGGER — it says "this domain is worth
|
|
31
|
-
* checking". What it must not do is decide WHO is dead. That call now goes to
|
|
32
|
-
* Google: each candidate's refresh token is exchanged, and only the ones that
|
|
33
|
-
* actually fail are disabled. Live accounts keep working, and the breaker
|
|
34
|
-
* still collapses a genuinely dead domain in one pass.
|
|
35
|
-
*/
|
|
36
|
-
import { getProviderConnections, updateProviderConnection, getSettings } from "@/lib/localDb";
|
|
37
|
-
import * as log from "../utils/logger.js";
|
|
38
|
-
|
|
39
|
-
// Never domain-break these public providers
|
|
40
|
-
const WHITELISTED_DOMAINS = new Set(["gmail.com", "googlemail.com"]);
|
|
41
|
-
|
|
42
|
-
// In-memory breaker state — survives per-process, cheap
|
|
43
|
-
const brokenDomains = new Set(); // domain -> already broken this process
|
|
44
|
-
|
|
45
|
-
export function getBrokenDomains() {
|
|
46
|
-
return new Set(brokenDomains);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
function extractDomain(email) {
|
|
50
|
-
if (!email || typeof email !== "string") return "";
|
|
51
|
-
const at = email.lastIndexOf("@");
|
|
52
|
-
if (at === -1) return "";
|
|
53
|
-
return email.slice(at + 1).trim().toLowerCase();
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
// 400/401/403 with auth text that proves the account is permanently dead,
|
|
57
|
-
// not a transient quota (429) or bad request body.
|
|
58
|
-
const PERMANENT_AUTH_PATTERNS = [
|
|
59
|
-
/invalid_grant/i,
|
|
60
|
-
/PERMISSION_DENIED/i,
|
|
61
|
-
/UNAUTHENTICATED/i,
|
|
62
|
-
/account.*(?:deleted|disabled|not found|suspended|does not exist)/i,
|
|
63
|
-
/user.*(?:deleted|disabled|not found|suspended)/i,
|
|
64
|
-
/Bad Request/i,
|
|
65
|
-
/NO_CREDENTIALS/i,
|
|
66
|
-
/401/i,
|
|
67
|
-
/unauthorized/i,
|
|
68
|
-
];
|
|
69
|
-
|
|
70
|
-
export function isPermanentAntigravityAuthFailure(status, errorText) {
|
|
71
|
-
if (status !== 400 && status !== 401 && status !== 403) return false;
|
|
72
|
-
// HTTP 401 on Google Cloud Code generateContent endpoint is ALWAYS a permanent auth failure (revoked/deleted token)
|
|
73
|
-
if (status === 401) return true;
|
|
74
|
-
const text = String(errorText || "");
|
|
75
|
-
if (!text) return status === 401;
|
|
76
|
-
return PERMANENT_AUTH_PATTERNS.some((re) => re.test(text));
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
// How many accounts to verify concurrently. Token exchange is a small POST, so
|
|
80
|
-
// a modest fan-out keeps a 120-account domain under a few seconds without
|
|
81
|
-
// tripping Google's per-client rate limits.
|
|
82
|
-
const VERIFY_CONCURRENCY = 8;
|
|
83
|
-
// Per-account timeout. A refresh that takes longer than this is treated as
|
|
84
|
-
// "unknown", NOT "dead" — see the conservative rule in verifyAccounts.
|
|
85
|
-
const VERIFY_TIMEOUT_MS = 15_000;
|
|
86
|
-
|
|
87
|
-
/**
|
|
88
|
-
* Ask Google whether each candidate account is actually dead.
|
|
89
|
-
*
|
|
90
|
-
* A refresh-token exchange is the cheapest possible probe: it spends no
|
|
91
|
-
* inference quota and Google answers definitively — `invalid_grant` with
|
|
92
|
-
* "Account has been deleted" means the account is gone, while a 200 with an
|
|
93
|
-
* access_token means it is alive and simply had a bad moment.
|
|
94
|
-
*
|
|
95
|
-
* Returns a Map of connectionId -> true (dead) / false (alive). Accounts that
|
|
96
|
-
* could not be reached are ABSENT from the map, and the caller must treat
|
|
97
|
-
* absent as alive — disabling an account because our network hiccuped would
|
|
98
|
-
* recreate the very bug this function exists to fix.
|
|
99
|
-
*
|
|
100
|
-
* @param {Array<{id: string, email: string, refreshToken?: string}>} accounts
|
|
101
|
-
* @param {object|null} refreshFn - injectable for tests
|
|
102
|
-
* @returns {Promise<Map<string, boolean>>}
|
|
103
|
-
*/
|
|
104
|
-
export async function verifyAccountsAlive(accounts, refreshFn = null) {
|
|
105
|
-
const out = new Map();
|
|
106
|
-
const queue = [...accounts];
|
|
107
|
-
const doRefresh = refreshFn || (async (creds) => {
|
|
108
|
-
const { refreshTokenByProvider } = await import("open-sse/services/tokenRefresh.js");
|
|
109
|
-
return refreshTokenByProvider("antigravity", creds, null);
|
|
110
|
-
});
|
|
111
|
-
|
|
112
|
-
async function worker() {
|
|
113
|
-
while (queue.length) {
|
|
114
|
-
const acct = queue.shift();
|
|
115
|
-
if (!acct?.refreshToken) continue; // no token to test — leave unjudged
|
|
116
|
-
try {
|
|
117
|
-
const refreshed = await Promise.race([
|
|
118
|
-
doRefresh({ refreshToken: acct.refreshToken, email: acct.email }),
|
|
119
|
-
new Promise((_, rej) => setTimeout(() => rej(new Error("verify timeout")), VERIFY_TIMEOUT_MS)),
|
|
120
|
-
]);
|
|
121
|
-
// A returned access_token proves the account is alive.
|
|
122
|
-
out.set(acct.id, !refreshed?.accessToken);
|
|
123
|
-
} catch (e) {
|
|
124
|
-
// Definitive rejections only. Anything else (timeout, network, 5xx)
|
|
125
|
-
// stays unjudged so the caller keeps the account.
|
|
126
|
-
const msg = String(e?.message || e || "");
|
|
127
|
-
if (/invalid_grant|account.*(?:deleted|disabled|suspended|not found)|unauthorized_client/i.test(msg)) {
|
|
128
|
-
out.set(acct.id, true);
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
await Promise.all(Array.from({ length: Math.min(VERIFY_CONCURRENCY, queue.length) }, worker));
|
|
135
|
-
return out;
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
/**
|
|
139
|
-
* Called right after a permanent 400/401/403 from the Antigravity executor.
|
|
140
|
-
* Decides whether to bulk-disable an entire dynamic domain.
|
|
141
|
-
*
|
|
142
|
-
* Rules (all dynamic — no hard-coded domain list):
|
|
143
|
-
* - Whitelisted domains (gmail.com) → never
|
|
144
|
-
* - Domain with < 3 total accounts → needs 1 dead to trigger (small pools)
|
|
145
|
-
* - Domain with 3-15 accounts → needs 2 dead in any window
|
|
146
|
-
* - Domain with >15 accounts → needs 2 dead OR >= 30% dead
|
|
147
|
-
*
|
|
148
|
-
* The bulk write is fire-and-forget from the chat handler's point of view
|
|
149
|
-
* (awaited here because the next account selection happens inside the same
|
|
150
|
-
* while(true) loop and must see the isActive=false).
|
|
151
|
-
*
|
|
152
|
-
* @param {string} email - failed account email
|
|
153
|
-
* @param {string} provider - must be "antigravity"
|
|
154
|
-
* @param {{refreshFn?: Function}} [opts] - refreshFn injectable for tests
|
|
155
|
-
* @returns {Promise<{ broken: boolean, domain: string, disabledCount: number }>}
|
|
156
|
-
*/
|
|
157
|
-
export async function maybeBreakAntigravityDomain(email, provider, opts = {}) {
|
|
158
|
-
const domain = extractDomain(email);
|
|
159
|
-
if (!domain) return { broken: false, domain: "", disabledCount: 0 };
|
|
160
|
-
if (provider && provider !== "antigravity") return { broken: false, domain, disabledCount: 0 };
|
|
161
|
-
if (WHITELISTED_DOMAINS.has(domain)) return { broken: false, domain, disabledCount: 0 };
|
|
162
|
-
if (brokenDomains.has(domain)) return { broken: false, domain, disabledCount: 0 };
|
|
163
|
-
|
|
164
|
-
// Use a snapshot of current active connections to compute counts
|
|
165
|
-
let allForDomain;
|
|
166
|
-
try {
|
|
167
|
-
const connections = await getProviderConnections({ provider: "antigravity", isActive: true });
|
|
168
|
-
allForDomain = connections.filter((c) => extractDomain(c.email) === domain);
|
|
169
|
-
} catch {
|
|
170
|
-
return { broken: false, domain, disabledCount: 0 };
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
const total = allForDomain.length;
|
|
174
|
-
if (total === 0) return { broken: false, domain, disabledCount: 0 };
|
|
175
|
-
|
|
176
|
-
// Re-read with inactive included to count how many are already disabled
|
|
177
|
-
let allWithInactive;
|
|
178
|
-
try {
|
|
179
|
-
const raw = await getProviderConnections({ provider: "antigravity" });
|
|
180
|
-
// getProviderConnections without isActive filter returns all — but we want only this domain
|
|
181
|
-
allWithInactive = raw.filter((c) => extractDomain(c.email) === domain);
|
|
182
|
-
} catch {
|
|
183
|
-
allWithInactive = allForDomain;
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
const alreadyDisabled = allWithInactive.length - total;
|
|
187
|
-
const deadCount = alreadyDisabled + 1; // +1 for the just-failed account (not yet written as disabled in this call)
|
|
188
|
-
|
|
189
|
-
// Adaptive threshold — dynamic per domain size
|
|
190
|
-
let threshold;
|
|
191
|
-
if (total < 3) threshold = 1;
|
|
192
|
-
else if (total <= 15) threshold = 2;
|
|
193
|
-
else threshold = Math.max(2, Math.ceil(allWithInactive.length * 0.3));
|
|
194
|
-
|
|
195
|
-
// Alternative ratio trigger for large domains (e.g. 40 accounts, 12 already dead = 30%)
|
|
196
|
-
const ratioTriggered = allWithInactive.length >= 6 && deadCount / allWithInactive.length >= 0.35;
|
|
197
|
-
|
|
198
|
-
const shouldBreak = deadCount >= threshold || ratioTriggered;
|
|
199
|
-
if (!shouldBreak) {
|
|
200
|
-
return { broken: false, domain, disabledCount: 0 };
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
// The threshold says "this domain is worth checking" — it does NOT say which
|
|
204
|
-
// accounts are dead. Verify against Google before writing anything: a domain
|
|
205
|
-
// is a billing grouping, and sellers ship multiple batches on one domain, so
|
|
206
|
-
// a dead batch must not take its live neighbours down with it.
|
|
207
|
-
let verdicts;
|
|
208
|
-
try {
|
|
209
|
-
verdicts = await verifyAccountsAlive(allForDomain, opts?.refreshFn || null);
|
|
210
|
-
} catch {
|
|
211
|
-
// Verification itself failed — do NOT disable on a guess.
|
|
212
|
-
log.warn("AG_DOMAIN_BREAKER", `${domain} | verification failed; leaving ${total} accounts active`);
|
|
213
|
-
return { broken: false, domain, disabledCount: 0 };
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
const dead = allForDomain.filter((c) => verdicts.get(c.id) === true);
|
|
217
|
-
const alive = allForDomain.filter((c) => verdicts.get(c.id) === false);
|
|
218
|
-
const unknown = allForDomain.filter((c) => !verdicts.has(c.id));
|
|
219
|
-
|
|
220
|
-
if (!dead.length) {
|
|
221
|
-
log.info("AG_DOMAIN_BREAKER", `${domain} | threshold hit but 0/${total} accounts failed verification — not disabling`);
|
|
222
|
-
return { broken: false, domain, disabledCount: 0 };
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
// Only now do we treat the domain as broken — and only for the accounts
|
|
226
|
-
// Google actually rejected.
|
|
227
|
-
brokenDomains.add(domain);
|
|
228
|
-
|
|
229
|
-
let disabledCount = 0;
|
|
230
|
-
const reason = `domain_dead:${domain}`;
|
|
231
|
-
const nowIso = new Date().toISOString();
|
|
232
|
-
|
|
233
|
-
for (const c of dead) {
|
|
234
|
-
try {
|
|
235
|
-
const data = c.data && typeof c.data === "object" ? { ...c.data } : {};
|
|
236
|
-
data.disabledReason = reason;
|
|
237
|
-
data.disabledAt = nowIso;
|
|
238
|
-
await updateProviderConnection(c.id, {
|
|
239
|
-
isActive: false,
|
|
240
|
-
data,
|
|
241
|
-
testStatus: "unavailable",
|
|
242
|
-
lastError: `Domain ${domain} auto-disabled: ${dead.length}/${total} accounts failed token verification`,
|
|
243
|
-
errorCode: 400,
|
|
244
|
-
lastErrorAt: nowIso,
|
|
245
|
-
});
|
|
246
|
-
disabledCount++;
|
|
247
|
-
} catch {
|
|
248
|
-
// best effort per account
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
log.warn(
|
|
253
|
-
"AG_DOMAIN_BREAKER",
|
|
254
|
-
`${domain} | verified ${total} accounts: ${dead.length} dead, ${alive.length} alive (kept), ${unknown.length} unknown (kept) -> disabled ${disabledCount} (${reason})`
|
|
255
|
-
);
|
|
256
|
-
return { broken: true, domain, disabledCount, deadCount: dead.length, aliveCount: alive.length, unknownCount: unknown.length };
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
// Test-only: reset in-memory set
|
|
260
|
-
export function _resetBreakerForTest() {
|
|
261
|
-
brokenDomains.clear();
|
|
262
|
-
}
|
|
File without changes
|
/package/app/.next-cli-build/static/{wMINFKWtJh3B20iNYsV48 → txTR0vPqJvVPhcaTOv3GX}/_ssgManifest.js
RENAMED
|
File without changes
|