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.
Files changed (374) hide show
  1. package/app/.next-cli-build/BUILD_ID +1 -1
  2. package/app/.next-cli-build/app-path-routes-manifest.json +6 -6
  3. package/app/.next-cli-build/build-manifest.json +2 -2
  4. package/app/.next-cli-build/server/app/(dashboard)/dashboard/basic-chat/page.js.nft.json +1 -1
  5. package/app/.next-cli-build/server/app/(dashboard)/dashboard/basic-chat/page_client-reference-manifest.js +1 -1
  6. package/app/.next-cli-build/server/app/(dashboard)/dashboard/cli-tools/[toolId]/page.js.nft.json +1 -1
  7. package/app/.next-cli-build/server/app/(dashboard)/dashboard/cli-tools/[toolId]/page_client-reference-manifest.js +1 -1
  8. package/app/.next-cli-build/server/app/(dashboard)/dashboard/cli-tools/page.js.nft.json +1 -1
  9. package/app/.next-cli-build/server/app/(dashboard)/dashboard/cli-tools/page_client-reference-manifest.js +1 -1
  10. package/app/.next-cli-build/server/app/(dashboard)/dashboard/combos/page.js.nft.json +1 -1
  11. package/app/.next-cli-build/server/app/(dashboard)/dashboard/combos/page_client-reference-manifest.js +1 -1
  12. package/app/.next-cli-build/server/app/(dashboard)/dashboard/console-log/page.js.nft.json +1 -1
  13. package/app/.next-cli-build/server/app/(dashboard)/dashboard/console-log/page_client-reference-manifest.js +1 -1
  14. package/app/.next-cli-build/server/app/(dashboard)/dashboard/endpoint/page.js.nft.json +1 -1
  15. package/app/.next-cli-build/server/app/(dashboard)/dashboard/endpoint/page_client-reference-manifest.js +1 -1
  16. package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/[kind]/[id]/page.js.nft.json +1 -1
  17. package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/[kind]/[id]/page_client-reference-manifest.js +1 -1
  18. package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/[kind]/page.js.nft.json +1 -1
  19. package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/[kind]/page_client-reference-manifest.js +1 -1
  20. package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/combo/[id]/page.js.nft.json +1 -1
  21. package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/combo/[id]/page_client-reference-manifest.js +1 -1
  22. package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/web/page.js.nft.json +1 -1
  23. package/app/.next-cli-build/server/app/(dashboard)/dashboard/media-providers/web/page_client-reference-manifest.js +1 -1
  24. package/app/.next-cli-build/server/app/(dashboard)/dashboard/mitm/page.js.nft.json +1 -1
  25. package/app/.next-cli-build/server/app/(dashboard)/dashboard/mitm/page_client-reference-manifest.js +1 -1
  26. package/app/.next-cli-build/server/app/(dashboard)/dashboard/page.js.nft.json +1 -1
  27. package/app/.next-cli-build/server/app/(dashboard)/dashboard/page_client-reference-manifest.js +1 -1
  28. package/app/.next-cli-build/server/app/(dashboard)/dashboard/profile/page.js.nft.json +1 -1
  29. package/app/.next-cli-build/server/app/(dashboard)/dashboard/profile/page_client-reference-manifest.js +1 -1
  30. package/app/.next-cli-build/server/app/(dashboard)/dashboard/providers/[id]/page.js.nft.json +1 -1
  31. package/app/.next-cli-build/server/app/(dashboard)/dashboard/providers/[id]/page_client-reference-manifest.js +1 -1
  32. package/app/.next-cli-build/server/app/(dashboard)/dashboard/providers/new/page.js.nft.json +1 -1
  33. package/app/.next-cli-build/server/app/(dashboard)/dashboard/providers/new/page_client-reference-manifest.js +1 -1
  34. package/app/.next-cli-build/server/app/(dashboard)/dashboard/providers/page.js.nft.json +1 -1
  35. package/app/.next-cli-build/server/app/(dashboard)/dashboard/providers/page_client-reference-manifest.js +1 -1
  36. package/app/.next-cli-build/server/app/(dashboard)/dashboard/proxy-pools/page.js.nft.json +1 -1
  37. package/app/.next-cli-build/server/app/(dashboard)/dashboard/proxy-pools/page_client-reference-manifest.js +1 -1
  38. package/app/.next-cli-build/server/app/(dashboard)/dashboard/pxpipe/page.js.nft.json +1 -1
  39. package/app/.next-cli-build/server/app/(dashboard)/dashboard/pxpipe/page_client-reference-manifest.js +1 -1
  40. package/app/.next-cli-build/server/app/(dashboard)/dashboard/quota/page.js.nft.json +1 -1
  41. package/app/.next-cli-build/server/app/(dashboard)/dashboard/quota/page_client-reference-manifest.js +1 -1
  42. package/app/.next-cli-build/server/app/(dashboard)/dashboard/skills/page.js.nft.json +1 -1
  43. package/app/.next-cli-build/server/app/(dashboard)/dashboard/skills/page_client-reference-manifest.js +1 -1
  44. package/app/.next-cli-build/server/app/(dashboard)/dashboard/token-saver/page.js.nft.json +1 -1
  45. package/app/.next-cli-build/server/app/(dashboard)/dashboard/token-saver/page_client-reference-manifest.js +1 -1
  46. package/app/.next-cli-build/server/app/(dashboard)/dashboard/translator/page.js.nft.json +1 -1
  47. package/app/.next-cli-build/server/app/(dashboard)/dashboard/translator/page_client-reference-manifest.js +1 -1
  48. package/app/.next-cli-build/server/app/(dashboard)/dashboard/usage/page.js.nft.json +1 -1
  49. package/app/.next-cli-build/server/app/(dashboard)/dashboard/usage/page_client-reference-manifest.js +1 -1
  50. package/app/.next-cli-build/server/app/_global-error/page.js.nft.json +1 -1
  51. package/app/.next-cli-build/server/app/_global-error/page_client-reference-manifest.js +1 -1
  52. package/app/.next-cli-build/server/app/_global-error.html +1 -1
  53. package/app/.next-cli-build/server/app/_global-error.rsc +1 -1
  54. package/app/.next-cli-build/server/app/_global-error.segments/_full.segment.rsc +1 -1
  55. package/app/.next-cli-build/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  56. package/app/.next-cli-build/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  57. package/app/.next-cli-build/server/app/_not-found/page.js.nft.json +1 -1
  58. package/app/.next-cli-build/server/app/_not-found/page_client-reference-manifest.js +1 -1
  59. package/app/.next-cli-build/server/app/_not-found.html +1 -1
  60. package/app/.next-cli-build/server/app/_not-found.rsc +4 -4
  61. package/app/.next-cli-build/server/app/_not-found.segments/_full.segment.rsc +4 -4
  62. package/app/.next-cli-build/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +4 -4
  63. package/app/.next-cli-build/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  64. package/app/.next-cli-build/server/app/api/auth/login/route.js.nft.json +1 -1
  65. package/app/.next-cli-build/server/app/api/auth/logout/route.js.nft.json +1 -1
  66. package/app/.next-cli-build/server/app/api/auth/oidc/callback/route.js.nft.json +1 -1
  67. package/app/.next-cli-build/server/app/api/auth/oidc/start/route.js.nft.json +1 -1
  68. package/app/.next-cli-build/server/app/api/auth/oidc/test/route.js.nft.json +1 -1
  69. package/app/.next-cli-build/server/app/api/auth/reset-password/route.js.nft.json +1 -1
  70. package/app/.next-cli-build/server/app/api/auth/saml/acs/route.js.nft.json +1 -1
  71. package/app/.next-cli-build/server/app/api/auth/saml/metadata/route.js.nft.json +1 -1
  72. package/app/.next-cli-build/server/app/api/auth/saml/start/route.js.nft.json +1 -1
  73. package/app/.next-cli-build/server/app/api/auth/saml/test/route.js.nft.json +1 -1
  74. package/app/.next-cli-build/server/app/api/auth/status/route.js.nft.json +1 -1
  75. package/app/.next-cli-build/server/app/api/cli-tools/all-statuses/route.js.nft.json +1 -1
  76. package/app/.next-cli-build/server/app/api/cli-tools/antigravity-mitm/alias/route.js.nft.json +1 -1
  77. package/app/.next-cli-build/server/app/api/cli-tools/antigravity-mitm/route.js.nft.json +1 -1
  78. package/app/.next-cli-build/server/app/api/cli-tools/claude-settings/route.js.nft.json +1 -1
  79. package/app/.next-cli-build/server/app/api/cli-tools/cline-settings/route.js.nft.json +1 -1
  80. package/app/.next-cli-build/server/app/api/cli-tools/codex-settings/route.js.nft.json +1 -1
  81. package/app/.next-cli-build/server/app/api/cli-tools/copilot-settings/route.js.nft.json +1 -1
  82. package/app/.next-cli-build/server/app/api/cli-tools/cowork-mcp-registry/route.js.nft.json +1 -1
  83. package/app/.next-cli-build/server/app/api/cli-tools/cowork-mcp-tools/route.js.nft.json +1 -1
  84. package/app/.next-cli-build/server/app/api/cli-tools/cowork-settings/route.js.nft.json +1 -1
  85. package/app/.next-cli-build/server/app/api/cli-tools/deepseek-tui-settings/route.js.nft.json +1 -1
  86. package/app/.next-cli-build/server/app/api/cli-tools/devin-settings/route.js.nft.json +1 -1
  87. package/app/.next-cli-build/server/app/api/cli-tools/droid-settings/route.js.nft.json +1 -1
  88. package/app/.next-cli-build/server/app/api/cli-tools/grok-build-settings/route.js.nft.json +1 -1
  89. package/app/.next-cli-build/server/app/api/cli-tools/hermes-settings/route.js.nft.json +1 -1
  90. package/app/.next-cli-build/server/app/api/cli-tools/jcode-settings/route.js.nft.json +1 -1
  91. package/app/.next-cli-build/server/app/api/cli-tools/kilo-settings/route.js.nft.json +1 -1
  92. package/app/.next-cli-build/server/app/api/cli-tools/openclaw-settings/route.js.nft.json +1 -1
  93. package/app/.next-cli-build/server/app/api/cli-tools/opencode-settings/route.js.nft.json +1 -1
  94. package/app/.next-cli-build/server/app/api/combos/[id]/route.js.nft.json +1 -1
  95. package/app/.next-cli-build/server/app/api/combos/route.js.nft.json +1 -1
  96. package/app/.next-cli-build/server/app/api/headroom/extras/route.js.nft.json +1 -1
  97. package/app/.next-cli-build/server/app/api/headroom/proxy/[...path]/route.js.nft.json +1 -1
  98. package/app/.next-cli-build/server/app/api/headroom/restart/route.js.nft.json +1 -1
  99. package/app/.next-cli-build/server/app/api/headroom/start/route.js.nft.json +1 -1
  100. package/app/.next-cli-build/server/app/api/headroom/status/route.js.nft.json +1 -1
  101. package/app/.next-cli-build/server/app/api/headroom/stop/route.js.nft.json +1 -1
  102. package/app/.next-cli-build/server/app/api/health/route.js.nft.json +1 -1
  103. package/app/.next-cli-build/server/app/api/init/route.js.nft.json +1 -1
  104. package/app/.next-cli-build/server/app/api/keys/[id]/route.js.nft.json +1 -1
  105. package/app/.next-cli-build/server/app/api/keys/route.js.nft.json +1 -1
  106. package/app/.next-cli-build/server/app/api/locale/route.js.nft.json +1 -1
  107. package/app/.next-cli-build/server/app/api/mcp/[plugin]/message/route.js.nft.json +1 -1
  108. package/app/.next-cli-build/server/app/api/mcp/[plugin]/sse/route.js.nft.json +1 -1
  109. package/app/.next-cli-build/server/app/api/media-providers/tts/deepgram/voices/route.js.nft.json +1 -1
  110. package/app/.next-cli-build/server/app/api/media-providers/tts/elevenlabs/voices/route.js.nft.json +1 -1
  111. package/app/.next-cli-build/server/app/api/media-providers/tts/inworld/voices/route.js.nft.json +1 -1
  112. package/app/.next-cli-build/server/app/api/media-providers/tts/minimax/voices/route.js.nft.json +1 -1
  113. package/app/.next-cli-build/server/app/api/media-providers/tts/voices/route.js.nft.json +1 -1
  114. package/app/.next-cli-build/server/app/api/models/alias/route.js.nft.json +1 -1
  115. package/app/.next-cli-build/server/app/api/models/availability/route.js.nft.json +1 -1
  116. package/app/.next-cli-build/server/app/api/models/catalog-sync/route.js.nft.json +1 -1
  117. package/app/.next-cli-build/server/app/api/models/custom/route.js.nft.json +1 -1
  118. package/app/.next-cli-build/server/app/api/models/disabled/route.js.nft.json +1 -1
  119. package/app/.next-cli-build/server/app/api/models/route.js.nft.json +1 -1
  120. package/app/.next-cli-build/server/app/api/models/test/route.js.nft.json +1 -1
  121. package/app/.next-cli-build/server/app/api/oauth/[provider]/[action]/route.js +1 -1
  122. package/app/.next-cli-build/server/app/api/oauth/[provider]/[action]/route.js.nft.json +1 -1
  123. package/app/.next-cli-build/server/app/api/oauth/codex/bulk-import/route.js +1 -1
  124. package/app/.next-cli-build/server/app/api/oauth/codex/bulk-import/route.js.nft.json +1 -1
  125. package/app/.next-cli-build/server/app/api/oauth/codex/import-token/route.js +1 -1
  126. package/app/.next-cli-build/server/app/api/oauth/codex/import-token/route.js.nft.json +1 -1
  127. package/app/.next-cli-build/server/app/api/oauth/cursor/auto-import/route.js.nft.json +1 -1
  128. package/app/.next-cli-build/server/app/api/oauth/cursor/import/route.js.nft.json +1 -1
  129. package/app/.next-cli-build/server/app/api/oauth/gitlab/pat/route.js.nft.json +1 -1
  130. package/app/.next-cli-build/server/app/api/oauth/grok-cli/bulk-import/route.js.nft.json +1 -1
  131. package/app/.next-cli-build/server/app/api/oauth/iflow/cookie/route.js.nft.json +1 -1
  132. package/app/.next-cli-build/server/app/api/oauth/kiro/api-key/route.js.nft.json +1 -1
  133. package/app/.next-cli-build/server/app/api/oauth/kiro/auto-import/route.js.nft.json +1 -1
  134. package/app/.next-cli-build/server/app/api/oauth/kiro/import/route.js.nft.json +1 -1
  135. package/app/.next-cli-build/server/app/api/oauth/kiro/import-cli-proxy/route.js.nft.json +1 -1
  136. package/app/.next-cli-build/server/app/api/oauth/kiro/social-authorize/route.js.nft.json +1 -1
  137. package/app/.next-cli-build/server/app/api/oauth/kiro/social-exchange/route.js.nft.json +1 -1
  138. package/app/.next-cli-build/server/app/api/pricing/route.js.nft.json +1 -1
  139. package/app/.next-cli-build/server/app/api/provider-nodes/[id]/route.js.nft.json +1 -1
  140. package/app/.next-cli-build/server/app/api/provider-nodes/route.js.nft.json +1 -1
  141. package/app/.next-cli-build/server/app/api/provider-nodes/validate/route.js.nft.json +1 -1
  142. package/app/.next-cli-build/server/app/api/providers/[id]/models/route.js.nft.json +1 -1
  143. package/app/.next-cli-build/server/app/api/providers/[id]/route.js.nft.json +1 -1
  144. package/app/.next-cli-build/server/app/api/providers/[id]/test/route.js.nft.json +1 -1
  145. package/app/.next-cli-build/server/app/api/providers/[id]/test-models/route.js.nft.json +1 -1
  146. package/app/.next-cli-build/server/app/api/providers/client/route.js +1 -1
  147. package/app/.next-cli-build/server/app/api/providers/client/route.js.nft.json +1 -1
  148. package/app/.next-cli-build/server/app/api/providers/kilo/free-models/route.js.nft.json +1 -1
  149. package/app/.next-cli-build/server/app/api/providers/route.js.nft.json +1 -1
  150. package/app/.next-cli-build/server/app/api/providers/suggested-models/route.js.nft.json +1 -1
  151. package/app/.next-cli-build/server/app/api/providers/test-batch/route.js.nft.json +1 -1
  152. package/app/.next-cli-build/server/app/api/providers/validate/route.js +1 -1
  153. package/app/.next-cli-build/server/app/api/providers/validate/route.js.nft.json +1 -1
  154. package/app/.next-cli-build/server/app/api/proxy-pools/[id]/route.js.nft.json +1 -1
  155. package/app/.next-cli-build/server/app/api/proxy-pools/[id]/test/route.js.nft.json +1 -1
  156. package/app/.next-cli-build/server/app/api/proxy-pools/cloudflare-deploy/route.js.nft.json +1 -1
  157. package/app/.next-cli-build/server/app/api/proxy-pools/deno-deploy/route.js.nft.json +1 -1
  158. package/app/.next-cli-build/server/app/api/proxy-pools/route.js.nft.json +1 -1
  159. package/app/.next-cli-build/server/app/api/proxy-pools/vercel-deploy/route.js.nft.json +1 -1
  160. package/app/.next-cli-build/server/app/api/pxpipe/health/route.js.nft.json +1 -1
  161. package/app/.next-cli-build/server/app/api/pxpipe/install/route.js.nft.json +1 -1
  162. package/app/.next-cli-build/server/app/api/pxpipe/logs/route.js.nft.json +1 -1
  163. package/app/.next-cli-build/server/app/api/pxpipe/restart/route.js.nft.json +1 -1
  164. package/app/.next-cli-build/server/app/api/pxpipe/start/route.js.nft.json +1 -1
  165. package/app/.next-cli-build/server/app/api/pxpipe/stats/route.js.nft.json +1 -1
  166. package/app/.next-cli-build/server/app/api/pxpipe/status/route.js.nft.json +1 -1
  167. package/app/.next-cli-build/server/app/api/pxpipe/stop/route.js.nft.json +1 -1
  168. package/app/.next-cli-build/server/app/api/settings/database/route.js.nft.json +1 -1
  169. package/app/.next-cli-build/server/app/api/settings/proxy-test/route.js.nft.json +1 -1
  170. package/app/.next-cli-build/server/app/api/settings/require-login/route.js.nft.json +1 -1
  171. package/app/.next-cli-build/server/app/api/settings/route.js.nft.json +1 -1
  172. package/app/.next-cli-build/server/app/api/shutdown/route.js.nft.json +1 -1
  173. package/app/.next-cli-build/server/app/api/tags/route.js.nft.json +1 -1
  174. package/app/.next-cli-build/server/app/api/translator/console-logs/route.js.nft.json +1 -1
  175. package/app/.next-cli-build/server/app/api/translator/console-logs/stream/route.js.nft.json +1 -1
  176. package/app/.next-cli-build/server/app/api/translator/load/route.js.nft.json +1 -1
  177. package/app/.next-cli-build/server/app/api/translator/save/route.js.nft.json +1 -1
  178. package/app/.next-cli-build/server/app/api/translator/send/route.js +1 -1
  179. package/app/.next-cli-build/server/app/api/translator/send/route.js.nft.json +1 -1
  180. package/app/.next-cli-build/server/app/api/translator/translate/route.js +1 -1
  181. package/app/.next-cli-build/server/app/api/translator/translate/route.js.nft.json +1 -1
  182. package/app/.next-cli-build/server/app/api/tunnel/disable/route.js.nft.json +1 -1
  183. package/app/.next-cli-build/server/app/api/tunnel/enable/route.js.nft.json +1 -1
  184. package/app/.next-cli-build/server/app/api/tunnel/status/route.js.nft.json +1 -1
  185. package/app/.next-cli-build/server/app/api/tunnel/tailscale-check/route.js.nft.json +1 -1
  186. package/app/.next-cli-build/server/app/api/tunnel/tailscale-disable/route.js.nft.json +1 -1
  187. package/app/.next-cli-build/server/app/api/tunnel/tailscale-enable/route.js.nft.json +1 -1
  188. package/app/.next-cli-build/server/app/api/tunnel/tailscale-install/route.js.nft.json +1 -1
  189. package/app/.next-cli-build/server/app/api/usage/[connectionId]/codex-reset-credits/route.js +1 -1
  190. package/app/.next-cli-build/server/app/api/usage/[connectionId]/codex-reset-credits/route.js.nft.json +1 -1
  191. package/app/.next-cli-build/server/app/api/usage/[connectionId]/route.js +1 -1
  192. package/app/.next-cli-build/server/app/api/usage/[connectionId]/route.js.nft.json +1 -1
  193. package/app/.next-cli-build/server/app/api/usage/backup/route.js.nft.json +1 -1
  194. package/app/.next-cli-build/server/app/api/usage/chart/route.js.nft.json +1 -1
  195. package/app/.next-cli-build/server/app/api/usage/history/route.js.nft.json +1 -1
  196. package/app/.next-cli-build/server/app/api/usage/logs/route.js.nft.json +1 -1
  197. package/app/.next-cli-build/server/app/api/usage/providers/route.js.nft.json +1 -1
  198. package/app/.next-cli-build/server/app/api/usage/request-details/route.js.nft.json +1 -1
  199. package/app/.next-cli-build/server/app/api/usage/request-logs/route.js.nft.json +1 -1
  200. package/app/.next-cli-build/server/app/api/usage/stats/route.js.nft.json +1 -1
  201. package/app/.next-cli-build/server/app/api/usage/stream/route.js.nft.json +1 -1
  202. package/app/.next-cli-build/server/app/api/v1/api/chat/route.js.nft.json +1 -1
  203. package/app/.next-cli-build/server/app/api/v1/audio/speech/route.js.nft.json +1 -1
  204. package/app/.next-cli-build/server/app/api/v1/audio/transcriptions/route.js.nft.json +1 -1
  205. package/app/.next-cli-build/server/app/api/v1/audio/voices/route.js.nft.json +1 -1
  206. package/app/.next-cli-build/server/app/api/v1/chat/completions/route.js.nft.json +1 -1
  207. package/app/.next-cli-build/server/app/api/v1/embeddings/route.js.nft.json +1 -1
  208. package/app/.next-cli-build/server/app/api/v1/images/generations/route.js.nft.json +1 -1
  209. package/app/.next-cli-build/server/app/api/v1/messages/count_tokens/route.js.nft.json +1 -1
  210. package/app/.next-cli-build/server/app/api/v1/messages/route.js.nft.json +1 -1
  211. package/app/.next-cli-build/server/app/api/v1/models/[kind]/route.js.nft.json +1 -1
  212. package/app/.next-cli-build/server/app/api/v1/models/info/route.js.nft.json +1 -1
  213. package/app/.next-cli-build/server/app/api/v1/models/route.js.nft.json +1 -1
  214. package/app/.next-cli-build/server/app/api/v1/responses/compact/route.js.nft.json +1 -1
  215. package/app/.next-cli-build/server/app/api/v1/responses/route.js.nft.json +1 -1
  216. package/app/.next-cli-build/server/app/api/v1/route.js.nft.json +1 -1
  217. package/app/.next-cli-build/server/app/api/v1/search/route.js.nft.json +1 -1
  218. package/app/.next-cli-build/server/app/api/v1/videos/[id]/route.js.nft.json +1 -1
  219. package/app/.next-cli-build/server/app/api/v1/videos/edits/route.js.nft.json +1 -1
  220. package/app/.next-cli-build/server/app/api/v1/videos/extensions/route.js.nft.json +1 -1
  221. package/app/.next-cli-build/server/app/api/v1/videos/generations/route.js.nft.json +1 -1
  222. package/app/.next-cli-build/server/app/api/v1/web/fetch/route.js.nft.json +1 -1
  223. package/app/.next-cli-build/server/app/api/v1beta/models/[...path]/route.js.nft.json +1 -1
  224. package/app/.next-cli-build/server/app/api/v1beta/models/route.js.nft.json +1 -1
  225. package/app/.next-cli-build/server/app/api/version/route.js +1 -1
  226. package/app/.next-cli-build/server/app/api/version/route.js.nft.json +1 -1
  227. package/app/.next-cli-build/server/app/api/version/shutdown/route.js.nft.json +1 -1
  228. package/app/.next-cli-build/server/app/api/version/update/route.js.nft.json +1 -1
  229. package/app/.next-cli-build/server/app/callback/page.js.nft.json +1 -1
  230. package/app/.next-cli-build/server/app/callback/page_client-reference-manifest.js +1 -1
  231. package/app/.next-cli-build/server/app/callback.html +1 -1
  232. package/app/.next-cli-build/server/app/callback.rsc +4 -4
  233. package/app/.next-cli-build/server/app/callback.segments/_full.segment.rsc +4 -4
  234. package/app/.next-cli-build/server/app/callback.segments/_tree.segment.rsc +1 -1
  235. package/app/.next-cli-build/server/app/callback.segments/callback/__PAGE__.segment.rsc +4 -4
  236. package/app/.next-cli-build/server/app/dashboard/basic-chat.html +1 -1
  237. package/app/.next-cli-build/server/app/dashboard/basic-chat.rsc +6 -6
  238. package/app/.next-cli-build/server/app/dashboard/basic-chat.segments/!KGRhc2hib2FyZCk/dashboard/basic-chat/__PAGE__.segment.rsc +6 -6
  239. package/app/.next-cli-build/server/app/dashboard/basic-chat.segments/_full.segment.rsc +6 -6
  240. package/app/.next-cli-build/server/app/dashboard/basic-chat.segments/_tree.segment.rsc +1 -1
  241. package/app/.next-cli-build/server/app/dashboard/cli-tools.html +1 -1
  242. package/app/.next-cli-build/server/app/dashboard/cli-tools.rsc +6 -6
  243. package/app/.next-cli-build/server/app/dashboard/cli-tools.segments/!KGRhc2hib2FyZCk/dashboard/cli-tools/__PAGE__.segment.rsc +6 -6
  244. package/app/.next-cli-build/server/app/dashboard/cli-tools.segments/_full.segment.rsc +6 -6
  245. package/app/.next-cli-build/server/app/dashboard/cli-tools.segments/_tree.segment.rsc +1 -1
  246. package/app/.next-cli-build/server/app/dashboard/combos.html +1 -1
  247. package/app/.next-cli-build/server/app/dashboard/combos.rsc +6 -6
  248. package/app/.next-cli-build/server/app/dashboard/combos.segments/!KGRhc2hib2FyZCk/dashboard/combos/__PAGE__.segment.rsc +6 -6
  249. package/app/.next-cli-build/server/app/dashboard/combos.segments/_full.segment.rsc +6 -6
  250. package/app/.next-cli-build/server/app/dashboard/combos.segments/_tree.segment.rsc +1 -1
  251. package/app/.next-cli-build/server/app/dashboard/endpoint.html +1 -1
  252. package/app/.next-cli-build/server/app/dashboard/endpoint.rsc +6 -6
  253. package/app/.next-cli-build/server/app/dashboard/endpoint.segments/!KGRhc2hib2FyZCk/dashboard/endpoint/__PAGE__.segment.rsc +6 -6
  254. package/app/.next-cli-build/server/app/dashboard/endpoint.segments/_full.segment.rsc +6 -6
  255. package/app/.next-cli-build/server/app/dashboard/endpoint.segments/_tree.segment.rsc +1 -1
  256. package/app/.next-cli-build/server/app/dashboard/media-providers/web.html +1 -1
  257. package/app/.next-cli-build/server/app/dashboard/media-providers/web.rsc +6 -6
  258. package/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/!KGRhc2hib2FyZCk/dashboard/media-providers/web/__PAGE__.segment.rsc +6 -6
  259. package/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/_full.segment.rsc +6 -6
  260. package/app/.next-cli-build/server/app/dashboard/media-providers/web.segments/_tree.segment.rsc +1 -1
  261. package/app/.next-cli-build/server/app/dashboard/mitm.html +1 -1
  262. package/app/.next-cli-build/server/app/dashboard/mitm.rsc +6 -6
  263. package/app/.next-cli-build/server/app/dashboard/mitm.segments/!KGRhc2hib2FyZCk/dashboard/mitm/__PAGE__.segment.rsc +6 -6
  264. package/app/.next-cli-build/server/app/dashboard/mitm.segments/_full.segment.rsc +6 -6
  265. package/app/.next-cli-build/server/app/dashboard/mitm.segments/_tree.segment.rsc +1 -1
  266. package/app/.next-cli-build/server/app/dashboard/profile.html +1 -1
  267. package/app/.next-cli-build/server/app/dashboard/profile.rsc +6 -6
  268. package/app/.next-cli-build/server/app/dashboard/profile.segments/!KGRhc2hib2FyZCk/dashboard/profile/__PAGE__.segment.rsc +6 -6
  269. package/app/.next-cli-build/server/app/dashboard/profile.segments/_full.segment.rsc +6 -6
  270. package/app/.next-cli-build/server/app/dashboard/profile.segments/_tree.segment.rsc +1 -1
  271. package/app/.next-cli-build/server/app/dashboard/providers/new.html +1 -1
  272. package/app/.next-cli-build/server/app/dashboard/providers/new.rsc +6 -6
  273. package/app/.next-cli-build/server/app/dashboard/providers/new.segments/!KGRhc2hib2FyZCk/dashboard/providers/new/__PAGE__.segment.rsc +6 -6
  274. package/app/.next-cli-build/server/app/dashboard/providers/new.segments/_full.segment.rsc +6 -6
  275. package/app/.next-cli-build/server/app/dashboard/providers/new.segments/_tree.segment.rsc +1 -1
  276. package/app/.next-cli-build/server/app/dashboard/providers.html +1 -1
  277. package/app/.next-cli-build/server/app/dashboard/providers.rsc +6 -6
  278. package/app/.next-cli-build/server/app/dashboard/providers.segments/!KGRhc2hib2FyZCk/dashboard/providers/__PAGE__.segment.rsc +6 -6
  279. package/app/.next-cli-build/server/app/dashboard/providers.segments/_full.segment.rsc +6 -6
  280. package/app/.next-cli-build/server/app/dashboard/providers.segments/_tree.segment.rsc +1 -1
  281. package/app/.next-cli-build/server/app/dashboard/proxy-pools.html +1 -1
  282. package/app/.next-cli-build/server/app/dashboard/proxy-pools.rsc +6 -6
  283. package/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/!KGRhc2hib2FyZCk/dashboard/proxy-pools/__PAGE__.segment.rsc +6 -6
  284. package/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/_full.segment.rsc +6 -6
  285. package/app/.next-cli-build/server/app/dashboard/proxy-pools.segments/_tree.segment.rsc +1 -1
  286. package/app/.next-cli-build/server/app/dashboard/pxpipe.html +1 -1
  287. package/app/.next-cli-build/server/app/dashboard/pxpipe.rsc +6 -6
  288. package/app/.next-cli-build/server/app/dashboard/pxpipe.segments/!KGRhc2hib2FyZCk/dashboard/pxpipe/__PAGE__.segment.rsc +6 -6
  289. package/app/.next-cli-build/server/app/dashboard/pxpipe.segments/_full.segment.rsc +6 -6
  290. package/app/.next-cli-build/server/app/dashboard/pxpipe.segments/_tree.segment.rsc +1 -1
  291. package/app/.next-cli-build/server/app/dashboard/quota.html +2 -2
  292. package/app/.next-cli-build/server/app/dashboard/quota.rsc +7 -7
  293. package/app/.next-cli-build/server/app/dashboard/quota.segments/!KGRhc2hib2FyZCk/dashboard/quota/__PAGE__.segment.rsc +7 -7
  294. package/app/.next-cli-build/server/app/dashboard/quota.segments/_full.segment.rsc +7 -7
  295. package/app/.next-cli-build/server/app/dashboard/quota.segments/_tree.segment.rsc +1 -1
  296. package/app/.next-cli-build/server/app/dashboard/settings/pricing/page.js.nft.json +1 -1
  297. package/app/.next-cli-build/server/app/dashboard/settings/pricing/page_client-reference-manifest.js +1 -1
  298. package/app/.next-cli-build/server/app/dashboard/settings/pricing.html +1 -1
  299. package/app/.next-cli-build/server/app/dashboard/settings/pricing.rsc +4 -4
  300. package/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/_full.segment.rsc +4 -4
  301. package/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/_tree.segment.rsc +1 -1
  302. package/app/.next-cli-build/server/app/dashboard/settings/pricing.segments/dashboard/settings/pricing/__PAGE__.segment.rsc +4 -4
  303. package/app/.next-cli-build/server/app/dashboard/skills.html +1 -1
  304. package/app/.next-cli-build/server/app/dashboard/skills.rsc +6 -6
  305. package/app/.next-cli-build/server/app/dashboard/skills.segments/!KGRhc2hib2FyZCk/dashboard/skills/__PAGE__.segment.rsc +6 -6
  306. package/app/.next-cli-build/server/app/dashboard/skills.segments/_full.segment.rsc +6 -6
  307. package/app/.next-cli-build/server/app/dashboard/skills.segments/_tree.segment.rsc +1 -1
  308. package/app/.next-cli-build/server/app/dashboard/token-saver.html +1 -1
  309. package/app/.next-cli-build/server/app/dashboard/token-saver.rsc +6 -6
  310. package/app/.next-cli-build/server/app/dashboard/token-saver.segments/!KGRhc2hib2FyZCk/dashboard/token-saver/__PAGE__.segment.rsc +6 -6
  311. package/app/.next-cli-build/server/app/dashboard/token-saver.segments/_full.segment.rsc +6 -6
  312. package/app/.next-cli-build/server/app/dashboard/token-saver.segments/_tree.segment.rsc +1 -1
  313. package/app/.next-cli-build/server/app/dashboard/translator.html +1 -1
  314. package/app/.next-cli-build/server/app/dashboard/translator.rsc +6 -6
  315. package/app/.next-cli-build/server/app/dashboard/translator.segments/!KGRhc2hib2FyZCk/dashboard/translator/__PAGE__.segment.rsc +6 -6
  316. package/app/.next-cli-build/server/app/dashboard/translator.segments/_full.segment.rsc +6 -6
  317. package/app/.next-cli-build/server/app/dashboard/translator.segments/_tree.segment.rsc +1 -1
  318. package/app/.next-cli-build/server/app/dashboard/usage.html +1 -1
  319. package/app/.next-cli-build/server/app/dashboard/usage.rsc +6 -6
  320. package/app/.next-cli-build/server/app/dashboard/usage.segments/!KGRhc2hib2FyZCk/dashboard/usage/__PAGE__.segment.rsc +6 -6
  321. package/app/.next-cli-build/server/app/dashboard/usage.segments/_full.segment.rsc +6 -6
  322. package/app/.next-cli-build/server/app/dashboard/usage.segments/_tree.segment.rsc +1 -1
  323. package/app/.next-cli-build/server/app/dashboard.html +1 -1
  324. package/app/.next-cli-build/server/app/dashboard.rsc +6 -6
  325. package/app/.next-cli-build/server/app/dashboard.segments/!KGRhc2hib2FyZCk/dashboard/__PAGE__.segment.rsc +6 -6
  326. package/app/.next-cli-build/server/app/dashboard.segments/_full.segment.rsc +6 -6
  327. package/app/.next-cli-build/server/app/dashboard.segments/_tree.segment.rsc +1 -1
  328. package/app/.next-cli-build/server/app/favicon.ico/route.js.nft.json +1 -1
  329. package/app/.next-cli-build/server/app/index.html +1 -1
  330. package/app/.next-cli-build/server/app/index.rsc +4 -4
  331. package/app/.next-cli-build/server/app/index.segments/__PAGE__.segment.rsc +4 -4
  332. package/app/.next-cli-build/server/app/index.segments/_full.segment.rsc +4 -4
  333. package/app/.next-cli-build/server/app/index.segments/_tree.segment.rsc +1 -1
  334. package/app/.next-cli-build/server/app/landing/page.js.nft.json +1 -1
  335. package/app/.next-cli-build/server/app/landing/page_client-reference-manifest.js +1 -1
  336. package/app/.next-cli-build/server/app/landing.html +1 -1
  337. package/app/.next-cli-build/server/app/landing.rsc +4 -4
  338. package/app/.next-cli-build/server/app/landing.segments/_full.segment.rsc +4 -4
  339. package/app/.next-cli-build/server/app/landing.segments/_tree.segment.rsc +1 -1
  340. package/app/.next-cli-build/server/app/landing.segments/landing/__PAGE__.segment.rsc +4 -4
  341. package/app/.next-cli-build/server/app/login/page.js.nft.json +1 -1
  342. package/app/.next-cli-build/server/app/login/page_client-reference-manifest.js +1 -1
  343. package/app/.next-cli-build/server/app/login.html +1 -1
  344. package/app/.next-cli-build/server/app/login.rsc +5 -5
  345. package/app/.next-cli-build/server/app/login.segments/_full.segment.rsc +5 -5
  346. package/app/.next-cli-build/server/app/login.segments/_tree.segment.rsc +1 -1
  347. package/app/.next-cli-build/server/app/login.segments/login/__PAGE__.segment.rsc +5 -5
  348. package/app/.next-cli-build/server/app/manifest.webmanifest/route.js.nft.json +1 -1
  349. package/app/.next-cli-build/server/app/page.js.nft.json +1 -1
  350. package/app/.next-cli-build/server/app/page_client-reference-manifest.js +1 -1
  351. package/app/.next-cli-build/server/app-paths-manifest.json +6 -6
  352. package/app/.next-cli-build/server/chunks/4037.js +1 -1
  353. package/app/.next-cli-build/server/chunks/6197.js +2 -2
  354. package/app/.next-cli-build/server/chunks/6922.js +1 -1
  355. package/app/.next-cli-build/server/chunks/7807.js +1 -1
  356. package/app/.next-cli-build/server/chunks/827.js +1 -1
  357. package/app/.next-cli-build/server/chunks/869.js +1 -1
  358. package/app/.next-cli-build/server/chunks/8847.js +1 -1
  359. package/app/.next-cli-build/server/chunks/8908.js +1 -1
  360. package/app/.next-cli-build/server/chunks/929.js +1 -1
  361. package/app/.next-cli-build/server/instrumentation.js.nft.json +1 -1
  362. package/app/.next-cli-build/server/middleware-build-manifest.js +1 -1
  363. package/app/.next-cli-build/server/middleware.js.nft.json +1 -1
  364. package/app/.next-cli-build/server/pages/404.html +1 -1
  365. package/app/.next-cli-build/server/pages/500.html +1 -1
  366. package/app/.next-cli-build/static/chunks/{1321-99f21e82349549e2.js → 1321-d944715e4f202568.js} +1 -1
  367. package/app/cli/.build-home/AppData/Roaming/9router/db/data.sqlite-shm +0 -0
  368. package/app/cli/.build-home/AppData/Roaming/9router/db/data.sqlite-wal +0 -0
  369. package/app/package.json +1 -1
  370. package/package.json +1 -1
  371. package/app/.next-cli-build/server/chunks/3666.js +0 -1
  372. package/app/src/sse/services/antigravityDomainBreaker.js +0 -262
  373. /package/app/.next-cli-build/static/{wMINFKWtJh3B20iNYsV48 → txTR0vPqJvVPhcaTOv3GX}/_buildManifest.js +0 -0
  374. /package/app/.next-cli-build/static/{wMINFKWtJh3B20iNYsV48 → txTR0vPqJvVPhcaTOv3GX}/_ssgManifest.js +0 -0
package/app/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "9router-app",
3
- "version": "0.5.94",
3
+ "version": "0.5.95",
4
4
  "description": "9Router web dashboard",
5
5
  "private": true,
6
6
  "scripts": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "9router-imagefix",
3
- "version": "0.5.94",
3
+ "version": "0.5.95",
4
4
  "description": "9Router CLI - Start and manage 9Router server (with image fix)",
5
5
  "bin": {
6
6
  "9router-imagefix": "./cli.js"
@@ -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
- }