opencode-navigator 0.21.0 → 0.21.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +5 -0
- package/PROVIDERS.md +1 -1
- package/README.md +9 -7
- package/dist/provider-limits.js +23 -9
- package/dist/server.js +2 -2
- package/dist/tui.js +8 -8
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
## [0.21.1] - 2026-10-06
|
|
6
|
+
|
|
7
|
+
- Fix Codex account quota windows being hidden when the provider omits model metadata. Show ordinary usage as shared account quota, retain banked-reset counts, and keep separate model buckets explicitly associated.
|
|
8
|
+
|
|
5
9
|
## [0.21.0] - 2026-10-06
|
|
6
10
|
|
|
7
11
|
- Automatically verify Codex account identity from OpenCode 2's ChatGPT connection. When host identity is unavailable, confirm a private binding once per connection or provider and reuse it across models, projects, and sessions; preserve compatible older confirmations and isolate conflicting ones until relinked.
|
|
@@ -78,6 +82,7 @@
|
|
|
78
82
|
|
|
79
83
|
Earlier release notes are available on [GitHub Releases](https://github.com/St1ggy/opencode-navigator/releases).
|
|
80
84
|
|
|
85
|
+
[0.21.1]: https://github.com/St1ggy/opencode-navigator/compare/v0.21.0...v0.21.1
|
|
81
86
|
[0.21.0]: https://github.com/St1ggy/opencode-navigator/compare/v0.20.0...v0.21.0
|
|
82
87
|
[0.20.0]: https://github.com/St1ggy/opencode-navigator/compare/v0.19.3...v0.20.0
|
|
83
88
|
[0.19.3]: https://github.com/St1ggy/opencode-navigator/compare/v0.19.2...v0.19.3
|
package/PROVIDERS.md
CHANGED
|
@@ -14,7 +14,7 @@ permissions, region, transport, and supported host APIs.
|
|
|
14
14
|
|
|
15
15
|
| Provider | Native source | Scope and prerequisites | Reference |
|
|
16
16
|
| --- | --- | --- | --- |
|
|
17
|
-
| OpenAI / Codex ChatGPT | Codex app-server account/rate-limit RPC and manual reset credits | Verified account identity;
|
|
17
|
+
| OpenAI / Codex ChatGPT | Codex app-server account/rate-limit RPC and manual reset credits | Verified account identity; ordinary `codex` quota explicitly labelled account-scoped even with null model metadata; separate model buckets need explicit association | [Codex protocol](https://github.com/openai/codex/tree/main/codex-rs/app-server-protocol) |
|
|
18
18
|
| OpenAI API | HTTP request/token/project-token rate-limit headers | Actual response for the selected model/account; HTTP transport | [Rate limits](https://developers.openai.com/api/docs/guides/rate-limits) |
|
|
19
19
|
| Anthropic API | Native response headers and organization rate-limits API | Per-model headers; configured limits need an eligible org/admin credential and explicit model association | [Rate limits API](https://platform.claude.com/docs/en/manage-claude/rate-limits-api) |
|
|
20
20
|
| Azure OpenAI | Native remaining request/token headers | Actual deployment response; does not expose a ChatGPT subscription | [Quotas and limits](https://learn.microsoft.com/en-us/azure/ai-foundry/openai/quotas-limits) |
|
package/README.md
CHANGED
|
@@ -364,9 +364,11 @@ times, account identity, and any available banked reset credits. The installed
|
|
|
364
364
|
Codex 0.160.0 protocol also exposes the separate
|
|
365
365
|
`account/rateLimitResetCredit/consume` RPC. Navigator requires explicit
|
|
366
366
|
confirmation before using it and never redeems credits in the background.
|
|
367
|
-
Limits follows the model selected in the current OpenCode
|
|
368
|
-
|
|
369
|
-
|
|
367
|
+
Limits follows the model and verified connection selected in the current OpenCode
|
|
368
|
+
session. Codex's ordinary `codex` windows appear as **Codex account** quota, shared
|
|
369
|
+
across models. The protocol can return `normalModelSlug: null` for this ordinary
|
|
370
|
+
bucket; that field is display metadata for quota aliases, not a prerequisite for
|
|
371
|
+
account usage. Separate model-specific buckets require explicit model association.
|
|
370
372
|
Switching provider, model, session, or account invalidates stale reads and credit actions.
|
|
371
373
|
CodexBar is useful for discovering providers, but its cookie, credential-file,
|
|
372
374
|
and undocumented endpoint integrations are not Navigator data sources.
|
|
@@ -402,7 +404,7 @@ worktree scope. Hiding or collapsing it does not stop background refreshes, and
|
|
|
402
404
|
does not grant permission to spend a reset credit. **Focus Limits** is also
|
|
403
405
|
available from the command palette.
|
|
404
406
|
|
|
405
|
-

|
|
406
408
|
|
|
407
409
|

|
|
408
410
|
|
|
@@ -426,8 +428,8 @@ and sessions. **Unlink Codex account** removes the manual association; **Relink
|
|
|
426
428
|
Codex account** is available after an account change. Compatible older model
|
|
427
429
|
bindings are reused; conflicting bindings remain isolated until a deliberate relink.
|
|
428
430
|
|
|
429
|
-
For an associated
|
|
430
|
-
|
|
431
|
+
For an associated connection, Limits shows the ordinary Codex account quota and
|
|
432
|
+
any explicitly associated model buckets, their native units and durations, reset times, and
|
|
431
433
|
the last successful read time. It refreshes quietly every five seconds, even
|
|
432
434
|
when hidden. **Refresh** requests a read immediately; a failed read preserves
|
|
433
435
|
cached windows with a stale label and **Retry**. Unsupported mappings, changed
|
|
@@ -440,7 +442,7 @@ details, statuses, and expiry. Selecting a credit first checks fresh eligibility
|
|
|
440
442
|
and opens a separate confirmation tied to the current account and model. Cancel
|
|
441
443
|
or Escape returns to the credit list without spending anything.
|
|
442
444
|
|
|
443
|
-
The provider must report ordinary usage blocked,
|
|
445
|
+
The provider must report ordinary usage blocked, an applicable account or model window, and an
|
|
444
446
|
available reset credit. A displayed percentage alone does not establish
|
|
445
447
|
eligibility. A reset can affect other eligible Codex windows as well. Navigator
|
|
446
448
|
checks the account and eligibility again before submission. Read-only providers
|
package/dist/provider-limits.js
CHANGED
|
@@ -117,7 +117,7 @@ child?.kill()
|
|
|
117
117
|
}}}
|
|
118
118
|
function normalizeProviderQuota(snapshot){if(!snapshot.providerId||!snapshot.providerName||!snapshot.model.providerID||!snapshot.model.modelID||!snapshot.model.sessionID||!Number.isFinite(snapshot.fetchedAt)){throw new Error("Invalid provider quota identity")
|
|
119
119
|
}
|
|
120
|
-
const windows=snapshot.windows.map((window)=>{if(!window.id||!window.label||window.modelID!==snapshot.model.modelID||!window.unit||window.used!==undefined&&!Number.isFinite(window.used)||window.remaining!==undefined&&!Number.isFinite(window.remaining)||window.used===undefined&&window.remaining===undefined&&window.total===undefined||window.total!==undefined&&(!Number.isFinite(window.total)||window.total<0)||window.durationMinutes!==undefined&&(!Number.isFinite(window.durationMinutes)||window.durationMinutes<0)||window.resetsAt!==undefined&&!Number.isFinite(window.resetsAt)){throw new Error("Quota window does not match the selected model or contains invalid values")
|
|
120
|
+
const windows=snapshot.windows.map((window)=>{if(!window.id||!window.label||window.scope!==undefined&&window.scope!=="account"&&window.scope!=="model"||(window.scope==="account"?!snapshot.accountId||window.modelID!==undefined:window.modelID!==snapshot.model.modelID)||!window.unit||window.used!==undefined&&!Number.isFinite(window.used)||window.remaining!==undefined&&!Number.isFinite(window.remaining)||window.used===undefined&&window.remaining===undefined&&window.total===undefined||window.total!==undefined&&(!Number.isFinite(window.total)||window.total<0)||window.durationMinutes!==undefined&&(!Number.isFinite(window.durationMinutes)||window.durationMinutes<0)||window.resetsAt!==undefined&&!Number.isFinite(window.resetsAt)){throw new Error("Quota window does not match the selected model or contains invalid values")
|
|
121
121
|
}
|
|
122
122
|
return{...window}})
|
|
123
123
|
const bankedResets=snapshot.bankedResets
|
|
@@ -239,8 +239,23 @@ requests.abortAll()
|
|
|
239
239
|
for(const adapter of adapters)
|
|
240
240
|
adapter.dispose?.()
|
|
241
241
|
}}}
|
|
242
|
-
function
|
|
243
|
-
|
|
242
|
+
function codexQuotaWindows(usage,modelID){const buckets=new Map
|
|
243
|
+
const legacy=usage.rateLimits
|
|
244
|
+
if(legacy.limitId==="codex"||!legacy.limitId&&!legacy.normalModelSlug)
|
|
245
|
+
buckets.set("codex",legacy)
|
|
246
|
+
const entries=Object.entries(usage.rateLimitsByLimitId??{})
|
|
247
|
+
for(const [key,limit] of entries)
|
|
248
|
+
buckets.set(limit.limitId??key,limit)
|
|
249
|
+
if(legacy.limitId&&!buckets.has(legacy.limitId))
|
|
250
|
+
buckets.set(legacy.limitId,legacy)
|
|
251
|
+
return [...buckets].flatMap(([id,limit])=>{const account=id==="codex"
|
|
252
|
+
if(!account&&limit.normalModelSlug!==modelID)
|
|
253
|
+
return []
|
|
254
|
+
return ["primary","secondary"].flatMap((name)=>{const value=limit[name]
|
|
255
|
+
if(!value)
|
|
256
|
+
return []
|
|
257
|
+
return [{id:`${id}.${name}`,label:account?`Codex account \xB7 ${name}`:`${limit.limitName ?? id} \xB7 ${name}`,limitID:id,...account?{scope:"account"}:{modelID},unit:"%",used:value.usedPercent,...value.windowDurationMins!==null&&{durationMinutes:value.windowDurationMins},...value.resetsAt!==null&&{resetsAt:value.resetsAt}}]
|
|
258
|
+
})
|
|
244
259
|
})
|
|
245
260
|
}
|
|
246
261
|
function createCodexQuotaAdapter(client,validateHost){const adapter={id:"codex",name:"Codex CLI",supports:(model)=>(model.providerID==="openai"||model.hostConnection?.providerID==="openai")&&model.hostConnection?.method!=="api"&&Boolean(model.accountID)&&(!model.hostConnection||model.hostConnection.status==="ready"),...validateHost&&{validateHost},async discoverAccount(signal){const account=await client.request("account/read",{refreshToken:false},signal)
|
|
@@ -260,12 +275,11 @@ return{...base,availability:"unauthenticated"}
|
|
|
260
275
|
const usage=await client.request("account/rateLimits/read",{supportsLunaReserve:false,excludeResetCreditDetails:false},signal)
|
|
261
276
|
if(!usage.accountId||usage.accountId!==model.accountID)
|
|
262
277
|
return{...base,availability:"unauthenticated"}
|
|
263
|
-
const
|
|
264
|
-
const matched=(candidates.length>0?candidates:[usage.rateLimits]).filter((limit)=>limit.normalModelSlug===model.modelID)
|
|
265
|
-
if(matched.length===0)
|
|
266
|
-
return{...base,accountId:usage.accountId,availability:"unsupported"}
|
|
278
|
+
const windows=codexQuotaWindows(usage,model.modelID)
|
|
267
279
|
const creditSummary=usage.rateLimitResetCredits
|
|
268
|
-
return normalizeProviderQuota({...base,accountId:usage.accountId,availability:"ready",ordinaryUsageAllowed:usage.ordinaryUsageAllowed??undefined,windows
|
|
280
|
+
return normalizeProviderQuota({...base,accountId:usage.accountId,availability:windows.length>0?"ready":"unavailable",ordinaryUsageAllowed:usage.ordinaryUsageAllowed??undefined,windows,...windows.some((window)=>window.scope==="account")&&{message:"Codex account quota; shared across models, not a model-specific allowance."
|
|
281
|
+
},...windows.length===0&&{message:"Codex reported no applicable usage windows for this account and model."
|
|
282
|
+
},...creditSummary&&{bankedResets:{availableCount:creditSummary.availableCount,...creditSummary.credits&&{credits:creditSummary.credits.map((credit)=>({id:credit.id,type:credit.resetType,status:credit.status,grantedAt:credit.grantedAt,...credit.expiresAt!==null&&{expiresAt:credit.expiresAt},...credit.title&&{title:credit.title},...credit.description&&{description:credit.description}}))
|
|
269
283
|
}}}})
|
|
270
284
|
},async prepareResetCreditConsumption(model,creditID,signal){const snapshot=await adapter.read(model,signal)
|
|
271
285
|
if(snapshot.availability==="unauthenticated"||!snapshot.accountId||snapshot.accountId!==model.accountID){throw new Error("Codex account is unavailable or changed")
|
|
@@ -521,7 +535,7 @@ return _el$
|
|
|
521
535
|
import {createComponent as _$createComponent5} from "@opentui/solid"
|
|
522
536
|
import {createSignal as createSignal4,onMount} from "solid-js"
|
|
523
537
|
import {SelectionMenu as SelectionMenu2,useDialogs as useDialogs2} from "./tui.js"
|
|
524
|
-
var rows=[["openai","OpenAI / Codex",["subscription","api-rate-limits"],"Codex account
|
|
538
|
+
var rows=[["openai","OpenAI / Codex",["subscription","api-rate-limits"],"Verified Codex account quota shared across models; HTTP response request/token limits for API connections.","https://developers.openai.com/api/docs/guides/rate-limits"],["anthropic","Anthropic / Claude",["api-rate-limits","configured-limits"],"Model HTTP headers; eligible organization/admin credentials can read configured model limits. Claude subscription windows are separate.","https://platform.claude.com/docs/en/manage-claude/rate-limits-api"],["openrouter","OpenRouter",["key-budget","account-balance"],"Inference-key budget; account credits require a management key. Free-model request limits apply only to free variants.","https://openrouter.ai/docs/api/api-reference/api-keys/get-current-api-key"],["deepseek","DeepSeek",["account-balance"],"Provider-reported USD/CNY available, granted and topped-up balances.","https://api-docs.deepseek.com/api/get-user-balance"],["moonshotai","Moonshot / Kimi API",["account-balance"],"International USD balances; coding subscriptions are a different product.","https://platform.moonshot.ai/docs/api/balance"],["moonshotai-cn","Moonshot / Kimi API China",["account-balance"],"China CNY balances; never reuse an international key against the China endpoint.","https://platform.moonshot.cn/docs/api/balance"],["minimax","MiniMax",["subscription","account-balance"],"Token Plan model rows/explicit percentages; official SDK balance response for pay-as-you-go keys.","https://platform.minimax.io/docs/token-plan/faq"],["minimax-cn","MiniMax China",["subscription","account-balance"],"Region-specific native Token Plan and SDK balance endpoints.","https://github.com/MiniMax-AI/cli/tree/main/src/sdk/quota"],["github-copilot","GitHub Copilot",["subscription"],"Official SDK token-scoped quota/model RPC; no direct copilot_internal calls or ambient CLI login.","https://github.com/github/copilot-sdk/blob/main/docs/features/usage-and-billing.md"],["groq","Groq",["api-rate-limits"],"Native model response headers: requests per day and tokens per minute.","https://console.groq.com/docs/rate-limits"],["fireworks-ai","Fireworks",["configured-limits","api-rate-limits"],"Native model token/second capacities and account monthly spend quota; GPU quotas are excluded.","https://docs.fireworks.ai/serverless/rate-limits"],["siliconflow","SiliconFlow",["account-balance"],"Native current-user balances; retain unknown currency when the API does not report it.","https://docs.siliconflow.com/en/api-reference/userinfo/get-user-info"],["siliconflow-cn","SiliconFlow China",["account-balance"],"Region-specific current-user balances; currency is unknown when the API omits it.","https://docs.siliconflow.cn/"],["novita-ai","Novita",["account-balance"],"Native current-user balances in 1/10000 USD.","https://novita.ai/docs/api-reference/basic-get-user-balance"],["poe","Poe",["account-balance"],"API account point balance; includes plan and add-on points, not session token usage.","https://creator.poe.com/docs/resources/usage-api"],["nano-gpt","NanoGPT",["account-balance","subscription"],"Native USD/Nano balance and documented subscription token windows; null/degraded counters remain unknown.","https://docs.nano-gpt.com/api-reference/endpoint/subscription-usage"],["aihubmix","AIHubMix",["account-balance"],"Current-account balance API needs a Manage Key; inference keys do not grant management access.","https://docs.aihubmix.com/en/api/CliEndpoints/get-self"],["azure","Azure OpenAI",["api-rate-limits"],"Remaining request/token headers for the actual deployment; no ChatGPT subscription or inferred cloud balance.","https://learn.microsoft.com/en-us/azure/ai-foundry/openai/quotas-limits"],["cerebras","Cerebras",["api-rate-limits"],"Only self-describing native counters actually returned for the selected model; console tier examples are not live quota.","https://inference-docs.cerebras.ai/support/rate-limits"],["mistral","Mistral",[],"Documented remaining header lacks a verified unit/window association; no inferred subscription balance.","https://docs.mistral.ai/resources/known-limitations"],["togetherai","Together AI",[],"Dynamic model limits expose retry intervals, not remaining quota; billing UI does not establish a remaining-credit API.","https://docs.together.ai/docs/rate-limits"],["xai","xAI / Grok",[],"Management billing needs separate team credentials; no verified portable remaining API for this inference connection.","https://docs.x.ai/"],["perplexity","Perplexity",[],"No verified remaining-credit API for an inference key. API credits, consumer subscriptions and Computer credits are distinct.","https://www.perplexity.ai/help-center/en/articles/10354847-api-payment-and-billing"],["google","Google Gemini",["configured-limits"],"Native model-matched QuotaFailure responses when provided; cloud quota permissions differ from an inference key.","https://ai.google.dev/gemini-api/docs/rate-limits"],["google-vertex","Google Vertex AI",["configured-limits"],"Native model-matched quota error details; cloud project/region management and dynamic shared quotas are separate.","https://cloud.google.com/vertex-ai/generative-ai/docs/quotas"],["amazon-bedrock","Amazon Bedrock",[],"Service Quotas/CloudWatch require cloud IAM/region/model mapping not exposed by a portable inference connection.","https://docs.aws.amazon.com/bedrock/latest/userguide/quotas.html"],["cloudflare-workers-ai","Cloudflare Workers AI",[],"Account analytics do not prove remaining free allowance; separate account management capability is required.","https://developers.cloudflare.com/workers-ai/platform/limits/"],["huggingface","Hugging Face Inference Providers",[],"Hub request quota is not an inference-model quota or inference-credit balance.","https://huggingface.co/docs/inference-providers/pricing"],["zai","Z.ai / GLM Coding Plan",[],"No verified external quota contract for monitor/dashboard APIs; private endpoints are excluded.","https://docs.z.ai/devpack/overview"],["kimi-for-coding","Kimi Code subscription",[],"Keep separate from Moonshot API balance; an external subscription usage contract/model mapping must be verified.","https://www.kimi.com/code/docs/en/"],["alibaba","Alibaba Cloud / Qwen / DashScope",[],"Cloud account/project billing permissions and model mapping are required; browser OAuth state is not a quota source.","https://www.alibabacloud.com/help/en/model-studio/"],["opencode","OpenCode Zen / Go",[],"Session token/cost statistics are not provider quota; no undocumented billing endpoints.","https://opencode.ai/docs/zen/"],["cursor","Cursor",[],"Consumer usage needs a supported external API; no cookie or credential-file integrations.","https://docs.cursor.com/"],["windsurf","Windsurf / Codeium",[],"Consumer plan windows need a supported external API; no private account endpoints.","https://docs.windsurf.com/"],["amp","Amp",[],"Product credits need a supported external account API; no cookie or local credential extraction.","https://ampcode.com/manual"],["ollama","Ollama",[],"Local inference has no provider subscription window; cloud products require their own account API.","https://docs.ollama.com/api"],["lmstudio","LM Studio",[],"Local inference has no provider subscription quota to read.","https://lmstudio.ai/docs/developer"],["nvidia","NVIDIA NIM / NGC",[],"Inference access does not identify cloud/trial NGC credit balance or self-hosted resource quota.","https://docs.nvidia.com/nim/"],["cohere","Cohere",[],"No verified native remaining-counter contract for this integration; static organization tier examples are not live quotas.","https://docs.cohere.com/docs/rate-limits"],["ai21","AI21",[],"No verified native remaining-counter contract or subscription balance endpoint for this integration.","https://docs.ai21.com/"],["replicate","Replicate",[],"Prediction cost is not remaining account credit; no inferred balance from execution cost.","https://replicate.com/docs/topics/billing"],["chutes","Chutes",[],"Current-user quota APIs exist, but their public schemas do not establish native units/model allowance semantics yet.","https://chutes.ai/docs/api-reference/users"],["requesty","Requesty",[],"Enterprise management key and key ID are required; dated usage reports alone are not remaining budget.","https://docs.requesty.ai/features/key-management-api"],["baseten","Baseten",[],"No independently verified portable remaining quota API for the configured inference connection.","https://docs.baseten.co/"],["modelscope","ModelScope",[],"No independently verified portable remaining quota API/model mapping for the selected connection.","https://opencode.ai/docs/providers/"],["nebius","Nebius",[],"Cloud billing/management access is separate from a plain inference credential.","https://docs.nebius.com/"],["vultr","Vultr",[],"Cloud management quota/billing permissions are separate from inference access.","https://docs.vultr.com/"],["v0","Vercel v0",[],"Consumer/product credits need their own documented external account API.","https://v0.dev/docs"]]
|
|
525
539
|
var PROVIDER_QUOTA_CAPABILITIES= rows.map(([id,name,sources,reason,url])=>({id,name,sources,reason,documentation:[url]}))
|
|
526
540
|
var aliases={fireworks:"fireworks-ai",novita:"novita-ai",moonshot:"moonshotai","minimax-coding-plan":"minimax","minimax-coding-plan-cn":"minimax-cn",together:"togetherai","silicon-flow":"siliconflow","github-copilot-enterprise":"github-copilot","google-vertex-anthropic":"google-vertex","z-ai":"zai",zhipuai:"zai",dashscope:"alibaba","alibaba-cn":"alibaba",qwen:"alibaba","opencode-go":"opencode","opencode-zen":"opencode",codeium:"windsurf","azure-cognitive-services":"azure"
|
|
527
541
|
}
|
package/dist/server.js
CHANGED
|
@@ -50,7 +50,7 @@ var NavigatorQuotaRpc={id:"opencode-navigator.quotas",methods:{read:{input:model
|
|
|
50
50
|
}}}};
|
|
51
51
|
function normalizeProviderQuota(snapshot){if(!snapshot.providerId||!snapshot.providerName||!snapshot.model.providerID||!snapshot.model.modelID||!snapshot.model.sessionID||!Number.isFinite(snapshot.fetchedAt)){throw new Error("Invalid provider quota identity")
|
|
52
52
|
}
|
|
53
|
-
const windows=snapshot.windows.map((window)=>{if(!window.id||!window.label||window.modelID!==snapshot.model.modelID||!window.unit||window.used!==undefined&&!Number.isFinite(window.used)||window.remaining!==undefined&&!Number.isFinite(window.remaining)||window.used===undefined&&window.remaining===undefined&&window.total===undefined||window.total!==undefined&&(!Number.isFinite(window.total)||window.total<0)||window.durationMinutes!==undefined&&(!Number.isFinite(window.durationMinutes)||window.durationMinutes<0)||window.resetsAt!==undefined&&!Number.isFinite(window.resetsAt)){throw new Error("Quota window does not match the selected model or contains invalid values")
|
|
53
|
+
const windows=snapshot.windows.map((window)=>{if(!window.id||!window.label||window.scope!==undefined&&window.scope!=="account"&&window.scope!=="model"||(window.scope==="account"?!snapshot.accountId||window.modelID!==undefined:window.modelID!==snapshot.model.modelID)||!window.unit||window.used!==undefined&&!Number.isFinite(window.used)||window.remaining!==undefined&&!Number.isFinite(window.remaining)||window.used===undefined&&window.remaining===undefined&&window.total===undefined||window.total!==undefined&&(!Number.isFinite(window.total)||window.total<0)||window.durationMinutes!==undefined&&(!Number.isFinite(window.durationMinutes)||window.durationMinutes<0)||window.resetsAt!==undefined&&!Number.isFinite(window.resetsAt)){throw new Error("Quota window does not match the selected model or contains invalid values")
|
|
54
54
|
}
|
|
55
55
|
return{...window}})
|
|
56
56
|
const bankedResets=snapshot.bankedResets
|
|
@@ -60,7 +60,7 @@ return{...balance}})
|
|
|
60
60
|
if(bankedResets&&(!Number.isSafeInteger(bankedResets.availableCount)||bankedResets.availableCount<0)){throw new Error("Invalid banked reset count")
|
|
61
61
|
}
|
|
62
62
|
return{...snapshot,windows,...balances&&{balances},...bankedResets&&{bankedResets:{availableCount:bankedResets.availableCount,...bankedResets.credits&&{credits:[...bankedResets.credits]}}}}}
|
|
63
|
-
var rows=[["openai","OpenAI / Codex",["subscription","api-rate-limits"],"Codex account
|
|
63
|
+
var rows=[["openai","OpenAI / Codex",["subscription","api-rate-limits"],"Verified Codex account quota shared across models; HTTP response request/token limits for API connections.","https://developers.openai.com/api/docs/guides/rate-limits"],["anthropic","Anthropic / Claude",["api-rate-limits","configured-limits"],"Model HTTP headers; eligible organization/admin credentials can read configured model limits. Claude subscription windows are separate.","https://platform.claude.com/docs/en/manage-claude/rate-limits-api"],["openrouter","OpenRouter",["key-budget","account-balance"],"Inference-key budget; account credits require a management key. Free-model request limits apply only to free variants.","https://openrouter.ai/docs/api/api-reference/api-keys/get-current-api-key"],["deepseek","DeepSeek",["account-balance"],"Provider-reported USD/CNY available, granted and topped-up balances.","https://api-docs.deepseek.com/api/get-user-balance"],["moonshotai","Moonshot / Kimi API",["account-balance"],"International USD balances; coding subscriptions are a different product.","https://platform.moonshot.ai/docs/api/balance"],["moonshotai-cn","Moonshot / Kimi API China",["account-balance"],"China CNY balances; never reuse an international key against the China endpoint.","https://platform.moonshot.cn/docs/api/balance"],["minimax","MiniMax",["subscription","account-balance"],"Token Plan model rows/explicit percentages; official SDK balance response for pay-as-you-go keys.","https://platform.minimax.io/docs/token-plan/faq"],["minimax-cn","MiniMax China",["subscription","account-balance"],"Region-specific native Token Plan and SDK balance endpoints.","https://github.com/MiniMax-AI/cli/tree/main/src/sdk/quota"],["github-copilot","GitHub Copilot",["subscription"],"Official SDK token-scoped quota/model RPC; no direct copilot_internal calls or ambient CLI login.","https://github.com/github/copilot-sdk/blob/main/docs/features/usage-and-billing.md"],["groq","Groq",["api-rate-limits"],"Native model response headers: requests per day and tokens per minute.","https://console.groq.com/docs/rate-limits"],["fireworks-ai","Fireworks",["configured-limits","api-rate-limits"],"Native model token/second capacities and account monthly spend quota; GPU quotas are excluded.","https://docs.fireworks.ai/serverless/rate-limits"],["siliconflow","SiliconFlow",["account-balance"],"Native current-user balances; retain unknown currency when the API does not report it.","https://docs.siliconflow.com/en/api-reference/userinfo/get-user-info"],["siliconflow-cn","SiliconFlow China",["account-balance"],"Region-specific current-user balances; currency is unknown when the API omits it.","https://docs.siliconflow.cn/"],["novita-ai","Novita",["account-balance"],"Native current-user balances in 1/10000 USD.","https://novita.ai/docs/api-reference/basic-get-user-balance"],["poe","Poe",["account-balance"],"API account point balance; includes plan and add-on points, not session token usage.","https://creator.poe.com/docs/resources/usage-api"],["nano-gpt","NanoGPT",["account-balance","subscription"],"Native USD/Nano balance and documented subscription token windows; null/degraded counters remain unknown.","https://docs.nano-gpt.com/api-reference/endpoint/subscription-usage"],["aihubmix","AIHubMix",["account-balance"],"Current-account balance API needs a Manage Key; inference keys do not grant management access.","https://docs.aihubmix.com/en/api/CliEndpoints/get-self"],["azure","Azure OpenAI",["api-rate-limits"],"Remaining request/token headers for the actual deployment; no ChatGPT subscription or inferred cloud balance.","https://learn.microsoft.com/en-us/azure/ai-foundry/openai/quotas-limits"],["cerebras","Cerebras",["api-rate-limits"],"Only self-describing native counters actually returned for the selected model; console tier examples are not live quota.","https://inference-docs.cerebras.ai/support/rate-limits"],["mistral","Mistral",[],"Documented remaining header lacks a verified unit/window association; no inferred subscription balance.","https://docs.mistral.ai/resources/known-limitations"],["togetherai","Together AI",[],"Dynamic model limits expose retry intervals, not remaining quota; billing UI does not establish a remaining-credit API.","https://docs.together.ai/docs/rate-limits"],["xai","xAI / Grok",[],"Management billing needs separate team credentials; no verified portable remaining API for this inference connection.","https://docs.x.ai/"],["perplexity","Perplexity",[],"No verified remaining-credit API for an inference key. API credits, consumer subscriptions and Computer credits are distinct.","https://www.perplexity.ai/help-center/en/articles/10354847-api-payment-and-billing"],["google","Google Gemini",["configured-limits"],"Native model-matched QuotaFailure responses when provided; cloud quota permissions differ from an inference key.","https://ai.google.dev/gemini-api/docs/rate-limits"],["google-vertex","Google Vertex AI",["configured-limits"],"Native model-matched quota error details; cloud project/region management and dynamic shared quotas are separate.","https://cloud.google.com/vertex-ai/generative-ai/docs/quotas"],["amazon-bedrock","Amazon Bedrock",[],"Service Quotas/CloudWatch require cloud IAM/region/model mapping not exposed by a portable inference connection.","https://docs.aws.amazon.com/bedrock/latest/userguide/quotas.html"],["cloudflare-workers-ai","Cloudflare Workers AI",[],"Account analytics do not prove remaining free allowance; separate account management capability is required.","https://developers.cloudflare.com/workers-ai/platform/limits/"],["huggingface","Hugging Face Inference Providers",[],"Hub request quota is not an inference-model quota or inference-credit balance.","https://huggingface.co/docs/inference-providers/pricing"],["zai","Z.ai / GLM Coding Plan",[],"No verified external quota contract for monitor/dashboard APIs; private endpoints are excluded.","https://docs.z.ai/devpack/overview"],["kimi-for-coding","Kimi Code subscription",[],"Keep separate from Moonshot API balance; an external subscription usage contract/model mapping must be verified.","https://www.kimi.com/code/docs/en/"],["alibaba","Alibaba Cloud / Qwen / DashScope",[],"Cloud account/project billing permissions and model mapping are required; browser OAuth state is not a quota source.","https://www.alibabacloud.com/help/en/model-studio/"],["opencode","OpenCode Zen / Go",[],"Session token/cost statistics are not provider quota; no undocumented billing endpoints.","https://opencode.ai/docs/zen/"],["cursor","Cursor",[],"Consumer usage needs a supported external API; no cookie or credential-file integrations.","https://docs.cursor.com/"],["windsurf","Windsurf / Codeium",[],"Consumer plan windows need a supported external API; no private account endpoints.","https://docs.windsurf.com/"],["amp","Amp",[],"Product credits need a supported external account API; no cookie or local credential extraction.","https://ampcode.com/manual"],["ollama","Ollama",[],"Local inference has no provider subscription window; cloud products require their own account API.","https://docs.ollama.com/api"],["lmstudio","LM Studio",[],"Local inference has no provider subscription quota to read.","https://lmstudio.ai/docs/developer"],["nvidia","NVIDIA NIM / NGC",[],"Inference access does not identify cloud/trial NGC credit balance or self-hosted resource quota.","https://docs.nvidia.com/nim/"],["cohere","Cohere",[],"No verified native remaining-counter contract for this integration; static organization tier examples are not live quotas.","https://docs.cohere.com/docs/rate-limits"],["ai21","AI21",[],"No verified native remaining-counter contract or subscription balance endpoint for this integration.","https://docs.ai21.com/"],["replicate","Replicate",[],"Prediction cost is not remaining account credit; no inferred balance from execution cost.","https://replicate.com/docs/topics/billing"],["chutes","Chutes",[],"Current-user quota APIs exist, but their public schemas do not establish native units/model allowance semantics yet.","https://chutes.ai/docs/api-reference/users"],["requesty","Requesty",[],"Enterprise management key and key ID are required; dated usage reports alone are not remaining budget.","https://docs.requesty.ai/features/key-management-api"],["baseten","Baseten",[],"No independently verified portable remaining quota API for the configured inference connection.","https://docs.baseten.co/"],["modelscope","ModelScope",[],"No independently verified portable remaining quota API/model mapping for the selected connection.","https://opencode.ai/docs/providers/"],["nebius","Nebius",[],"Cloud billing/management access is separate from a plain inference credential.","https://docs.nebius.com/"],["vultr","Vultr",[],"Cloud management quota/billing permissions are separate from inference access.","https://docs.vultr.com/"],["v0","Vercel v0",[],"Consumer/product credits need their own documented external account API.","https://v0.dev/docs"]]
|
|
64
64
|
var PROVIDER_QUOTA_CAPABILITIES= rows.map(([id,name,sources,reason,url])=>({id,name,sources,reason,documentation:[url]}))
|
|
65
65
|
var aliases={fireworks:"fireworks-ai",novita:"novita-ai",moonshot:"moonshotai","minimax-coding-plan":"minimax","minimax-coding-plan-cn":"minimax-cn",together:"togetherai","silicon-flow":"siliconflow","github-copilot-enterprise":"github-copilot","google-vertex-anthropic":"google-vertex","z-ai":"zai",zhipuai:"zai",dashscope:"alibaba","alibaba-cn":"alibaba",qwen:"alibaba","opencode-go":"opencode","opencode-zen":"opencode",codeium:"windsurf","azure-cognitive-services":"azure"
|
|
66
66
|
}
|
package/dist/tui.js
CHANGED
|
@@ -7565,7 +7565,7 @@ const limitsPath=import.meta.url.includes("/dist/tui.js")?"./provider-limits.js"
|
|
|
7565
7565
|
const limitsModule=await import(limitsPath)
|
|
7566
7566
|
const LimitsSection=limitsModule.ProviderLimitsSection
|
|
7567
7567
|
const{controller:limits,codex,accountSource,selectModel,capabilities
|
|
7568
|
-
}=limitsModule.createProviderQuotaIntegration(api,preferences,"0.21.
|
|
7568
|
+
}=limitsModule.createProviderQuotaIntegration(api,preferences,"0.21.1",hostContext)
|
|
7569
7569
|
const mcp=createMcpController(api,preferences.persistMcp,preferences)
|
|
7570
7570
|
const interaction=createSidebarInteraction(api,()=>openKeyboardHelp(api,preferences.lspIconStyle,preferences.cornerFont))
|
|
7571
7571
|
const startup=createStartupSessionController(api,preferences)
|
|
@@ -7593,7 +7593,7 @@ api.slots.register({order:100,slots:{app(){return _$createComponent(IconProvider
|
|
|
7593
7593
|
},interaction,skills,subagents,mcp
|
|
7594
7594
|
}),_$createComponent(FirstRunWizardPersistence,{api,preferences
|
|
7595
7595
|
}),_$createComponent(StartupSessionBinding,{api,controller:startup
|
|
7596
|
-
}),_$createComponent(UpgradeNotesBinding,{api,preferences,version:"0.21.
|
|
7596
|
+
}),_$createComponent(UpgradeNotesBinding,{api,preferences,version:"0.21.1"
|
|
7597
7597
|
}),_$createComponent(McpPersistence,{api,controller:mcp
|
|
7598
7598
|
})]
|
|
7599
7599
|
}})
|
|
@@ -7624,12 +7624,12 @@ throw result.error
|
|
|
7624
7624
|
}
|
|
7625
7625
|
return result.data?.type==="text"?result.data.content:undefined
|
|
7626
7626
|
})
|
|
7627
|
-
const versionStatus=createVersionStatus(api,"0.21.
|
|
7628
|
-
const versionUpdates=createVersionUpdateActions(api,versionStatus,createOpenCodeV1VersionUpdater(api,meta),()=>preferences.rememberNavigatorVersionBeforeUpdate("0.21.
|
|
7627
|
+
const versionStatus=createVersionStatus(api,"0.21.1")
|
|
7628
|
+
const versionUpdates=createVersionUpdateActions(api,versionStatus,createOpenCodeV1VersionUpdater(api,meta),()=>preferences.rememberNavigatorVersionBeforeUpdate("0.21.1"))
|
|
7629
7629
|
api.slots.register({order:90,slots:{sidebar_footer(_context,props){return _$createComponent(IconProvider,{get style(){return preferences.lspIconStyle
|
|
7630
7630
|
},get multilineCorners(){return preferences.cornerFont
|
|
7631
7631
|
},get children(){return _$createComponent(VersionFooter,{api,get sessionID(){return props.session_id
|
|
7632
|
-
},navigatorVersion:"0.21.
|
|
7632
|
+
},navigatorVersion:"0.21.1",status:versionStatus,get onOpenCodeUpdate(){return versionUpdates.openCode
|
|
7633
7633
|
},get onNavigatorUpdate(){return versionUpdates.navigator
|
|
7634
7634
|
}})
|
|
7635
7635
|
}})
|
|
@@ -7643,15 +7643,15 @@ return
|
|
|
7643
7643
|
return new TextDecoder().decode(await context.client.file.read({location:context.location,path:".opencode/navigator.json"
|
|
7644
7644
|
}))
|
|
7645
7645
|
},todo,context)
|
|
7646
|
-
const versionStatus=createVersionStatus(adapter.api,"0.21.
|
|
7647
|
-
const versionUpdates=createVersionUpdateActions(adapter.api,versionStatus,createOpenCodeV2VersionUpdater(context),()=>preferences.rememberNavigatorVersionBeforeUpdate("0.21.
|
|
7646
|
+
const versionStatus=createVersionStatus(adapter.api,"0.21.1")
|
|
7647
|
+
const versionUpdates=createVersionUpdateActions(adapter.api,versionStatus,createOpenCodeV2VersionUpdater(context),()=>preferences.rememberNavigatorVersionBeforeUpdate("0.21.1"))
|
|
7648
7648
|
const disposeFooter=context.ui.slot({append:"sidebar.footer",render:()=>_$createComponent(IconProvider,{get style(){return preferences.lspIconStyle
|
|
7649
7649
|
},get multilineCorners(){return preferences.cornerFont
|
|
7650
7650
|
},get children(){var _el$=_$createElement("box")
|
|
7651
7651
|
_$setProp(_el$,"flexDirection","row")
|
|
7652
7652
|
_$setProp(_el$,"justifyContent","space-between")
|
|
7653
7653
|
_$insert(_el$,_$createComponent(VersionSummary,{get api(){return adapter.api
|
|
7654
|
-
},navigatorVersion:"0.21.
|
|
7654
|
+
},navigatorVersion:"0.21.1",status:versionStatus,get onOpenCodeUpdate(){return versionUpdates.openCode
|
|
7655
7655
|
},get onNavigatorUpdate(){return versionUpdates.navigator
|
|
7656
7656
|
}}),null)
|
|
7657
7657
|
_$insert(_el$,_$createComponent(SettingsFooterButton,{get api(){return adapter.api
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://json.schemastore.org/package.json",
|
|
3
3
|
"name": "opencode-navigator",
|
|
4
|
-
"version": "0.21.
|
|
4
|
+
"version": "0.21.1",
|
|
5
5
|
"description": "Search, navigate, and manage OpenCode sessions from the TUI",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"packageManager": "bun@1.4.2",
|