mirror of
https://github.com/stablyai/orca.git
synced 2026-10-01 08:01:56 +00:00
fix(rate-limits): read OpenCode Go usage with the Go API key (#22551)
* fix(rate-limits): read OpenCode Go usage with the account API key Since OpenCode's console migration (upstream fe51b0b19a, "fix(console): restrict legacy access to Black"), an account with no Black subscription is redirected from the legacy console to /console/login, so Orca's cookie-based workspace lookup returns nothing and the Go bar stays empty. Fetch usage from GET https://opencode.ai/zen/go/v1/usage instead, which authenticates with `Authorization: Bearer <key>` and needs no console session. The key resolves in order: Orca settings override, OPENCODE_API_KEY, then whatever OpenCode itself stored on /connect -- auth.json for 1.x, the credential table for 2.x. The cookie path stays as the fallback so Black/legacy accounts keep working. A 403 EntitlementError now reads as "no OpenCode Go subscription" in the status bar instead of a generic refresh failure (#22257's reporter was misled by exactly that). * fix(rate-limits): prefer OpenCode's stored Go key over OPENCODE_API_KEY OpenCode applies the key saved on /connect after the environment, so the stored key is the one its own Go requests use. OPENCODE_API_KEY is also the Zen provider's variable, so ranking it first could read a key that OpenCode itself is not using for Go. Co-Authored-By: Claude <noreply@anthropic.com> * fix(rate-limits): name the API key when OpenCode Go usage lands on sign-in A redirected usage request arrives as a 200 sign-in page because Electron follows redirects; report it as a rejected key instead of a parse failure. The cookie path's empty workspace lookup is what non-Black accounts now hit after the console migration, so its message points at the API key rather than only the workspace override. Co-Authored-By: Claude <noreply@anthropic.com> * chore(i18n): add the OpenCode Go API key strings to the English catalog Co-Authored-By: Claude <noreply@anthropic.com> * docs(rate-limits): stop calling the credential table an OpenCode 2 marker Verified on two real Windows hosts running OpenCode 1.18.16: the `credential` table exists there too (empty, same columns), so its presence does not identify a 2.x install. Neither host had an `auth.json` at all. The resolution already probes both stores on every version, so only the comments were wrong. Says so now, and records that a 2.x install which never ran the legacy import has no `auth.json` either — which is why both tiers exist. * refactor(shared): move GhosttyImportPreview out of global-settings-types Adding `opencodeGoApiKey` pushed global-settings-types.ts one line past the 300-line ceiling, failing `oxlint` in CI. AGENTS.md forbids a max-lines suppression, so split instead: the Ghostty import preview is a distinct concern that never belonged in the settings-shape file. Re-exported from the original module so no importer changes. 293 code lines now. --------- Co-authored-by: Jinwoo-H <jinwoo0825@gmail.com> Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -210,6 +210,7 @@ export function buildDefaultSettings(args: {
|
||||
defaultLinearTeamSelection: null,
|
||||
opencodeSessionCookie: '',
|
||||
opencodeWorkspaceId: '',
|
||||
opencodeGoApiKey: '',
|
||||
minimaxGroupId: '',
|
||||
minimaxUsageModels: 'general',
|
||||
minimaxEndpoint: 'overseas',
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
import type { GlobalSettings } from './global-settings-types'
|
||||
|
||||
/** What a Ghostty config import would change, shown before the user accepts it. */
|
||||
export type GhosttyImportPreview = {
|
||||
found: boolean
|
||||
configPath?: string
|
||||
configPaths?: string[]
|
||||
diff: Partial<GlobalSettings>
|
||||
unsupportedKeys: string[]
|
||||
error?: string
|
||||
}
|
||||
@@ -389,6 +389,8 @@ export type GlobalSettings = {
|
||||
opencodeSessionCookie: string
|
||||
/** Optional OpenCode Go workspace ID override; when set, skips the workspaces lookup and fetches usage directly. */
|
||||
opencodeWorkspaceId: string
|
||||
/** Optional OpenCode Go API key override. Takes precedence over OpenCode's own stored key and OPENCODE_API_KEY. Stored encrypted. */
|
||||
opencodeGoApiKey: string
|
||||
/** Optional MiniMax group id. When empty, the usage fetcher extracts minimax_group_id_v2 from the cookie. */
|
||||
minimaxGroupId: string
|
||||
/** Comma-separated MiniMax model names to show in the status bar usage window. */
|
||||
@@ -525,11 +527,6 @@ export type OrcaWorkspaceLayout = {
|
||||
nestWorkspaces: boolean
|
||||
}
|
||||
|
||||
export type GhosttyImportPreview = {
|
||||
found: boolean
|
||||
configPath?: string
|
||||
configPaths?: string[]
|
||||
diff: Partial<GlobalSettings>
|
||||
unsupportedKeys: string[]
|
||||
error?: string
|
||||
}
|
||||
// Re-exported so existing importers keep one entry point; the shape lives in its
|
||||
// own file because this one is at the max-lines ceiling.
|
||||
export type { GhosttyImportPreview } from './ghostty-import-preview'
|
||||
|
||||
@@ -13,6 +13,7 @@ export function createEmptyRateLimitState(overrides: Partial<RateLimitState> = {
|
||||
grok: null,
|
||||
minimaxCookieConfigured: false,
|
||||
minimaxApiKeyConfigured: false,
|
||||
opencodeGoApiKeyConfigured: false,
|
||||
grokAuthConfigured: false,
|
||||
claudeTarget: { runtime: 'host', wslDistro: null },
|
||||
codexTarget: { runtime: 'host', wslDistro: null },
|
||||
|
||||
@@ -18,6 +18,7 @@ describe('RateLimitState', () => {
|
||||
grok: null,
|
||||
minimaxCookieConfigured: false,
|
||||
minimaxApiKeyConfigured: false,
|
||||
opencodeGoApiKeyConfigured: false,
|
||||
grokAuthConfigured: false,
|
||||
claudeTarget: { runtime: 'host', wslDistro: null },
|
||||
codexTarget: { runtime: 'host', wslDistro: null },
|
||||
|
||||
@@ -25,6 +25,8 @@ export type UsageRateLimitFailureKind =
|
||||
| 'deferred-by-live-session'
|
||||
| 'keychain-unavailable'
|
||||
| 'missing-scope'
|
||||
/** The account is authenticated but not entitled to the product being polled. */
|
||||
| 'no-subscription'
|
||||
| 'network'
|
||||
| 'server'
|
||||
| 'parse'
|
||||
@@ -138,6 +140,13 @@ export type RateLimitState = {
|
||||
* visible across reloads.
|
||||
*/
|
||||
minimaxApiKeyConfigured: boolean
|
||||
/**
|
||||
* True when main resolved an OpenCode Go API key (Orca settings,
|
||||
* OPENCODE_API_KEY, or what OpenCode stored on /connect). The key itself
|
||||
* never leaves main; the status bar ORs this with the session cookie to
|
||||
* decide whether the OpenCode Go bar stays visible.
|
||||
*/
|
||||
opencodeGoApiKeyConfigured: boolean
|
||||
/** True when main finds a Grok CLI session file (~/.grok/auth.json or GROK_HOME). */
|
||||
grokAuthConfigured: boolean
|
||||
claudeTarget: RateLimitRuntimeTarget
|
||||
|
||||
Reference in New Issue
Block a user