@eddyskywalker/dsh-chatgpt-subscription 0.15.0 → 0.16.0

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/lib/client.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","names":["formatPercent","request","post","messageOf","formatCapacity","formatDate","formatReset","parsePositiveCapacity","zh","en","dictionaries","api","zh","zh","en","dictionaries","EFFORT_LABELS","api","zh","zh","en","dictionaries","zh","api","zh","zh","en","dictionaries","API","api","zh","EFFORT_LABELS","zh","api","request","post","zh","en","dictionaries","zh","post","zh","en","dictionaries","api","zh","zh","API","zh","en","dictionaries","zh","CSS","CSS","STYLE_ID","api","selectBadgeFacts","api","selectBadgeFacts","STYLE_ID","api","selectBadgeFacts","api","selectBadgeFacts","STYLE_ID","api","selectBadgeFacts","STYLE_ID","antigravityDicts","claudeDicts","commandCodeDicts","kimiCodeDicts","minimaxCodeDicts","workBuddyDicts","ollamaDicts"],"sources":["../src/shared/minimax-code-contracts.ts","../src/compat.ts","../src/client/common/use-store.ts","../src/client/quota.ts","../src/client/CodexComposerQuota.tsx","../src/client/CodexImageToolView.tsx","../src/shared/hub-contracts.ts","../src/client/common/account-pool-labels.ts","../src/client/hub/brand-svg.ts","../src/client/hub/brand-icons.tsx","../src/shared/model-catalog.ts","../src/client/api.ts","../src/client/common/account-quota.tsx","../src/client/common/AccountPoolSection.tsx","../src/client/common/ModelChecklist.tsx","../src/client/common/quota-follow-up.ts","../src/client/CodexSubscriptionSection.tsx","../src/client/common/format.ts","../src/client/common/ContextWindowEditor.tsx","../src/client/common/line-api.ts","../src/client/antigravity/locales.ts","../src/client/antigravity/AntigravitySection.tsx","../src/shared/command-code-contracts.ts","../src/client/command-code/locales.ts","../src/client/command-code/CommandCodeSection.tsx","../src/shared/kimi-code-contracts.ts","../src/client/kimi-code/locales.ts","../src/client/kimi-code/KimiModelCapabilities.tsx","../src/client/kimi-code/KimiCodeSection.tsx","../src/shared/workbuddy-contracts.ts","../src/client/workbuddy/locales.ts","../src/client/workbuddy/useWorkBuddySection.ts","../src/client/workbuddy/WorkBuddySection.tsx","../src/client/minimax-code/api.ts","../src/client/minimax-code/locales.ts","../src/client/minimax-code/useMinimaxCodeSection.ts","../src/client/minimax-code/MinimaxCodeSection.tsx","../src/shared/claude-contracts.ts","../src/client/claude/locales.ts","../src/client/claude/useClaudeSection.ts","../src/client/claude/ClaudeSection.tsx","../src/client/ollama/api.ts","../src/client/ollama/locales.ts","../src/client/ollama/OllamaSection.tsx","../src/client/hub/providers.tsx","../src/client/hub/HubOverview.tsx","../src/client/ProviderHubSection.tsx","../src/client/locales.ts","../src/client/common/plugin-style.ts","../src/client/styles.ts","../src/client/hub/hub-styles.ts","../src/client/common/model-checklist-styles.ts","../src/client/antigravity/styles.ts","../src/client/common/styles.ts","../src/client/common/ComposerQuotaBadge.tsx","../src/client/antigravity/AntigravityComposerQuota.tsx","../src/client/claude/ClaudeComposerQuota.tsx","../src/client/claude/styles.ts","../src/client/command-code/CommandCodeComposerQuota.tsx","../src/client/kimi-code/KimiCodeComposerQuota.tsx","../src/client/kimi-code/styles.ts","../src/client/minimax-code/MinimaxCodeComposerQuota.tsx","../src/client/minimax-code/styles.ts","../src/client/workbuddy/WorkBuddyComposerQuota.tsx","../src/client/workbuddy/styles.ts","../src/client/mermaid/sanitize.ts","../src/client/mermaid/styles.ts","../src/client/mermaid/renderer.ts","../src/client/index.tsx"],"sourcesContent":["/**\n * MiniMax Code(编程订阅)线路的共享契约。\n *\n * host 与 client 两半只依赖本文件的类型与常量,互不 import。\n * 本文件由调度者冻结:类型名与常量名不得更改,可追加。\n */\n\nimport type {\n AccountRotationStrategy,\n PoolAccountSummaryDto,\n} from './account-pool-contracts.ts'\n\nexport const MINIMAX_CODE_PROVIDER_ID = 'minimax-code'\nexport const MINIMAX_CODE_PROVIDER_NAME = 'MiniMax Code(编程订阅)'\n\n/** 区域。cn 用 account.minimax.cn / agent.minimax.cn;global 用对应 .io 域名。 */\nexport type MinimaxCodeRegion = 'cn' | 'global'\n\n/** M3.1 的思考档位;M2.7 恒定开启,M3 为开关二态。 */\nexport type MinimaxCodeReasoningEffort = 'default' | 'low' | 'medium' | 'high' | 'xhigh' | 'max'\n\n/**\n * 全线共用的思考档位,按从小到大的顺序排列。\n *\n * 设置卡片只渲染这一份列表:档位是线路级的词汇表(`isMinimaxCodeReasoningEffort`\n * 就是按它校验的),而不是单个模型的能力表。某个模型实际接受哪些档位由\n * `MinimaxCodeModelOption.reasoningEfforts` 单独给出——把两者合成一份会让卡片\n * 在给一个只认 `default` 的模型显示 `max` 时无从判断是模型不支持还是文案没写。\n */\nexport const MINIMAX_CODE_REASONING_EFFORTS: readonly MinimaxCodeReasoningEffort[] =\n ['default', 'low', 'medium', 'high', 'xhigh', 'max']\n\n/**\n * 路由前缀(host 暴露、client 消费)。\n *\n * 与其余各订阅线路一致:每条线路把自己的设置面挂在 `/<line>/api` 下\n * (antigravity / claude / command-code / kimi-code / workbuddy 都是如此),\n * 而不是挂到 Codex 那条线路的 `/api/dsh-chatgpt-subscription` 前缀下面。\n * 唯一的 `/api/dsh-chatgpt-subscription` 前缀属于 Codex 自己的路由表。\n */\nexport const MINIMAX_CODE_ROUTE_PREFIX = '/minimax-code/api'\n\nexport interface MinimaxCodeAccount {\n id: string\n label: string\n email?: string\n /** 凭据代数,每次刷新自增;用于诊断两侧刷新争用。 */\n generation: number\n expiresAtMs: number\n}\n\nexport interface MinimaxCodeCredentialStorage {\n /** minimax-native = 直接复用 MiniMax Code 的 auth.json;其余为插件自持。 */\n kind: 'minimax-native' | 'dpapi' | 'file'\n path?: string\n}\n\nexport interface MinimaxCodeWebLogin {\n loginId: string\n userCode: string\n verificationUri: string\n expiresInSec: number\n}\n\n/**\n * 一个配额窗口。\n *\n * Token Plan 同时给两个窗口:5 小时滚动窗口与每周窗口。两者都要单独呈现,\n * 因为周窗口还带一个显示倍率(服务端返回 percentage 与 boost 两个值,渲染值\n * 是两者相乘),而把两个窗口合成一个数字会让用户无法判断是哪一边快用完了。\n */\nexport interface MinimaxCodeQuotaWindow {\n /** 稳定标识,由客户端本地化成窗口名;不要在这里放展示文案。 */\n key: 'interval' | 'weekly'\n /** 剩余百分比(周窗口已乘上 boost)。服务端未给出时为 null。 */\n remainingPercent: number | null\n /** 已用百分比;由剩余百分比取反得到。 */\n usedPercent?: number\n /** 已用/总量;仅当服务端计数与其百分比自洽时才有值(见 host 侧消歧说明)。 */\n used?: number\n total?: number\n /** 该窗口重置的绝对时刻(Unix 毫秒)。 */\n resetsAtMs?: number\n /** 服务端把该窗口标为不限量。 */\n unlimited?: boolean\n}\n\nexport interface MinimaxCodeQuota {\n label: string\n usedPercent?: number\n resetsAtMs?: number\n /** 每个窗口的明细;服务端只给了一个数字时缺省。 */\n windows?: MinimaxCodeQuotaWindow[]\n /** 本快照读取时刻(Unix 毫秒),便于卡片判断数据新旧。 */\n fetchedAtMs?: number\n}\n\n/** 一条模型行的思考形态;取值与 host 目录里的 MinimaxCodeThinkingMode 一致。 */\nexport type MinimaxCodeThinkingModeDto = 'always-on' | 'toggle' | 'forced-effort'\n\n/**\n * 设置卡片渲染的一行模型。\n *\n * 硬编码目录(host 的 `MINIMAX_CODE_MODELS`)带的是「模型是什么」,这里带的是\n * 「这个安装当前怎么用它」:启用与否、生效的上下文窗口、请求缺省输出上限。\n * 两者分开是因为前者随代码发布、后者随用户设置变化;把设置混进目录会让一份\n * 用户数据看起来像一条已发布的目录项。\n */\nexport interface MinimaxCodeModelOption {\n id: string\n name: string\n /** 是否由 DSH 提供给会话模型选择器。 */\n enabled: boolean\n /** 目录声明的默认上下文窗口。 */\n defaultContextWindow: number\n /** 生效窗口:有覆盖值时用覆盖值,否则等于 `defaultContextWindow`。 */\n contextWindow: number\n /** 调用方不指定时,本线路请求的输出上限。 */\n defaultMaxTokens: number\n /** 本模型接受的思考档位;没有可选档位时缺省。 */\n reasoningEfforts?: string[]\n /** 会话未指定档位时使用的档位。 */\n defaultReasoningEffort?: string\n /** 思考形态:恒定开启 / 开关二态 / 强制带档位。 */\n thinking: MinimaxCodeThinkingModeDto\n description: string | null\n}\n\n/**\n * 每日签到偏好。\n *\n * 签到面同时覆盖 cn 与 global 两个区域(官方 CLI 的 public-gateway 对两个\n * region 各有源站),因此这里不像 workbuddy 那样只限国区:账号自己的\n * region 决定走哪个源站。没有可配置的窗口:宿主启动后的第一次 tick\n * 就是当天签到。\n */\nexport interface MinimaxCodeCheckinSettings {\n /** 是否由进程内调度器自动签到。 */\n enabled: boolean\n}\n\n/**\n * 设置卡片渲染的签到聚合。\n *\n * 有意不带账号身份:卡片只显示一行「今日已签 x/y」,不做逐账号明细。\n */\nexport interface MinimaxCodeCheckinSummary {\n enabled: boolean\n /** 参与签到的账号数(号池中当前可选的账号)。 */\n totalAccounts: number\n /** 今日已确认签到的账号数(本已签过,或由某次运行签成)。 */\n doneToday: number\n /** 今日签到面报告不可签的账号数(当日格非「可领」状态,按小时复查)。 */\n skippedToday: number\n /** 今日重试次数耗尽仍未签成的账号数。 */\n failedToday: number\n /** 调度器上次运行时刻(Unix 毫秒),自动或手动。 */\n lastRunAt: number | null\n /** 已签到账号当前连续签到天数的最大值;今天还没人签时缺省。 */\n streakDays?: number\n /** 最近一次运行实际领到的积分;本轮没人新签时缺省。 */\n claimedPoints?: number\n}\n\nexport interface MinimaxCodeWebStatus {\n /** 线路总开关;关闭时适配器不暴露任何模型。 */\n enabled: boolean\n authenticated: boolean\n providerId: typeof MINIMAX_CODE_PROVIDER_ID\n region: MinimaxCodeRegion\n storage: MinimaxCodeCredentialStorage\n account?: MinimaxCodeAccount\n login?: MinimaxCodeWebLogin\n /** 硬编码目录渲染成的模型行(远端 `/v1/models` 不可用)。 */\n models: MinimaxCodeModelOption[]\n /** 每条被覆盖的模型当前保存的上下文窗口;未被覆盖的模型不出现。 */\n contextWindowOverrides: Record<string, number>\n /** 未指定时的全局思考档位;null 表示各模型用自己的默认档位。 */\n defaultReasoningEffort: MinimaxCodeReasoningEffort | null\n /** 无可用用量快照时为 undefined,UI 应优雅降级。 */\n quota?: MinimaxCodeQuota\n /**\n * 用量快照缺失、且原因值得告诉用户时给出。\n *\n * - `credential-not-accepted`:端点应答了,但**拒绝本线路持有的凭据类型**——\n * `/v1/token_plan/remains` 只接受平台 API 密钥,MiniMax Code 的\n * `mcode-public` 登录态在四种认证写法下都被拒(`base_resp.status_code: 1004`)。\n * - `unreachable`:没有任何候选主机给出可用应答。\n * - `token-expired`:所有候选主机都以 401/403 拒绝了 bearer,且随后那一次\n * 续期也失败了。注意这**不等于**未登录:access token 一小时到期是常态,\n * 账号仍然是登录态,UI 不应据此提示重新登录。\n * - `stale`:本次读取失败,但卡片仍在渲染上一次成功解析出的数值——数值是真的,\n * 只是不再新鲜。\n */\n quotaUnavailable?: 'credential-not-accepted' | 'unreachable' | 'token-expired' | 'stale'\n /**\n * 本次应答背后是否正在刷新用量。\n *\n * 卡片先用已有快照作答、不等待上游请求;该值为 true 时客户端应当稍后\n * 再问一次,让刷新后的快照尽快上屏。\n */\n quotaRefreshing?: boolean\n /** 本插件是否正在服务该 Provider 路由;被别的适配器占用时为 false。 */\n serving: boolean\n /** 路由被别的适配器占用时的诊断文案。 */\n conflict: string | null\n /**\n * 凭据是否由本插件自己持有(即本插件设备码登录写下的那一份)。\n *\n * false 有两种情况:尚未登录,或当前登录态属于 MiniMax Code 桌面端自己\n * (`~/.minimax/auth`)。后者本插件**会**在需要时续期并原子写回(只读优先),\n * 但**不会删除**它——删掉等于把用户从正在运行的官方客户端里踢下线。因此\n * 「登出」对它无效,卡片必须据此禁用按钮并说明原因,而不是给出一个按下去\n * 没有效果的按钮。\n */\n ownedByPlugin: boolean\n /**\n * 号池里的账号,供设置卡片的「账号管理」渲染。\n *\n * 与其余各线路同构(复用同一个共享卡片与同一份 DTO):每条元素只带非机密的\n * 展示信息,令牌永远不过这条边界。桌面端自有账号在其中会被标为\n * `removable: false`——它归 MiniMax Code 所有,本插件只读与续期。\n */\n accounts?: PoolAccountSummaryDto[]\n /** 下一个请求会使用的账号。 */\n activeAccountId?: string\n /** 号池调度策略;无号池时缺省为顺序耗尽。 */\n rotationStrategy?: AccountRotationStrategy\n /** 本进程是否装载了号池。false 时卡片按单凭据模式渲染。 */\n poolInstalled?: boolean\n /** 每日签到聚合;未装载签到调度器时为 null。 */\n checkin?: MinimaxCodeCheckinSummary | null\n}\n\n","/**\n * Compatibility constants for the ChatGPT-backed Codex flow. The backend and\n * OAuth parameters are not a public third-party API contract, so every such\n * value is isolated here for review and rollback.\n */\nexport const CHATGPT_OAUTH_ISSUER = 'https://auth.openai.com' as const\nexport const CHATGPT_OAUTH_CLIENT_ID = 'app_EMoamEEZ73f0CkXaXp7hrann' as const\nexport const OAUTH_CALLBACK_HOST = 'localhost' as const\nexport const OAUTH_CALLBACK_PORT = 1455 as const\nexport const OAUTH_CALLBACK_PATH = '/auth/callback' as const\nexport const OAUTH_REDIRECT_URI = `http://${OAUTH_CALLBACK_HOST}:${OAUTH_CALLBACK_PORT}${OAUTH_CALLBACK_PATH}` as const\nexport const OAUTH_SCOPE = 'openid profile email offline_access' as const\n/**\n * The single `originator` this line presents to the Codex backend on every\n * request, and the one OAuth sends during sign-in.\n *\n * This used to be three different values - `opencode` for chat and sign-in,\n * `pi` for the image and search endpoints - which was an archaeological record\n * of when each endpoint was reverse-engineered, not a decision. The Codex\n * backend keys behaviour off this value (`codex_cli_rs` is what the official\n * CLI sends) and treats it as one client identity, so splitting it across three\n * files meant three unrelated failure signatures for one account. Both spellings\n * are known-good against the backend; `opencode` is kept because it is the value\n * the OAuth flow has always presented, and changing the sign-in originator is a\n * different risk from changing the request originator.\n */\nexport const CODEX_ORIGINATOR = 'opencode' as const\n/** OAuth presents the same identity the request path does (see above). */\nexport const OAUTH_ORIGINATOR = CODEX_ORIGINATOR\nexport const OAUTH_LOGIN_TIMEOUT_MS = 5 * 60_000\nexport const TOKEN_REFRESH_MARGIN_MS = 60_000\nexport const ROUTE_PREFIX = '/api/dsh-chatgpt-subscription' as const\nexport const PLUGIN_VERSION = '0.1.0-alpha.0' as const\nexport const CODEX_CHATGPT_PROVIDER_ID = 'codex-chatgpt' as const\n\n//\n// MiniMax Code subscription line.\n//\n// The provider id and the route prefix are re-exported from the frozen shared\n// contract rather than restated here, so the two halves of the line cannot drift\n// apart. This line's settings routes live under its own `/minimax-code/api`\n// prefix like every other subscription line, NOT under the Codex\n// `/api/dsh-chatgpt-subscription` prefix below, which belongs to that one route\n// table alone. Exposing the constant here keeps the mounted prefixes discoverable\n// from the compatibility seam.\n//\nexport { MINIMAX_CODE_PROVIDER_ID, MINIMAX_CODE_ROUTE_PREFIX } from './shared/minimax-code-contracts.ts'\n\nexport const CODEX_API_BASE = 'https://chatgpt.com/backend-api/codex' as const\nexport const CODEX_RESPONSES_URL = `${CODEX_API_BASE}/responses` as const\nexport const CODEX_IMAGE_GENERATION_URL = `${CODEX_API_BASE}/images/generations` as const\nexport const CODEX_SEARCH_URL = `${CODEX_API_BASE}/alpha/search` as const\nexport const CODEX_USAGE_URL = 'https://chatgpt.com/backend-api/wham/usage' as const\n/**\n * The live model listing the subscription serves.\n *\n * Unlike the public `/v1/models`, this endpoint answers the *subscription*\n * entitlement: which models this plan can call, their real context window, and\n * the reasoning levels each one accepts. `client_version` is required and is the\n * same value the official CLI sends.\n */\nexport const CODEX_CLIENT_VERSION = '0.99.0' as const\nexport const CODEX_MODELS_URL = `${CODEX_API_BASE}/models?client_version=${CODEX_CLIENT_VERSION}` as const\n/**\n * Beta gate the Codex backend expects on every responses request.\n *\n * The subscription backend is served under a beta flag, not as stable API:\n * without this header the endpoint is a different (and, on older builds,\n * rejected) surface. Kept as a single constant so the value is reviewable in\n * one place with the rest of the wire contract in `wire-auth.ts`.\n */\nexport const CODEX_OPENAI_BETA = 'responses=experimental' as const\nexport const CODEX_RESET_CREDITS_URL = 'https://chatgpt.com/backend-api/wham/rate-limit-reset-credits' as const\nexport const CODEX_RESET_CREDITS_CONSUME_URL = `${CODEX_RESET_CREDITS_URL}/consume` as const\nexport const CODEX_IMAGE_TOOL_NAME = 'codex_image_generate' as const\nexport const CODEX_IMAGE_MODEL = 'gpt-image-2' as const\nexport const CODEX_SEARCH_PROVIDER_ID = 'codex-subscription' as const\nexport const CODEX_FETCH_PROVIDER_ID = 'codex-subscription' as const\nexport const QUOTA_CACHE_MS = 60_000\nexport const QUOTA_MIN_UPSTREAM_INTERVAL_MS = 15_000\n\nexport const OAUTH_AUTHORIZE_URL = `${CHATGPT_OAUTH_ISSUER}/oauth/authorize` as const\nexport const OAUTH_TOKEN_URL = `${CHATGPT_OAUTH_ISSUER}/oauth/token` as const\n","/**\n * Subscribe to a snapshot store as a React value.\n *\n * Two copies of this existed — the shared composer badge and the ChatGPT badge —\n * which is why it lives in its own module rather than being exported from the\n * badge: a component module exporting a generic hook reads as if the hook\n * belonged to that component.\n */\nimport { useSyncExternalStore } from 'react'\nimport type { SnapshotStore } from '../store.ts'\n\nexport function useStore<T>(store: SnapshotStore<T>): T {\n return useSyncExternalStore(\n (listener) => store.subscribe(listener),\n () => store.getSnapshot(),\n () => store.getSnapshot(),\n )\n}\n","import type { QuotaBucketDto, QuotaStatusDto, QuotaWindowDto } from '../shared/contracts.ts'\n\nexport interface SelectedQuotaWindow {\n bucket: QuotaBucketDto\n window: QuotaWindowDto\n remainingPercent: number\n}\n\nexport function selectQuotaForModel(quota: QuotaStatusDto | undefined, modelId: string | undefined): SelectedQuotaWindow | null {\n if (quota === undefined || quota.buckets.length === 0) return null\n const model = modelId?.toLowerCase() ?? ''\n const wantsSpark = model.includes('spark')\n const bucket = wantsSpark\n ? quota.buckets.find(candidate => `${candidate.id} ${candidate.name}`.toLowerCase().includes('spark'))\n : quota.buckets.find(candidate => candidate.id === 'codex')\n ?? quota.buckets.find(candidate => candidate.name.toLowerCase() === 'codex')\n if (bucket === undefined) return null\n const windows = quotaWindows(bucket)\n if (windows.length === 0) return null\n // 优先选取 5h 等短周期额度(按 windowDurationMins 升序排序),没有短周期时选取周额度\n const sorted = [...windows].sort((a, b) => {\n const durA = a.windowDurationMins ?? Infinity\n const durB = b.windowDurationMins ?? Infinity\n return durA - durB\n })\n const window = sorted[0]!\n return {\n bucket,\n window,\n remainingPercent: Math.max(0, 100 - window.usedPercent),\n }\n}\n\nexport function quotaWindows(bucket: QuotaBucketDto): QuotaWindowDto[] {\n if (bucket.windows.length > 0) return bucket.windows\n return [bucket.primary, bucket.secondary].filter((window): window is QuotaWindowDto => window !== null)\n}\n","import { useEffect, useMemo, useRef, useState } from 'react'\nimport type { ModelDirectoryState } from '@deepseek-ai/dsh-client-ui-model-selection/client'\nimport type { PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\nimport { CODEX_CHATGPT_PROVIDER_ID } from '../compat.ts'\nimport type { PluginStatusDto } from '../shared/contracts.ts'\nimport { SubscriptionApi } from './api.ts'\nimport { useStore } from './common/use-store.ts'\nimport { NS } from './locales.ts'\nimport { selectQuotaForModel } from './quota.ts'\nimport type { SnapshotStore } from './store.ts'\n\ntype Props = PropsRuntime<'conversation.input.right'> & PropsLocale<typeof NS> & {\n api: SubscriptionApi\n directory: SnapshotStore<ModelDirectoryState>\n loadModelDirectory: () => void\n}\n\nexport function CodexComposerQuota({ api, directory, loadModelDirectory, t }: Props): React.JSX.Element | null {\n const modelState = useStore(directory)\n const [status, setStatus] = useState<PluginStatusDto | null>(null)\n const [loading, setLoading] = useState(false)\n const mountedRef = useRef(false)\n const selected = modelState.current\n const isCodex = selected?.provider === CODEX_CHATGPT_PROVIDER_ID\n\n useEffect(() => {\n loadModelDirectory()\n }, [loadModelDirectory])\n\n useEffect(() => {\n mountedRef.current = true\n return () => {\n mountedRef.current = false\n }\n }, [])\n\n useEffect(() => {\n if (!isCodex) return\n let disposed = false\n const refresh = async (): Promise<void> => {\n setLoading(true)\n try {\n const next = await api.status()\n if (!disposed && mountedRef.current) setStatus(next)\n } catch {\n if (!disposed && mountedRef.current) setStatus(null)\n } finally {\n if (!disposed && mountedRef.current) setLoading(false)\n }\n }\n void refresh()\n const timer = window.setInterval(() => {\n if (document.visibilityState === 'visible') void refresh()\n }, 60_000)\n return () => {\n disposed = true\n window.clearInterval(timer)\n }\n }, [api, isCodex])\n\n const quota = useMemo(() => selectQuotaForModel(status?.quota, selected?.model), [selected?.model, status?.quota])\n if (!isCodex || status?.preferences.quickQuotaVisible !== true) return null\n const level = quota === null\n ? 'normal'\n : quota.remainingPercent <= 5\n ? 'danger'\n : quota.remainingPercent <= 20\n ? 'warning'\n : 'normal'\n return <span className=\"dsh-codex-composer-quota\" data-level={level} aria-label={quota === null ? t('quickQuotaLoading') : `${t('quickQuotaLabel')}: ${formatPercent(quota.remainingPercent)}`}>\n <span>{t('quickQuotaLabel')}</span>\n <strong>{quota === null ? (loading ? t('quickQuotaLoading') : '—') : formatPercent(quota.remainingPercent)}</strong>\n </span>\n}\n\nfunction formatPercent(value: number): string {\n return `${new Intl.NumberFormat(undefined, { maximumFractionDigits: 0 }).format(value)}%`\n}\n","import { useEffect, useState } from 'react'\nimport type { ImageAttachmentRef } from '@deepseek-ai/dsh-attachment'\nimport type { ContentBlock } from '@deepseek-ai/dsh-client-connection/client'\nimport type { PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\nimport { NS } from './locales.ts'\n\nexport type ImageLoader = (attachment: ImageAttachmentRef) => Promise<string>\n\ntype Props = PropsRuntime<'tool.call.toolview'> & PropsLocale<typeof NS> & {\n loadImage: ImageLoader\n}\n\nexport function CodexImageToolView({ block, loadImage, t }: Props): React.JSX.Element {\n const settled = 'kind' in block\n const isError = settled ? block.isError : false\n const prompt = promptFromBlock(block)\n const images = settled && !isError ? imageBlocks(block.content) : []\n const label = isError ? t('imageToolFailed') : settled ? t('imageToolDone') : t('imageToolRunning')\n const summary = prompt ?? textSummary(settled ? block.content : [])\n return <div className=\"dsh-codex-image-tool\" data-state={isError ? 'error' : settled ? 'done' : 'running'}>\n <div className=\"dsh-codex-image-tool-head\">\n <span className=\"dsh-codex-image-dot\" aria-hidden=\"true\" />\n <span className=\"dsh-codex-image-title\">{label}</span>\n {summary !== null ? <span className=\"dsh-codex-image-summary\">{summary}</span> : null}\n </div>\n {images.length > 0 ? <div className=\"dsh-codex-image-grid\">\n {images.map((attachment) => <GeneratedImage key={String(attachment.attachmentId)} attachment={attachment} load={loadImage} label={attachment.name ?? t('image')} t={t} />)}\n </div> : null}\n </div>\n}\n\nfunction GeneratedImage({ attachment, load, label, t }: {\n attachment: ImageAttachmentRef\n load: ImageLoader\n label: string\n t: Props['t']\n}): React.JSX.Element {\n const [src, setSrc] = useState<string | null>(null)\n const [failed, setFailed] = useState(false)\n useEffect(() => {\n let disposed = false\n setSrc(null)\n setFailed(false)\n load(attachment).then((url) => {\n if (!disposed) setSrc(url)\n }, () => {\n if (!disposed) setFailed(true)\n })\n return () => {\n disposed = true\n }\n }, [attachment, load])\n if (failed) return <span className=\"dsh-codex-image-failed\">{t('imageLoadFailed')}</span>\n if (src === null) return <span className=\"dsh-codex-image-loading\">{t('imageLoading')}</span>\n return <img className=\"dsh-codex-image-preview\" src={src} alt={label} />\n}\n\nfunction promptFromBlock(block: Props['block']): string | null {\n const raw = 'kind' in block ? block.call?.argsRaw : dispatchedArgsRaw(block)\n if (typeof raw !== 'string' || raw.trim() === '') return null\n try {\n const value = JSON.parse(raw) as unknown\n return typeof value === 'object'\n && value !== null\n && !Array.isArray(value)\n && typeof (value as { prompt?: unknown }).prompt === 'string'\n ? (value as { prompt: string }).prompt\n : null\n } catch {\n return null\n }\n}\n\n/**\n * Arguments of a dispatched call that has no result yet.\n *\n * Harness 0.1.7-rc.1 dispatches a view as soon as its call starts *preparing*,\n * before the arguments exist, so the preparing shape carries no `argsRaw` at\n * all. Older generations only ever sent the dispatched shape.\n */\nfunction dispatchedArgsRaw(block: Props['block']): string | undefined {\n return 'argsRaw' in block ? block.argsRaw : undefined\n}\n\n/** Pre-0.1.7 tool-result block: a harness that still carries one nests its content here. */\ninterface LegacyToolResultBlock {\n type: 'tool-result'\n content: readonly ContentBlock[]\n}\n\ntype ToolViewBlock = ContentBlock | LegacyToolResultBlock\n\nfunction imageBlocks(blocks: readonly ToolViewBlock[]): ImageAttachmentRef[] {\n const result: ImageAttachmentRef[] = []\n for (const block of blocks) {\n if (block.type === 'image') result.push(block.attachment)\n if (block.type === 'tool-result') result.push(...imageBlocks(block.content))\n }\n return result\n}\n\nfunction textSummary(blocks: readonly ToolViewBlock[]): string | null {\n const text = blocks\n .map((block) => block.type === 'text' || block.type === 'reasoning' ? block.text : '')\n .filter(Boolean)\n .join(' ')\n .trim()\n return text === '' ? null : text\n}\n","/**\n * Wire contracts for the subscription hub's overview route.\n *\n * The overview is the settings page's opening screen: one card per provider\n * line, annotated with how many accounts it holds and whether it is enabled.\n * Everything here is a non-secret fact a settings card may render; no\n * credential, quota figure, or upstream call ever crosses this boundary.\n */\nimport { ROUTE_PREFIX } from '../compat.ts'\n\n/** The aggregated, read-only overview the hub's opening screen renders. */\nexport const HUB_OVERVIEW_PATH = `${ROUTE_PREFIX}/hub/overview` as const\n\n/** One provider line as the hub's overview card renders it. */\nexport interface HubProviderSummaryDto {\n /** Client descriptor key, e.g. 'chatgpt', 'kimi-code', 'ollama'. */\n id: string\n /** LLM route id the line serves, e.g. 'codex-chatgpt', 'workbuddy-subscription'. */\n providerId: string\n /**\n * Whether the line has an \"enable this provider\" switch at all.\n *\n * Ollama has none (a key line is always servable), so its card renders no\n * switch instead of a frozen one.\n */\n canToggle: boolean\n /** Whether the line currently serves its route. Always true when `canToggle` is false. */\n enabled: boolean\n /** Signed-in / stored accounts the pool currently holds. */\n accountCount: number\n /** Whether at least one account can authenticate right now. */\n authenticated: boolean\n /**\n * Enabled model count, when the line can determine it locally.\n *\n * Lines whose catalog only exists upstream report null rather than guessing,\n * and the card simply omits the model annotation.\n */\n enabledModelCount: number | null\n /** Total catalog size when locally known; null otherwise. */\n totalModelCount: number | null\n /** True when this line's summary could not be read and the counts are placeholders. */\n error?: boolean\n}\n\nexport interface HubOverviewDto {\n providers: HubProviderSummaryDto[]\n}\n","/**\n * Labels every provider tab's account-pool card renders.\n *\n * They live here rather than in each provider's locale file so the four tabs\n * cannot drift apart in wording, ordering or meaning. The active locale is the\n * one the host already selects per provider; each `locales.ts` spreads the set\n * it needs and may override individual keys.\n */\n\n/** Labels the shared card needs, in the order its markup uses them. */\nexport interface AccountPoolLabels {\n accountPool: string\n addAccount: string\n /** `{count}` is replaced with the number of signed-in accounts. */\n accountCount: string\n primaryAccount: string\n activeAccount: string\n setPrimary: string\n deleteAccount: string\n cooling: string\n /** `{minutes}` is replaced with the remaining cooldown in whole minutes. */\n cooldownLeft: string\n clearCooldown: string\n needsRelogin: string\n relogin: string\n rotationStrategy: string\n strategySequential: string\n strategyRoundRobin: string\n strategySticky: string\n noAccounts: string\n email: string\n expires: string\n lastUsed: string\n accountId: string\n /** Legend of the per-account quota block. */\n accountQuota: string\n /** Shown when no quota was ever read for that account. */\n quotaNone: string\n /** `{time}` is replaced with the snapshot's read time. */\n quotaSnapshot: string\n /** Prefix of a window's reset moment, e.g. `重置 3 小时后`. */\n quotaResets: string\n /** Drawn in place of a percentage once a window is spent. */\n quotaExhausted: string\n /** Fallback window name when the line gave neither a label nor a length. */\n quotaWindow: string\n /** Read out by a screen reader beside the bar's percentage. */\n quotaUsed: string\n /** Explains that the page-level facts belong to the current account only. */\n quotaFactsScope: string\n /** The composer badge's own label, in front of its number. */\n composerLabel: string\n}\n\n/** Chinese labels; the wording the Antigravity card shipped with. */\nexport const accountPoolZh: AccountPoolLabels = {\n accountPool: '账号管理',\n addAccount: '添加账号',\n accountCount: '已登录 {count} 个账号',\n primaryAccount: '主账号',\n activeAccount: '当前使用',\n setPrimary: '设为主账号',\n deleteAccount: '删除',\n cooling: '冷却中',\n cooldownLeft: '剩 {minutes} 分',\n clearCooldown: '重置冷却',\n needsRelogin: '需重新登录',\n relogin: '重新登录',\n rotationStrategy: '调度策略',\n strategySequential: '顺序耗尽(当前优先,遇限流自动切号)',\n strategyRoundRobin: '轮询调度(按账号循环均匀分摊)',\n strategySticky: '粘性会话(保持当前账号,遇限流才切换)',\n noAccounts: '暂无账号,点击「添加账号」完成登录授权。',\n email: '邮箱',\n expires: '令牌到期',\n lastUsed: '上次调用',\n accountId: '账号 ID',\n accountQuota: '配额',\n quotaNone: '尚无配额数据',\n quotaSnapshot: '快照 {time}',\n quotaResets: '重置',\n quotaExhausted: '已用尽',\n quotaWindow: '额度窗口',\n quotaUsed: '已用',\n quotaFactsScope: '以下为当前账号的配额事实;每个账号自己的进度显示在它的账号卡片里。',\n composerLabel: '额度',\n}\n\n/** English labels for the ChatGPT tab, which is the bilingual one. */\nexport const accountPoolEn: AccountPoolLabels = {\n accountPool: 'Account Management',\n addAccount: 'Add Account',\n accountCount: '{count} account(s) signed in',\n primaryAccount: 'Primary',\n activeAccount: 'In Use',\n setPrimary: 'Set as Primary',\n deleteAccount: 'Delete',\n cooling: 'In Cooldown',\n cooldownLeft: '{minutes} min left',\n clearCooldown: 'Clear Cooldown',\n needsRelogin: 'Sign-in required',\n relogin: 'Sign in again',\n rotationStrategy: 'Scheduling Strategy',\n strategySequential: 'Sequential Drain (primary first, fail over on 429)',\n strategyRoundRobin: 'Round-Robin (evenly rotate across accounts)',\n strategySticky: 'Sticky Session (keep the current account until it is limited)',\n noAccounts: 'No accounts yet. Click \"Add Account\" to authorize.',\n email: 'Email',\n expires: 'Token expires',\n lastUsed: 'Last used',\n accountId: 'Account ID',\n accountQuota: 'Quota',\n quotaNone: 'No quota read yet',\n quotaSnapshot: 'Snapshot {time}',\n quotaResets: 'Resets',\n quotaExhausted: 'Exhausted',\n quotaWindow: 'Limit window',\n quotaUsed: 'used',\n quotaFactsScope: 'These facts describe the current account; each account\\u2019s own progress is shown on its card above.',\n composerLabel: 'Quota',\n}\n\n/** Replace `{name}` placeholders in one label. */\nexport function formatPoolLabel(template: string, values: Record<string, string | number>): string {\n return template.replace(/\\{(\\w+)\\}/g, (match, name: string) => (\n name in values ? String(values[name]) : match\n ))\n}\n","/**\n * Inline brand marks, extracted from the vendored combine lockups\n * (dsh-claude-style/src/assets/icons/combine). Each entry is the\n * mark-color group's inner artwork with its original transform, cropped\n * to a square, mark-centered viewBox measured against the rendered lockup.\n * Regenerate with temp/gen-brand-svg.cjs; do not hand-edit the artwork.\n */\nexport interface BrandMarkSvg { viewBox: string; body: string }\n\nexport const BRAND_MARKS = {\n 'openai': {\n viewBox: '0 -0.225 1.45 1.45',\n body: '<g transform=\"translate(-0.2852 -2.0104) scale(0.002787)\"><g fill=\"currentColor\"><path d=\"M583.793,841.346c11.778,-44.127 0.356,-93.159 -34.264,-127.777c-34.616,-34.618 -83.65,-46.041 -127.777,-34.264c-32.329,-32.262 -80.503,-46.887 -127.794,-34.215c-47.289,12.672 -81.694,49.424 -93.563,93.526c-44.102,11.866 -80.854,46.274 -93.523,93.564c-12.673,47.289 1.952,95.462 34.214,127.791c-11.776,44.126 -0.354,93.16 34.264,127.777c34.618,34.62 83.651,46.041 127.779,34.264c32.329,32.263 80.503,46.888 127.79,34.215c47.289,-12.672 81.695,-49.425 93.564,-93.526c44.104,-11.865 80.857,-46.274 93.526,-93.563c12.672,-47.291 -1.952,-95.462 -34.216,-127.792Zm-179.693,-124.105c39.682,-22.943 91.303,-17.439 125.254,16.511c23.963,23.965 33.748,56.745 29.367,87.904l-111.77,-64.53c-4.415,-2.549 -9.855,-2.549 -14.27,0l-130.876,75.563l0,-50.806c0,-3.427 1.837,-6.63 4.803,-8.343l97.49,-56.297l0.002,-0.002Zm-41.659,113.397l60.638,35.01l0,70.02l-60.638,35.01l-60.639,-35.01l0,-70.02l60.639,-35.01Zm-138.015,-57.766c-0.029,-45.836 30.549,-87.793 76.926,-100.217c32.734,-8.773 66.015,-0.856 90.81,18.518l-111.768,64.53c-4.415,2.549 -7.134,7.261 -7.134,12.359l0,151.125l-44.001,-25.405c-2.967,-1.715 -4.824,-4.909 -4.824,-8.332l-0.009,-112.576l0,-0.002Zm-89.99,66.69c8.773,-32.735 32.268,-57.601 61.443,-69.386l0,129.056c0,5.099 2.719,9.81 7.134,12.359l130.877,75.564l-44.002,25.405c-2.964,1.713 -6.661,1.724 -9.627,0.011l-97.498,-56.279c-39.71,-22.893 -60.754,-70.353 -48.329,-116.727l0.002,-0.003Zm186.345,244.515c-39.681,22.943 -91.303,17.437 -125.253,-16.512c-23.965,-23.965 -33.749,-56.745 -29.368,-87.904l111.769,64.53c4.414,2.549 9.856,2.549 14.271,0l130.876,-75.564l0,50.807c0,3.429 -1.837,6.632 -4.803,8.343l-97.49,56.298l-0.002,0.002Zm179.675,-55.631c0.028,45.837 -30.55,87.793 -76.927,100.216c-32.736,8.774 -66.017,0.856 -90.81,-18.519l111.767,-64.529c4.417,-2.549 7.136,-7.262 7.136,-12.359l0,-151.123l44.001,25.404c2.965,1.713 4.824,4.909 4.824,8.332l0.009,112.578Zm89.986,-66.691c-8.773,32.735 -32.268,57.601 -61.444,69.387l0,-129.058c0,-5.097 -2.718,-9.808 -7.133,-12.359l-130.878,-75.562l44.002,-25.405c2.965,-1.714 6.662,-1.726 9.628,-0.012l97.497,56.278c39.712,22.893 60.754,70.355 48.329,116.729l-0.001,0.002Z\" style=\"\"/></g></g>',\n },\n 'gemini': {\n viewBox: '0 -0.1644 1.329 1.329',\n body: '<g transform=\"translate(-0.0604 -0.2250) scale(0.060417)\"><g><path d=\"M20.616 10.835a14.147 14.147 0 01-4.45-3.001 14.111 14.111 0 01-3.678-6.452.503.503 0 00-.975 0 14.134 14.134 0 01-3.679 6.452 14.155 14.155 0 01-4.45 3.001c-.65.28-1.318.505-2.002.678a.502.502 0 000 .975c.684.172 1.35.397 2.002.677a14.147 14.147 0 014.45 3.001 14.112 14.112 0 013.679 6.453.502.502 0 00.975 0c.172-.685.397-1.351.677-2.003a14.145 14.145 0 013.001-4.45 14.113 14.113 0 016.453-3.678.503.503 0 000-.975 13.245 13.245 0 01-2.003-.678z\" fill=\"#3186FF\"></path><path d=\"M20.616 10.835a14.147 14.147 0 01-4.45-3.001 14.111 14.111 0 01-3.678-6.452.503.503 0 00-.975 0 14.134 14.134 0 01-3.679 6.452 14.155 14.155 0 01-4.45 3.001c-.65.28-1.318.505-2.002.678a.502.502 0 000 .975c.684.172 1.35.397 2.002.677a14.147 14.147 0 014.45 3.001 14.112 14.112 0 013.679 6.453.502.502 0 00.975 0c.172-.685.397-1.351.677-2.003a14.145 14.145 0 013.001-4.45 14.113 14.113 0 016.453-3.678.503.503 0 000-.975 13.245 13.245 0 01-2.003-.678z\" fill=\"url(#lobe-icons-gemini-0-_R_0_)\"></path><path d=\"M20.616 10.835a14.147 14.147 0 01-4.45-3.001 14.111 14.111 0 01-3.678-6.452.503.503 0 00-.975 0 14.134 14.134 0 01-3.679 6.452 14.155 14.155 0 01-4.45 3.001c-.65.28-1.318.505-2.002.678a.502.502 0 000 .975c.684.172 1.35.397 2.002.677a14.147 14.147 0 014.45 3.001 14.112 14.112 0 013.679 6.453.502.502 0 00.975 0c.172-.685.397-1.351.677-2.003a14.145 14.145 0 013.001-4.45 14.113 14.113 0 016.453-3.678.503.503 0 000-.975 13.245 13.245 0 01-2.003-.678z\" fill=\"url(#lobe-icons-gemini-1-_R_0_)\"></path><path d=\"M20.616 10.835a14.147 14.147 0 01-4.45-3.001 14.111 14.111 0 01-3.678-6.452.503.503 0 00-.975 0 14.134 14.134 0 01-3.679 6.452 14.155 14.155 0 01-4.45 3.001c-.65.28-1.318.505-2.002.678a.502.502 0 000 .975c.684.172 1.35.397 2.002.677a14.147 14.147 0 014.45 3.001 14.112 14.112 0 013.679 6.453.502.502 0 00.975 0c.172-.685.397-1.351.677-2.003a14.145 14.145 0 013.001-4.45 14.113 14.113 0 016.453-3.678.503.503 0 000-.975 13.245 13.245 0 01-2.003-.678z\" fill=\"url(#lobe-icons-gemini-2-_R_0_)\"></path><defs><linearGradient gradientUnits=\"userSpaceOnUse\" id=\"lobe-icons-gemini-0-_R_0_\" x1=\"7\" x2=\"11\" y1=\"15.5\" y2=\"12\"><stop stop-color=\"#08B962\"></stop><stop offset=\"1\" stop-color=\"#08B962\" stop-opacity=\"0\"></stop></linearGradient><linearGradient gradientUnits=\"userSpaceOnUse\" id=\"lobe-icons-gemini-1-_R_0_\" x1=\"8\" x2=\"11.5\" y1=\"5.5\" y2=\"11\"><stop stop-color=\"#F94543\"></stop><stop offset=\"1\" stop-color=\"#F94543\" stop-opacity=\"0\"></stop></linearGradient><linearGradient gradientUnits=\"userSpaceOnUse\" id=\"lobe-icons-gemini-2-_R_0_\" x1=\"3.5\" x2=\"17.5\" y1=\"13.5\" y2=\"12\"><stop stop-color=\"#FABC12\"></stop><stop offset=\".46\" stop-color=\"#FABC12\" stop-opacity=\"0\"></stop></linearGradient></defs></g></g>',\n },\n 'kimi': {\n viewBox: '0.0488 -0.225 1.2083 1.2083',\n body: '<g transform=\"translate(-0.1812 -0.2250) scale(0.060417)\"><g><path d=\"M21.846 0a1.923 1.923 0 110 3.846H20.15a.226.226 0 01-.227-.226V1.923C19.923.861 20.784 0 21.846 0z\" fill=\"#1783FF\"></path><path d=\"M11.065 11.199l7.257-7.2c.137-.136.06-.41-.116-.41H14.3a.164.164 0 00-.117.051l-7.82 7.756c-.122.12-.302.013-.302-.179V3.82c0-.127-.083-.23-.185-.23H3.186c-.103 0-.186.103-.186.23V19.77c0 .128.083.23.186.23h2.69c.103 0 .186-.102.186-.23v-3.25c0-.069.025-.135.069-.178l2.424-2.406a.158.158 0 01.205-.023l6.484 4.772a7.677 7.677 0 003.453 1.283c.108.012.2-.095.2-.23v-3.06c0-.117-.07-.212-.164-.227a5.028 5.028 0 01-2.027-.807l-5.613-4.064c-.117-.078-.132-.279-.028-.381z\" fill=\"currentColor\"></path></g></g>',\n },\n 'minimax': {\n viewBox: '0 -0.225 1.45 1.45',\n body: '<g transform=\"translate(-0.0000 -0.2250) scale(0.060417)\"><g><defs><linearGradient id=\"lobe-icons-minimax-_R_0_\" x1=\"0%\" x2=\"100.182%\" y1=\"50.057%\" y2=\"50.057%\"><stop offset=\"0%\" stop-color=\"#E2167E\"></stop><stop offset=\"100%\" stop-color=\"#FE603C\"></stop></linearGradient></defs><path d=\"M16.278 2c1.156 0 2.093.927 2.093 2.07v12.501a.74.74 0 00.744.709.74.74 0 00.743-.709V9.099a2.06 2.06 0 012.071-2.049A2.06 2.06 0 0124 9.1v6.561a.649.649 0 01-.652.645.649.649 0 01-.653-.645V9.1a.762.762 0 00-.766-.758.762.762 0 00-.766.758v7.472a2.037 2.037 0 01-2.048 2.026 2.037 2.037 0 01-2.048-2.026v-12.5a.785.785 0 00-.788-.753.785.785 0 00-.789.752l-.001 15.904A2.037 2.037 0 0113.441 22a2.037 2.037 0 01-2.048-2.026V18.04c0-.356.292-.645.652-.645.36 0 .652.289.652.645v1.934c0 .263.142.506.372.638.23.131.514.131.744 0a.734.734 0 00.372-.638V4.07c0-1.143.937-2.07 2.093-2.07zm-5.674 0c1.156 0 2.093.927 2.093 2.07v11.523a.648.648 0 01-.652.645.648.648 0 01-.652-.645V4.07a.785.785 0 00-.789-.78.785.785 0 00-.789.78v14.013a2.06 2.06 0 01-2.07 2.048 2.06 2.06 0 01-2.071-2.048V9.1a.762.762 0 00-.766-.758.762.762 0 00-.766.758v3.8a2.06 2.06 0 01-2.071 2.049A2.06 2.06 0 010 12.9v-1.378c0-.357.292-.646.652-.646.36 0 .653.29.653.646V12.9c0 .418.343.757.766.757s.766-.339.766-.757V9.099a2.06 2.06 0 012.07-2.048 2.06 2.06 0 012.071 2.048v8.984c0 .419.343.758.767.758.423 0 .766-.339.766-.758V4.07c0-1.143.937-2.07 2.093-2.07z\" fill=\"url(#lobe-icons-minimax-_R_0_)\" fill-rule=\"nonzero\"></path></g></g>',\n },\n 'tencent': {\n viewBox: '0 -0.225 1.45 1.45',\n body: '<g transform=\"translate(-0.0000 -0.2250) scale(0.060417)\"><g><circle cx=\"12\" cy=\"12\" fill=\"#0055E9\" r=\"12\"></circle><path d=\"M12 0c.518 0 1.028.033 1.528.096A6.188 6.188 0 0112.12 12.28l-.12.001c-2.99 0-5.242 2.179-5.554 5.11-.223 2.086.353 4.412 2.242 6.146C3.672 22.1 0 17.479 0 12 0 5.373 5.373 0 12 0z\" fill=\"currentColor\"></path><path d=\"M5.286 5a2.438 2.438 0 01.682 3.38c-3.962 5.966-3.215 10.743 2.648 15.136C3.636 22.056 0 17.452 0 12c0-1.787.39-3.482 1.09-5.006.253-.435.525-.872.817-1.311A2.438 2.438 0 015.286 5z\" fill=\"#0055E9\"></path><path d=\"M12.98.04c.272.021.543.053.81.093.583.106 1.117.254 1.538.44 6.638 2.927 8.07 10.052 1.748 15.642a4.125 4.125 0 01-5.822-.358c-1.51-1.706-1.3-4.184.357-5.822.858-.848 3.108-1.223 4.045-2.441 1.257-1.634 2.122-6.009-2.523-7.506L12.98.039z\" fill=\"#00BCFF\"></path><path d=\"M13.528.096A6.187 6.187 0 0112 12.281a5.75 5.75 0 00-1.71.255c.147-.905.595-1.784 1.321-2.501.858-.848 3.108-1.223 4.045-2.441 1.27-1.651 2.14-6.104-2.676-7.554.184.014.367.033.548.056z\" fill=\"#ECECEE\"></path></g></g>',\n },\n 'qwen': {\n viewBox: '-0.0125 -0.1646 1.3417 1.3417',\n body: '<g transform=\"translate(-0.0604 -0.2250) scale(0.060417)\"><g><path d=\"M12.604 1.34c.393.69.784 1.382 1.174 2.075a.18.18 0 00.157.091h5.552c.174 0 .322.11.446.327l1.454 2.57c.19.337.24.478.024.837-.26.43-.513.864-.76 1.3l-.367.658c-.106.196-.223.28-.04.512l2.652 4.637c.172.301.111.494-.043.77-.437.785-.882 1.564-1.335 2.34-.159.272-.352.375-.68.37-.777-.016-1.552-.01-2.327.016a.099.099 0 00-.081.05 575.097 575.097 0 01-2.705 4.74c-.169.293-.38.363-.725.364-.997.003-2.002.004-3.017.002a.537.537 0 01-.465-.271l-1.335-2.323a.09.09 0 00-.083-.049H4.982c-.285.03-.553-.001-.805-.092l-1.603-2.77a.543.543 0 01-.002-.54l1.207-2.12a.198.198 0 000-.197 550.951 550.951 0 01-1.875-3.272l-.79-1.395c-.16-.31-.173-.496.095-.965.465-.813.927-1.625 1.387-2.436.132-.234.304-.334.584-.335a338.3 338.3 0 012.589-.001.124.124 0 00.107-.063l2.806-4.895a.488.488 0 01.422-.246c.524-.001 1.053 0 1.583-.006L11.704 1c.341-.003.724.032.9.34zm-3.432.403a.06.06 0 00-.052.03L6.254 6.788a.157.157 0 01-.135.078H3.253c-.056 0-.07.025-.041.074l5.81 10.156c.025.042.013.062-.034.063l-2.795.015a.218.218 0 00-.2.116l-1.32 2.31c-.044.078-.021.118.068.118l5.716.008c.046 0 .08.02.104.061l1.403 2.454c.046.081.092.082.139 0l5.006-8.76.783-1.382a.055.055 0 01.096 0l1.424 2.53a.122.122 0 00.107.062l2.763-.02a.04.04 0 00.035-.02.041.041 0 000-.04l-2.9-5.086a.108.108 0 010-.113l.293-.507 1.12-1.977c.024-.041.012-.062-.035-.062H9.2c-.059 0-.073-.026-.043-.077l1.434-2.505a.107.107 0 000-.114L9.225 1.774a.06.06 0 00-.053-.031zm6.29 8.02c.046 0 .058.02.034.06l-.832 1.465-2.613 4.585a.056.056 0 01-.05.029.058.058 0 01-.05-.029L8.498 9.841c-.02-.034-.01-.052.028-.054l.216-.012 6.722-.012z\" fill=\"url(#lobe-icons-qwen-_R_0_)\" fill-rule=\"nonzero\"></path><defs><linearGradient id=\"lobe-icons-qwen-_R_0_\" x1=\"0%\" x2=\"100%\" y1=\"0%\" y2=\"0%\"><stop offset=\"0%\" stop-color=\"#6336E7\" stop-opacity=\".84\"></stop><stop offset=\"100%\" stop-color=\"#6F69F7\" stop-opacity=\".84\"></stop></linearGradient></defs></g></g>',\n },\n 'deepseek': {\n viewBox: '0 -0.2352 1.45 1.45',\n body: '<g transform=\"translate(-0.0000 -0.2250) scale(0.060417)\"><g><path d=\"M23.748 4.482c-.254-.124-.364.113-.512.234-.051.039-.094.09-.137.136-.372.397-.806.657-1.373.626-.829-.046-1.537.214-2.163.848-.133-.782-.575-1.248-1.247-1.548-.352-.156-.708-.311-.955-.65-.172-.241-.219-.51-.305-.774-.055-.16-.11-.323-.293-.35-.2-.031-.278.136-.356.276-.313.572-.434 1.202-.422 1.84.027 1.436.633 2.58 1.838 3.393.137.093.172.187.129.323-.082.28-.18.552-.266.833-.055.179-.137.217-.329.14a5.526 5.526 0 01-1.736-1.18c-.857-.828-1.631-1.742-2.597-2.458a11.365 11.365 0 00-.689-.471c-.985-.957.13-1.743.388-1.836.27-.098.093-.432-.779-.428-.872.004-1.67.295-2.687.684a3.055 3.055 0 01-.465.137 9.597 9.597 0 00-2.883-.102c-1.885.21-3.39 1.102-4.497 2.623C.082 8.606-.231 10.684.152 12.85c.403 2.284 1.569 4.175 3.36 5.653 1.858 1.533 3.997 2.284 6.438 2.14 1.482-.085 3.133-.284 4.994-1.86.47.234.962.327 1.78.397.63.059 1.236-.03 1.705-.128.735-.156.684-.837.419-.961-2.155-1.004-1.682-.595-2.113-.926 1.096-1.296 2.746-2.642 3.392-7.003.05-.347.007-.565 0-.845-.004-.17.035-.237.23-.256a4.173 4.173 0 001.545-.475c1.396-.763 1.96-2.015 2.093-3.517.02-.23-.004-.467-.247-.588zM11.581 18c-2.089-1.642-3.102-2.183-3.52-2.16-.392.024-.321.471-.235.763.09.288.207.486.371.739.114.167.192.416-.113.603-.673.416-1.842-.14-1.897-.167-1.361-.802-2.5-1.86-3.301-3.307-.774-1.393-1.224-2.887-1.298-4.482-.02-.386.093-.522.477-.592a4.696 4.696 0 011.529-.039c2.132.312 3.946 1.265 5.468 2.774.868.86 1.525 1.887 2.202 2.891.72 1.066 1.494 2.082 2.48 2.914.348.292.625.514.891.677-.802.09-2.14.11-3.054-.614zm1-6.44a.306.306 0 01.415-.287.302.302 0 01.2.288.306.306 0 01-.31.307.303.303 0 01-.304-.308zm3.11 1.596c-.2.081-.399.151-.59.16a1.245 1.245 0 01-.798-.254c-.274-.23-.47-.358-.552-.758a1.73 1.73 0 01.016-.588c.07-.327-.008-.537-.239-.727-.187-.156-.426-.199-.688-.199a.559.559 0 01-.254-.078c-.11-.054-.2-.19-.114-.358.028-.054.16-.186.192-.21.356-.202.767-.136 1.146.016.352.144.618.408 1.001.782.391.451.462.576.685.914.176.265.336.537.445.848.067.195-.019.354-.25.452z\" fill=\"#4D6BFE\"></path></g></g>',\n },\n 'grok': {\n viewBox: '0 -0.2237 1.45 1.45',\n body: '<g transform=\"translate(-0.0000 -0.2250) scale(0.060417)\"><g fill=\"#000\" fill-rule=\"evenodd\"><path d=\"M9.27 15.29l7.978-5.897c.391-.29.95-.177 1.137.272.98 2.369.542 5.215-1.41 7.169-1.951 1.954-4.667 2.382-7.149 1.406l-2.711 1.257c3.889 2.661 8.611 2.003 11.562-.953 2.341-2.344 3.066-5.539 2.388-8.42l.006.007c-.983-4.232.242-5.924 2.75-9.383.06-.082.12-.164.179-.248l-3.301 3.305v-.01L9.267 15.292M7.623 16.723c-2.792-2.67-2.31-6.801.071-9.184 1.761-1.763 4.647-2.483 7.166-1.425l2.705-1.25a7.808 7.808 0 00-1.829-1A8.975 8.975 0 005.984 5.83c-2.533 2.536-3.33 6.436-1.962 9.764 1.022 2.487-.653 4.246-2.34 6.022-.599.63-1.199 1.259-1.682 1.925l7.62-6.815\"></path></g></g>',\n },\n 'claude': {\n viewBox: '0 0 148.09 148.18',\n body: '<g transform=\\'translate(-75.96,-223.53)\\'><path d=\\'m 105.01,322.07 29.14,-16.35 0.49,-1.42 -0.49,-0.79 h -1.42 l -4.87,-0.3 -16.65,-0.45 -14.44,-0.6 -13.99,-0.75 -3.52,-0.75 -3.3,-4.35 0.34,-2.17 2.96,-1.99 4.24,0.37 9.37,0.64 14.06,0.97 10.2,0.6 15.11,1.57 h 2.4 l 0.34,-0.97 -0.82,-0.6 -0.64,-0.6 -14.55,-9.86 -15.75,-10.42 -8.25,-6 -4.46,-3.04 -2.25,-2.85 -0.97,-6.22 4.05,-4.46 5.44,0.37 1.39,0.37 5.51,4.24 11.77,9.11 15.37,11.32 2.25,1.87 0.9,-0.64 0.11,-0.45 -1.01,-1.69 -8.36,-15.11 -8.92,-15.37 -3.97,-6.37 -1.05,-3.82 c -0.37,-1.57 -0.64,-2.89 -0.64,-4.5 l 4.61,-6.26 2.55,-0.82 6.15,0.82 2.59,2.25 3.82,8.74 6.19,13.76 9.6,18.71 2.81,5.55 1.5,5.14 0.56,1.57 h 0.97 v -0.9 l 0.79,-10.54 1.46,-12.94 1.42,-16.65 0.49,-4.69 2.32,-5.62 4.61,-3.04 3.6,1.72 2.96,4.24 -0.41,2.74 -1.76,11.44 -3.45,17.92 -2.25,12 h 1.31 l 1.5,-1.5 6.07,-8.06 10.2,-12.75 4.5,-5.06 5.25,-5.59 3.37,-2.66 h 6.37 l 4.69,6.97 -2.1,7.2 -6.56,8.32 -5.44,7.05 -7.8,10.5 -4.87,8.4 0.45,0.67 1.16,-0.11 17.62,-3.75 9.52,-1.72 11.36,-1.95 5.14,2.4 0.56,2.44 -2.02,4.99 -12.15,3 -14.25,2.85 -21.22,5.02 -0.26,0.19 0.3,0.37 9.56,0.9 4.09,0.22 h 10.01 l 18.64,1.39 4.87,3.22 2.92,3.94 -0.49,3 -7.5,3.82 -10.12,-2.4 -23.62,-5.62 -8.1,-2.02 h -1.12 v 0.67 l 6.75,6.6 12.37,11.17 15.49,14.4 0.79,3.56 -1.99,2.81 -2.1,-0.3 -13.61,-10.24 -5.25,-4.61 -11.89,-10.01 h -0.79 v 1.05 l 2.74,4.01 14.47,21.75 0.75,6.67 -1.05,2.17 -3.75,1.31 -4.12,-0.75 -8.47,-11.89 -8.74,-13.39 -7.05,-12 -0.86,0.49 -4.16,44.81 -1.95,2.29 -4.5,1.72 -3.75,-2.85 -1.99,-4.61 1.99,-9.11 2.4,-11.89 1.95,-9.45 1.76,-11.74 1.05,-3.9 -0.07,-0.26 -0.86,0.11 -8.85,12.15 -13.46,18.19 -10.65,11.4 -2.55,1.01 -4.42,-2.29 0.41,-4.09 2.47,-3.64 14.74,-18.75 8.89,-11.62 5.74,-6.71 -0.04,-0.97 h -0.34 l -39.15,25.42 -6.97,0.9 -3,-2.81 0.37,-4.61 1.42,-1.5 11.77,-8.1 -0.04,0.04 z\\'/></g>',\n },\n} as const satisfies Record<string, BrandMarkSvg>\n\nexport type BrandMarkKey = keyof typeof BRAND_MARKS\n","/**\n * Provider and vendor brand marks for the hub overview cards and the shared\n * model checklist.\n *\n * The artwork lives in brand-svg.ts as inline strings (extracted from the\n * vendored combine lockups); this module adds the presentation: a rounded,\n * brand-tinted tile for provider cards, a bare mark for model rows, and the\n * ordered model-id → vendor rules. A model no rule claims draws no mark at\n * all — a wrong vendor's mark reads as a wrong answer, not a missing one\n * (the same principle claude-style's brand.js documents).\n */\nimport { BRAND_MARKS, type BrandMarkKey } from './brand-svg.ts'\n\nexport type HubProviderId =\n | 'chatgpt' | 'antigravity' | 'command-code' | 'kimi-code'\n | 'workbuddy' | 'minimax-code' | 'claude' | 'ollama'\n\ninterface ProviderBrand {\n /** Key into BRAND_MARKS; absent for monogram-only providers. */\n mark?: BrandMarkKey\n /**\n * Text color for artwork that draws in currentColor (OpenAI's knot, Kimi's\n * K, Claude's mark). Self-colored artwork (gradients, multi-fill marks)\n * leaves this undefined.\n */\n color?: string\n /** Brand color the tile's tinted background is mixed from. */\n tile: string\n /** Monogram for providers without vendored artwork. */\n monogram?: string\n}\n\nexport const PROVIDER_BRANDS: Record<HubProviderId, ProviderBrand> = {\n chatgpt: { mark: 'openai', color: '#10A37F', tile: '#10A37F' },\n antigravity: { mark: 'gemini', tile: '#3186FF' },\n 'command-code': { monogram: '>_', color: '#7C6AEF', tile: '#7C6AEF' },\n 'kimi-code': { mark: 'kimi', color: '#1F1F1F', tile: '#1783FF' },\n workbuddy: { mark: 'tencent', tile: '#0055E9' },\n 'minimax-code': { mark: 'minimax', tile: '#E2167E' },\n claude: { mark: 'claude', color: '#D97757', tile: '#D97757' },\n ollama: { monogram: 'O', color: '#3B3B3B', tile: '#3B3B3B' },\n}\n\n/** One brand mark at a given box size; the artwork is decorative. */\nexport function BrandMark({ mark, color, size = 22 }: { mark: BrandMarkKey; color?: string; size?: number }): React.JSX.Element {\n const art = BRAND_MARKS[mark]\n return <svg\n aria-hidden=\"true\"\n viewBox={art.viewBox}\n width={size}\n height={size}\n style={color === undefined ? undefined : { color }}\n dangerouslySetInnerHTML={{ __html: art.body }}\n />\n}\n\n/**\n * The overview card's logo tile: the mark centered on a rounded square tinted\n * with the brand color, in the QQ-mail idiom. The tile element doubles as the\n * fallback surface for monogram providers.\n */\nexport function BrandTile({ id, size = 40 }: { id: HubProviderId; size?: number }): React.JSX.Element {\n const brand = PROVIDER_BRANDS[id]\n return <span\n className=\"dsh-hub-brand-tile\"\n aria-hidden=\"true\"\n style={{ width: size, height: size, ['--dsh-hub-brand' as string]: brand.tile }}\n >\n {brand.mark !== undefined\n ? <BrandMark mark={brand.mark} color={brand.color} size={Math.round(size * 0.58)} />\n : <span className=\"dsh-hub-brand-mono\" style={brand.color === undefined ? undefined : { color: brand.color }}>{brand.monogram}</span>}\n </span>\n}\n\n/**\n * The vendor that made one model, resolved from its id. Ordered: the first\n * matching rule wins, so a specific rule ('kimi') precedes a looser one.\n */\nconst MODEL_BRAND_RULES: ReadonlyArray<{ re: RegExp; mark: BrandMarkKey }> = [\n { re: /gpt|codex|o[0-9]/, mark: 'openai' },\n { re: /claude|anthropic/, mark: 'claude' },\n { re: /kimi|moonshot|\\bk[0-9]/, mark: 'kimi' },\n { re: /minimax|\\bm[0-9]/, mark: 'minimax' },\n { re: /gemini/, mark: 'gemini' },\n { re: /qwen/, mark: 'qwen' },\n { re: /deepseek/, mark: 'deepseek' },\n { re: /grok/, mark: 'grok' },\n]\n\nexport function modelBrandMark(modelId: string): BrandMarkKey | null {\n const id = modelId.toLowerCase()\n for (const rule of MODEL_BRAND_RULES) {\n if (rule.re.test(id)) return rule.mark\n }\n return null\n}\n","import type { CodexOutputVerbosity } from './contracts.ts'\n\nexport type CodexModelModality = 'text' | 'image'\n\nexport const GPT_56_MAX_CONTEXT_WINDOW = 1_000_000\n// Codex subscription limits from the model catalog; the public API advertises 1.05M\n// for these families instead.\nexport const GPT_6_MAX_CONTEXT_WINDOW = 872_000\n/** Effective context the GPT-6 family starts at, before any user override. */\nexport const GPT_6_DEFAULT_CONTEXT_WINDOW = 384_000\n/** Output cap of the GPT-6 family; the vendor declares 128K for all three. */\nexport const GPT_6_MAX_TOKENS = 128_000\n/** Output cap for the models predating the GPT-6 family. */\nexport const CODEX_DEFAULT_MAX_TOKENS = 32_768\n\nexport interface CodexModelCatalogEntry {\n id: string\n name: string\n contextWindow: number\n inputModalities: readonly CodexModelModality[]\n defaultReasoningEffort: string\n reasoningProfile: 'standard' | 'gpt-5.6' | 'gpt-6'\n supportsReasoningSummary: boolean\n /**\n * Whether the Responses `text.verbosity` control applies to this model.\n *\n * Official Codex gates the field on the catalog's own `support_verbosity`:\n * a model that does not accept it is sent none, and the official client warns\n * instead of guessing. An absent flag therefore means \"not established\" — this\n * line will not invent the field for a model it has no evidence about.\n */\n supportsOutputVerbosity?: boolean\n /**\n * Verbosity the official client sends when the user has chosen none.\n *\n * Read from the same catalog: every model the backend currently lists declares\n * `default_verbosity: \"low\"`, so \"follow the provider\" means low — not the\n * server's own (medium) fallback, which is what omitting the field gets.\n */\n defaultOutputVerbosity?: CodexOutputVerbosity\n /** Output cap when the caller omits one; falls back to {@link CODEX_DEFAULT_MAX_TOKENS}. */\n maxTokens?: number\n fallbackModelId?: string\n}\n\nexport const CODEX_MODEL_CATALOG = [\n {\n id: 'gpt-5.6-sol',\n name: '5.6 Sol',\n contextWindow: 272_000,\n inputModalities: ['text', 'image'],\n defaultReasoningEffort: 'medium',\n reasoningProfile: 'gpt-5.6',\n supportsReasoningSummary: true,\n fallbackModelId: 'gpt-5.6-terra',\n supportsOutputVerbosity: true,\n defaultOutputVerbosity: 'low',\n },\n {\n id: 'gpt-6-astra',\n name: '6 Astra',\n contextWindow: GPT_6_DEFAULT_CONTEXT_WINDOW,\n inputModalities: ['text', 'image'],\n defaultReasoningEffort: 'medium',\n reasoningProfile: 'gpt-6',\n supportsReasoningSummary: true,\n maxTokens: GPT_6_MAX_TOKENS,\n supportsOutputVerbosity: true,\n defaultOutputVerbosity: 'low',\n },\n {\n id: 'gpt-6.1-sol',\n name: '6.1 Sol',\n contextWindow: GPT_6_DEFAULT_CONTEXT_WINDOW,\n inputModalities: ['text', 'image'],\n defaultReasoningEffort: 'medium',\n reasoningProfile: 'gpt-6',\n supportsReasoningSummary: true,\n maxTokens: GPT_6_MAX_TOKENS,\n supportsOutputVerbosity: true,\n defaultOutputVerbosity: 'low',\n },\n {\n id: 'gpt-6-sol',\n name: '6 Sol',\n contextWindow: GPT_6_DEFAULT_CONTEXT_WINDOW,\n inputModalities: ['text', 'image'],\n defaultReasoningEffort: 'medium',\n reasoningProfile: 'gpt-6',\n supportsReasoningSummary: true,\n maxTokens: GPT_6_MAX_TOKENS,\n supportsOutputVerbosity: true,\n defaultOutputVerbosity: 'low',\n },\n {\n id: 'gpt-6-luna',\n name: '6 Luna',\n contextWindow: GPT_6_DEFAULT_CONTEXT_WINDOW,\n inputModalities: ['text', 'image'],\n defaultReasoningEffort: 'medium',\n reasoningProfile: 'gpt-6',\n supportsReasoningSummary: true,\n maxTokens: GPT_6_MAX_TOKENS,\n supportsOutputVerbosity: true,\n defaultOutputVerbosity: 'low',\n },\n {\n id: 'gpt-5.6-terra',\n name: '5.6 Terra',\n contextWindow: 272_000,\n inputModalities: ['text', 'image'],\n defaultReasoningEffort: 'medium',\n reasoningProfile: 'gpt-5.6',\n supportsReasoningSummary: true,\n fallbackModelId: 'gpt-5.5',\n supportsOutputVerbosity: true,\n defaultOutputVerbosity: 'low',\n },\n {\n id: 'gpt-5.6-luna',\n name: '5.6 Luna',\n contextWindow: 272_000,\n inputModalities: ['text', 'image'],\n defaultReasoningEffort: 'medium',\n reasoningProfile: 'gpt-5.6',\n supportsReasoningSummary: true,\n fallbackModelId: 'gpt-5.5',\n supportsOutputVerbosity: true,\n defaultOutputVerbosity: 'low',\n },\n {\n id: 'gpt-5.5',\n name: '5.5',\n contextWindow: 272_000,\n inputModalities: ['text', 'image'],\n defaultReasoningEffort: 'medium',\n reasoningProfile: 'standard',\n supportsReasoningSummary: true,\n supportsOutputVerbosity: true,\n defaultOutputVerbosity: 'low',\n },\n {\n id: 'gpt-5.4',\n name: '5.4',\n contextWindow: 272_000,\n inputModalities: ['text', 'image'],\n defaultReasoningEffort: 'none',\n reasoningProfile: 'standard',\n supportsReasoningSummary: true,\n fallbackModelId: 'gpt-5.4-mini',\n },\n {\n id: 'gpt-5.4-mini',\n name: '5.4 Mini',\n contextWindow: 272_000,\n inputModalities: ['text', 'image'],\n defaultReasoningEffort: 'none',\n reasoningProfile: 'standard',\n supportsReasoningSummary: true,\n },\n {\n id: 'gpt-5.3-codex-spark',\n name: '5.3 Codex Spark',\n contextWindow: 258_000,\n inputModalities: ['text'],\n defaultReasoningEffort: 'high',\n reasoningProfile: 'standard',\n supportsReasoningSummary: false,\n },\n] as const satisfies readonly CodexModelCatalogEntry[]\n\nexport type CodexModelId = typeof CODEX_MODEL_CATALOG[number]['id']\n\nexport const DEFAULT_VISIBLE_CODEX_MODEL_IDS = [\n 'gpt-6-astra',\n 'gpt-6.1-sol',\n 'gpt-6-sol',\n 'gpt-6-luna',\n 'gpt-5.6-sol',\n 'gpt-5.6-terra',\n 'gpt-5.6-luna',\n] as const satisfies readonly CodexModelId[]\n\nexport const DEFAULT_CODEX_MODEL = CODEX_MODEL_CATALOG[0]\n\nexport const STANDARD_REASONING_EFFORTS = ['none', 'low', 'medium', 'high', 'xhigh'] as const\nexport const GPT_56_REASONING_EFFORTS = [...STANDARD_REASONING_EFFORTS, 'max'] as const\n// Ultra in Codex also controls subagent orchestration; expose the Responses efforts here.\nexport const GPT_6_REASONING_EFFORTS = ['low', 'medium', 'high', 'xhigh', 'max'] as const\nexport type CodexReasoningEffort = typeof GPT_56_REASONING_EFFORTS[number]\n\nexport function reasoningEffortsForModel(model: string): readonly CodexReasoningEffort[] {\n const profile = resolveCodexCatalogEntry(model).reasoningProfile\n if (profile === 'gpt-6') return GPT_6_REASONING_EFFORTS\n return profile === 'gpt-5.6'\n ? GPT_56_REASONING_EFFORTS\n : STANDARD_REASONING_EFFORTS\n}\n\nexport function isCodexReasoningEffort(value: unknown): value is CodexReasoningEffort {\n return typeof value === 'string' && GPT_56_REASONING_EFFORTS.some((effort) => effort === value)\n}\n\nexport function modelSupportsReasoningEffort(model: string, effort: unknown): effort is CodexReasoningEffort {\n return isCodexReasoningEffort(effort) && reasoningEffortsForModel(model).some((candidate) => candidate === effort)\n}\n\nexport function isCodexModelId(model: unknown): model is CodexModelId {\n return typeof model === 'string' && CODEX_MODEL_CATALOG.some((entry) => entry.id === model)\n}\n\n/**\n * Upper bound for one model's context window override. The Codex subscription\n * caps the whole GPT-6 family at 872K and everything older at 1M, so a model's\n * catalog default is where the number starts, not where it has to stay.\n */\nexport function contextWindowLimitForModel(model: CodexModelId): number {\n return resolveCodexCatalogEntry(model).reasoningProfile === 'gpt-6'\n ? GPT_6_MAX_CONTEXT_WINDOW\n : GPT_56_MAX_CONTEXT_WINDOW\n}\n\nexport function resolveCodexCatalogEntry(model: string): CodexModelCatalogEntry {\n return CODEX_MODEL_CATALOG.find((entry) => entry.id === model) ?? DEFAULT_CODEX_MODEL\n}\n\nexport function codexModelSupportsImageInput(model: string): boolean {\n return resolveCodexCatalogEntry(model).inputModalities.includes('image')\n}\n\nexport function codexModelSupportsReasoningSummary(model: string): boolean {\n return resolveCodexCatalogEntry(model).supportsReasoningSummary\n}\n\n/**\n * One catalog entry by exact id, or undefined when this table has no record.\n *\n * Deliberately NOT {@link resolveCodexCatalogEntry}, which answers an unknown id\n * with the default entry: that substitution is the right guide for a model whose\n * capabilities only need a sensible floor, but it cannot tell \"this model\n * declares verbosity support\" apart from \"nobody said\". A wire field must not be\n * invented from silence.\n */\nfunction codexCatalogEntryById(model: string): CodexModelCatalogEntry | undefined {\n return CODEX_MODEL_CATALOG.find((entry) => entry.id === model)\n}\n\n/**\n * Verbosity to send when the user has not chosen one.\n *\n * \"Follow the provider\" has to mean what the provider's own client sends. The\n * official catalog declares `default_verbosity: \"low\"` for every model it\n * lists, so the answer is low — not the server's implicit medium, which is what\n * omitting the field gets.\n *\n * @returns the verbosity to send, or `undefined` to omit the field entirely.\n */\nexport function codexDefaultOutputVerbosity(model: string): CodexOutputVerbosity | undefined {\n const entry = codexCatalogEntryById(model)\n if (entry?.supportsOutputVerbosity !== true) return undefined\n return entry.defaultOutputVerbosity ?? 'low'\n}\n\n/**\n * Declared output ceiling for one model, or the pre-GPT-6 default when it\n * declares none.\n *\n * This is NOT a request field. The subscription Responses endpoint rejects\n * `max_output_tokens` outright (400 Unsupported parameter, issue #29 — and the\n * official CLI's own request struct has no such field), so nothing is sent to\n * the wire from here. The value reaches DSH only as the adapter's\n * `defaultMaxTokens`, which compaction uses as a local completion reservation\n * when it plans a fold; that number never leaves this process.\n */\nexport function codexModelMaxTokens(model: string): number {\n return resolveCodexCatalogEntry(model).maxTokens ?? CODEX_DEFAULT_MAX_TOKENS\n}\n\n/**\n * The effort the Responses wire accepts for one model. The GPT-6 family dropped\n * `none`/`minimal`, so a request that still carries one — a session started on an\n * older model, or the `none` default of a model this route no longer offers — is\n * sent as `low` instead of being rejected.\n */\nexport function codexWireReasoningEffort(model: string, effort: string): string {\n if (resolveCodexCatalogEntry(model).reasoningProfile !== 'gpt-6') return effort\n return effort === 'none' || effort === 'minimal' ? 'low' : effort\n}\n\nexport function resolveCodexFallbackModel(model: string): CodexModelCatalogEntry | undefined {\n const entry = resolveCodexCatalogEntry(model)\n if (!entry.fallbackModelId) return undefined\n return CODEX_MODEL_CATALOG.find((cand) => cand.id === entry.fallbackModelId)\n}\n","import { ROUTE_PREFIX } from '../compat.ts'\nimport type {\n ApiEnvelope,\n LoginEventDto,\n LoginStartDto,\n PluginStatusDto,\n QuotaStatusDto,\n ConnectionTestDto,\n SubscriptionPreferencesDto,\n SubscriptionPreferencesUpdateDto,\n} from '../shared/contracts.ts'\n\nexport class SubscriptionApi {\n status(): Promise<PluginStatusDto> {\n return request<PluginStatusDto>(`${ROUTE_PREFIX}/status`)\n }\n\n startLogin(): Promise<LoginStartDto> {\n return post<LoginStartDto>(`${ROUTE_PREFIX}/login/start`, {})\n }\n\n cancelLogin(loginId: string): Promise<{ cancelled: boolean }> {\n return post(`${ROUTE_PREFIX}/login/cancel`, { loginId })\n }\n\n /** Sign out one pooled account; without an id, the active one. */\n logout(accountId?: string): Promise<{ authenticated: false }> {\n return post(`${ROUTE_PREFIX}/logout`, accountId === undefined ? {} : { accountId })\n }\n\n /**\n * One account-pool action, returning the refreshed status.\n *\n * The host answers with the same envelope the status route uses, so the card\n * never has to guess what the pool looks like after a change.\n */\n accountAction(action: 'set-primary' | 'set-alias' | 'delete' | 'clear-cooldown' | 'strategy' | 'relogin', body: { accountId?: string; alias?: string; strategy?: string } = {}): Promise<PluginStatusDto> {\n return post<PluginStatusDto>(`${ROUTE_PREFIX}/accounts`, { action, ...body })\n }\n\n /**\n * Import this machine's Codex CLI sign-in, answering with the refreshed status.\n *\n * The body names the source rather than the URL carrying it, so the host can\n * refuse a sign-in it does not import with a sentence instead of a silent\n * no-op. The type is 'codex' alone on purpose: Claude Code and MiniMax Code are\n * imported from their own provider settings, and a union here would invite a\n * call the host always answers with a 400.\n */\n adoptLocalLogin(source: 'codex'): Promise<PluginStatusDto> {\n return post<PluginStatusDto>(`${ROUTE_PREFIX}/adopt`, { source })\n }\n\n /** Forget every imported snapshot. The CLIs' own files are never touched. */\n disableAdoptedLocalLogins(): Promise<PluginStatusDto> {\n return post<PluginStatusDto>(`${ROUTE_PREFIX}/adopt/disable`, {})\n }\n\n refresh(): Promise<PluginStatusDto> {\n return post(`${ROUTE_PREFIX}/token/refresh`, {})\n }\n\n refreshQuota(): Promise<QuotaStatusDto> {\n return post(`${ROUTE_PREFIX}/quota/refresh`, {})\n }\n\n useResetCredit(): Promise<QuotaStatusDto> {\n return post(`${ROUTE_PREFIX}/quota/reset-credit/use`, {})\n }\n\n testConnection(): Promise<ConnectionTestDto> {\n return post(`${ROUTE_PREFIX}/connection/test`, {})\n }\n\n updatePreferences(patch: SubscriptionPreferencesUpdateDto): Promise<SubscriptionPreferencesDto> {\n return post(`${ROUTE_PREFIX}/preferences/update`, patch)\n }\n\n events(loginId: string): EventSource {\n return new EventSource(`${ROUTE_PREFIX}/login/events?loginId=${encodeURIComponent(loginId)}`)\n }\n}\n\nasync function post<T>(url: string, body: object): Promise<T> {\n return request<T>(url, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(body),\n })\n}\n\nasync function request<T>(url: string, init?: RequestInit): Promise<T> {\n const response = await fetch(url, { ...init, credentials: 'same-origin' })\n const envelope = await response.json() as ApiEnvelope<T>\n if (!response.ok || !envelope.ok) {\n throw new Error(envelope.ok ? `Request failed (${response.status})` : envelope.error.message)\n }\n return envelope.value\n}\n\nexport function parseLoginEvent(event: MessageEvent<string>): LoginEventDto | null {\n try {\n const value = JSON.parse(event.data) as LoginEventDto\n return typeof value === 'object' && value !== null && typeof value.type === 'string' ? value : null\n } catch {\n return null\n }\n}\n","/**\n * The quota block that lives INSIDE one account row.\n *\n * Quota follows the account: a rotation decides which account spends the next\n * request, so a line-level quota figure describes whichever account happened to\n * be active when it was read. The host therefore reports each account's own\n * newest snapshot on that account's summary, and this renders it where the\n * account is — beside its alias, its cooldown and its last-used time.\n *\n * Every line disagrees about the wire (buckets, groups, meters, ISO strings,\n * unix seconds, remaining fractions) and agrees about the shape the host\n * normalizes into: a labeled window, a consumed share, and usually a moment it\n * reopens. Nothing here fetches: an account whose quota was never read shows\n * that it was never read, which is a different statement from \"nothing used\".\n */\nimport type { PoolAccountQuotaDto, PoolAccountQuotaWindowDto } from '../../shared/account-pool-contracts.ts'\nimport { formatPoolLabel, type AccountPoolLabels } from './account-pool-labels.ts'\n\n/** The label keys this block needs, all of them already on every tab's set. */\nexport type AccountQuotaLabels = Pick<\n AccountPoolLabels,\n 'accountQuota' | 'quotaNone' | 'quotaSnapshot' | 'quotaResets' | 'quotaExhausted' | 'quotaWindow' | 'quotaUsed'\n>\n\n/**\n * Percent with at most one decimal.\n *\n * A share that is not a finite number renders as `0%` rather than `NaN%`. Every\n * caller has already tested `Number.isFinite` and skips the row, so this is the\n * last line of defence, not a claim about an unmeasured window.\n */\nexport function formatQuotaPercent(value: number): string {\n if (!Number.isFinite(value)) return '0%'\n try {\n return `${new Intl.NumberFormat(undefined, { maximumFractionDigits: 1 }).format(value)}%`\n } catch {\n return `${value}%`\n }\n}\n\n/**\n * When a window reopens, in the reader's own words.\n *\n * Always a distance. The page's own quota block counts down (\"7天 3时\"), and a\n * row that switched to an absolute date past a threshold described the same\n * window two different ways inside one card. Days carry a long window, hours\n * the short ones, minutes the last stretch.\n */\nexport function formatQuotaReset(resetsAt: number | null | undefined, now = Date.now()): string {\n if (typeof resetsAt !== 'number' || !Number.isFinite(resetsAt) || resetsAt <= now) return '—'\n const deltaMinutes = Math.round((resetsAt - now) / 60_000)\n try {\n const relative = new Intl.RelativeTimeFormat(undefined, { numeric: 'auto' })\n if (deltaMinutes < 60) return relative.format(deltaMinutes, 'minute')\n if (deltaMinutes < 36 * 60) return relative.format(Math.round(deltaMinutes / 60), 'hour')\n return relative.format(Math.round(deltaMinutes / 1440), 'day')\n } catch {\n return '—'\n }\n}\n\n/**\n * When the snapshot was read.\n *\n * A time alone reads as \"just now\" — which is a lie about a snapshot taken\n * yesterday, and the card's whole promise is that this is what we last saw.\n */\nexport function formatQuotaSnapshot(fetchedAt: number, now = Date.now()): string {\n try {\n const sameDay = new Date(fetchedAt).toDateString() === new Date(now).toDateString()\n return new Intl.DateTimeFormat(undefined, sameDay\n ? { timeStyle: 'short' }\n : { dateStyle: 'short', timeStyle: 'short' }).format(fetchedAt)\n } catch {\n return '—'\n }\n}\n\n/** A window's name: the line's own label, else its length, else a generic one. */\nexport function quotaWindowLabel(window: PoolAccountQuotaWindowDto, labels: AccountQuotaLabels): string {\n if (window.label !== '') return window.label\n const minutes = window.windowDurationMins\n if (typeof minutes !== 'number' || !Number.isFinite(minutes) || minutes <= 0) return labels.quotaWindow\n const [value, unit]: [number, Intl.NumberFormatOptions['unit']] = minutes % 1440 === 0\n ? [minutes / 1440, 'day']\n : minutes % 60 === 0 ? [minutes / 60, 'hour'] : [Math.round(minutes), 'minute']\n try {\n return new Intl.NumberFormat(undefined, { style: 'unit', unit, unitDisplay: 'long' }).format(value)\n } catch {\n return `${value} ${unit}`\n }\n}\n\nfunction levelFor(usedPercent: number): 'normal' | 'warning' | 'danger' {\n return usedPercent >= 95 ? 'danger' : usedPercent >= 80 ? 'warning' : 'normal'\n}\n\n/**\n * One account's quota, or the honest statement that none was ever read.\n *\n * `showEmpty` lets the hosting card stay quiet on a line that has no quota to\n * speak of, while still saying \"not read yet\" for an account the line does read\n * (its active one, or any account once a sibling has a snapshot).\n */\nexport function AccountQuota(props: {\n quota: PoolAccountQuotaDto | undefined\n labels: AccountQuotaLabels\n /** True to render the \"no quota read yet\" line instead of nothing. */\n showEmpty: boolean\n now?: number\n}): React.JSX.Element | null {\n const { quota, labels } = props\n if (quota === undefined) {\n return props.showEmpty\n ? <div className=\"dsha-account-quota\"><span className=\"dsha-account-quota-empty\">{labels.quotaNone}</span></div>\n : null\n }\n const now = props.now ?? Date.now()\n return <div className=\"dsha-account-quota\">\n <span className=\"dsha-account-quota-head\">\n {labels.accountQuota}\n {quota.fetchedAt > 0 && (\n <em>{formatPoolLabel(labels.quotaSnapshot, { time: formatQuotaSnapshot(quota.fetchedAt, now) })}</em>\n )}\n </span>\n {quota.windows.length === 0\n ? <span className=\"dsha-account-quota-empty\">{labels.quotaNone}</span>\n : quota.windows.map((window, index) => {\n const percent = Number.isFinite(window.usedPercent) ? window.usedPercent : 0\n const label = quotaWindowLabel(window, labels)\n const reset = formatQuotaReset(window.resetsAt, now)\n return <div key={`${label}:${index}`} className=\"dsha-account-quota-row\" data-level={levelFor(percent)}>\n <span className=\"dsha-account-quota-name\" title={label}>{label}</span>\n <span\n className=\"dsha-account-quota-track\"\n role=\"progressbar\"\n aria-label={`${label}: ${formatQuotaPercent(percent)} ${labels.quotaUsed}`}\n aria-valuemin={0}\n aria-valuemax={100}\n aria-valuenow={percent}\n >\n <i className=\"dsha-account-quota-fill\" style={{ width: `${Math.min(100, Math.max(0, percent))}%` }} />\n </span>\n <span className=\"dsha-account-quota-value\">\n {percent >= 100 ? labels.quotaExhausted : formatQuotaPercent(percent)}\n </span>\n <span className=\"dsha-account-quota-meta\">{reset === '—' ? '—' : `${labels.quotaResets} ${reset}`}</span>\n </div>\n })}\n </div>\n}\n","import React, { type ReactNode } from 'react'\nimport type {\n AccountPoolStatusDto,\n AccountRotationStrategy,\n PoolAccountSummaryDto,\n} from '../../shared/account-pool-contracts.ts'\nimport { formatPoolLabel, type AccountPoolLabels } from './account-pool-labels.ts'\nimport { AccountQuota } from './account-quota.tsx'\n\nexport type { AccountPoolLabels } from './account-pool-labels.ts'\n\nexport interface AccountPoolSectionProps<\n TAccount extends PoolAccountSummaryDto = PoolAccountSummaryDto,\n> extends Omit<Pick<AccountPoolStatusDto, 'activeAccountId' | 'rotationStrategy'>, 'accounts'> {\n accounts: TAccount[]\n /** Label set of the hosting tab; see {@link AccountPoolLabels}. */\n labels: AccountPoolLabels\n /** Action currently in flight, used to disable every control at once. */\n busy: string | null\n /** Overrides the login button text while a sign-in flow is running. */\n loginBusyLabel?: string\n onLogin(): void\n /**\n * Replaces the single header button with the provider's own entry points.\n *\n * WorkBuddy signs in against two regional deployments, so one \"add account\"\n * button cannot express it; every other line keeps the default button.\n */\n renderLoginActions?(): ReactNode\n onSetPrimary(accountId: string): void\n onDelete(accountId: string): void\n onClearCooldown(accountId: string): void\n /** Offered on an account whose credential no longer authenticates. */\n onRelogin?(accountId: string): void\n onSetStrategy(strategy: AccountRotationStrategy): void\n /** Provider-specific detail rows, rendered before the shared ones. */\n renderDetails?(account: TAccount): ReactNode\n /**\n * Whether this line has a quota concept at all.\n *\n * Quota follows the account, so an account the host never read shows \"no\n * quota read yet\" instead of nothing — but only on a line that reads quota in\n * the first place. A line without one (Ollama: spend, no allowance) leaves\n * this off and its rows stay silent about quota.\n */\n showQuota?: boolean\n /**\n * Provider-specific per-account buttons, rendered before the shared ones.\n *\n * Used by a line that adopts accounts it does not own: hiding or restoring\n * an externally-managed account replaces the delete it must never offer.\n */\n renderAccountActions?(account: TAccount): ReactNode\n /** Extra controls inside the group, after the account list. */\n children?: ReactNode\n}\n\n/** Format one account timestamp the way every tab renders it. */\nexport function formatAccountDate(ms?: number): string {\n if (!ms || ms <= 0) return '—'\n try {\n return new Intl.DateTimeFormat(undefined, { dateStyle: 'medium', timeStyle: 'short' }).format(ms)\n } catch {\n return '—'\n }\n}\n\n/** Whole minutes left in a cooldown, never below one. */\nexport function cooldownMinutesLeft(cooldownUntil: number, now = Date.now()): number {\n return Math.max(1, Math.ceil((cooldownUntil - now) / 60_000))\n}\n\n/** Whether one account currently carries a live 429 cooldown. */\nexport function isCoolingDown(account: PoolAccountSummaryDto, now = Date.now()): boolean {\n return typeof account.cooldownUntil === 'number' && account.cooldownUntil > now\n}\n\n/**\n * The account-management group every provider tab renders.\n *\n * One component rather than four near-identical blocks: the account card, its\n * badges and the rotation-strategy picker are identical across providers, and\n * only the identity details differ.\n *\n * Credential storage is deliberately NOT shown here. Where the host keeps a\n * token is not a setting a user can act on, and rendering it as a labeled row\n * invited exactly that reading; several lines' notices went further and printed\n * the credential file's path.\n */\nexport function AccountPoolSection<TAccount extends PoolAccountSummaryDto = PoolAccountSummaryDto>(\n props: AccountPoolSectionProps<TAccount>,\n): React.ReactElement {\n const t = props.labels\n const accounts = props.accounts\n const now = Date.now()\n // One sibling holding a snapshot proves the line reads quota per account, so\n // the accounts it has not read yet may say so. Without this, a line that has\n // no quota concept would grow a row of \"not read yet\" on every account.\n const anyQuota = accounts.some((account) => account.quota !== undefined)\n\n return (\n <section className=\"dsha-group\">\n <div className=\"dsha-grouphead\">\n <h3>\n {t.accountPool}\n {accounts.length > 0 && (\n <span className=\"dsha-muted\" style={{ fontWeight: 400, marginLeft: 8 }}>\n ({formatPoolLabel(t.accountCount, { count: accounts.length })})\n </span>\n )}\n </h3>\n {props.renderLoginActions !== undefined ? props.renderLoginActions() : (\n <button className=\"dsha-btn dsha-btn-primary\" disabled={props.busy !== null} onClick={props.onLogin}>\n {props.loginBusyLabel || t.addAccount}\n </button>\n )}\n </div>\n\n {accounts.length > 1 && (\n <div className=\"dsha-pref-row\">\n <div>\n <strong>{t.rotationStrategy}</strong>\n <p className=\"dsha-muted\" style={{ fontSize: 12, marginTop: 2 }}>\n {props.rotationStrategy === 'round-robin'\n ? t.strategyRoundRobin\n : props.rotationStrategy === 'sticky' ? t.strategySticky : t.strategySequential}\n </p>\n </div>\n <select\n className=\"dsha-select\"\n aria-label={t.rotationStrategy}\n value={props.rotationStrategy}\n disabled={props.busy !== null}\n onChange={(event) => props.onSetStrategy(event.target.value as AccountRotationStrategy)}\n >\n <option value=\"sequential\">顺序耗尽</option>\n <option value=\"round-robin\">轮询调度</option>\n <option value=\"sticky\">粘性会话</option>\n </select>\n </div>\n )}\n\n {accounts.length === 0 ? (\n <div className=\"dsha-empty\">{t.noAccounts}</div>\n ) : (\n <div className=\"dsha-accounts-list\">\n {accounts.map((account) => {\n const isActive = account.id === props.activeAccountId\n const cooling = isCoolingDown(account, now)\n const needsRelogin = account.authStatus !== undefined && account.authStatus !== 'ok'\n return (\n <div key={account.id} className={`dsha-account-card ${isActive ? 'active' : ''}`}>\n <div className=\"dsha-account-header\">\n <div className=\"dsha-account-identity\">\n <span className=\"dsha-account-title\">{account.alias || account.email || account.id}</span>\n <div className=\"dsha-badges\">\n {account.isPrimary && <span className=\"dsha-badge primary\">{t.primaryAccount}</span>}\n {isActive && <span className=\"dsha-badge active\">{t.activeAccount}</span>}\n {cooling && (\n <span className=\"dsha-badge cooldown\">\n {t.cooling}({formatPoolLabel(t.cooldownLeft, { minutes: cooldownMinutesLeft(account.cooldownUntil!, now) })})\n </span>\n )}\n {needsRelogin && <span className=\"dsha-badge danger\">{t.needsRelogin}</span>}\n </div>\n </div>\n <div className=\"dsha-account-actions\">\n {props.renderAccountActions?.(account)}\n {!account.isPrimary && (\n <button\n className=\"dsha-btn\"\n disabled={props.busy !== null}\n onClick={() => props.onSetPrimary(account.id)}\n >\n {t.setPrimary}\n </button>\n )}\n {cooling && (\n <button\n className=\"dsha-btn\"\n disabled={props.busy !== null}\n onClick={() => props.onClearCooldown(account.id)}\n >\n {t.clearCooldown}\n </button>\n )}\n {needsRelogin && props.onRelogin && (\n <button\n className=\"dsha-btn\"\n disabled={props.busy !== null}\n onClick={() => props.onRelogin!(account.id)}\n >\n {t.relogin}\n </button>\n )}\n {/* An account this plugin does not own must never be\n destroyed from here; its line supplies the action. */}\n {account.removable !== false && (\n <button\n className=\"dsha-btn\"\n disabled={props.busy !== null}\n onClick={() => props.onDelete(account.id)}\n >\n {t.deleteAccount}\n </button>\n )}\n </div>\n </div>\n\n <div className=\"dsha-account-details\">\n {/* The line's own facts first, then the shared ones. Neither\n repeats the card's title: on most lines the alias IS the\n address, so printing \"邮箱: <same address>\" under a title\n that already reads as that address is the same fact twice.\n The same rule is why no line's renderDetails may render\n e-mail, expiry or last-used itself. */}\n {props.renderDetails?.(account)}\n {account.email !== undefined && account.email !== account.alias\n && <span>{t.email}: {account.email}</span>}\n {account.expiresAt !== undefined && <span>{t.expires}: {formatAccountDate(account.expiresAt)}</span>}\n {account.lastUsedAt !== undefined && <span>{t.lastUsed}: {formatAccountDate(account.lastUsedAt)}</span>}\n </div>\n <AccountQuota\n quota={account.quota}\n labels={t}\n showEmpty={props.showQuota === true || anyQuota}\n now={now}\n />\n {needsRelogin && account.authFailedReason && (\n <div className=\"dsha-account-details\">\n <span>{account.authFailedReason}</span>\n </div>\n )}\n </div>\n )\n })}\n </div>\n )}\n\n {props.children}\n </section>\n )\n}\n","/**\n * The shared \"which models appear in the picker\" list every provider section\n * renders.\n *\n * The visual language follows the claude-style model picker: one row per\n * model — vendor mark, name, a single quiet hint line (context window when\n * the catalog carries one) — with the selection state drawn as a trailing\n * check dot instead of a bare checkbox. Unlike the picker this list is\n * multi-select, so rows are `role=\"checkbox\"` and the header carries the\n * select-all / clear-all pair the old checkbox blocks had.\n *\n * One component rather than eight near-identical blocks: sections differ only\n * in where the items come from and which dictionary supplies the labels.\n */\nimport { BrandMark, modelBrandMark } from '../hub/brand-icons.tsx'\n\nexport interface ModelChecklistItem {\n id: string\n name: string\n /** One quiet line under the name (e.g. the context window); omit when none. */\n hint?: string\n enabled: boolean\n}\n\nexport interface ModelChecklistLabels {\n selectAll: string\n clearAll: string\n /**\n * `{count}` and `{total}` are replaced with the enabled/total numbers.\n * Optional: a provider dictionary without the key gets the bare \"3/8\" form.\n */\n countTemplate?: string\n /** aria-label of the list itself; omit when the section header already names it. */\n list?: string\n}\n\ninterface Props {\n items: ModelChecklistItem[]\n /** Disables every row and the header buttons while a commit is in flight. */\n busy: boolean\n onToggle(id: string, enabled: boolean): void\n onToggleAll(enabled: boolean): void\n labels: ModelChecklistLabels\n}\n\nconst CHECK_SVG = '<svg viewBox=\"0 0 16 16\" width=\"11\" height=\"11\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M3 8.5l3.2 3.2L13 5\"/></svg>'\n\nexport function ModelChecklist({ items, busy, onToggle, onToggleAll, labels }: Props): React.JSX.Element {\n const enabledCount = items.filter((item) => item.enabled).length\n const count = (labels.countTemplate ?? '{count}/{total}')\n .replace('{count}', String(enabledCount))\n .replace('{total}', String(items.length))\n return <div className=\"dsh-mcl\">\n <div className=\"dsh-mcl-head\">\n <span className=\"dsh-mcl-count\">{count}</span>\n <span className=\"dsh-mcl-head-actions\">\n <button type=\"button\" className=\"dsh-mcl-action\" disabled={busy || enabledCount === items.length} onClick={() => onToggleAll(true)}>{labels.selectAll}</button>\n <button type=\"button\" className=\"dsh-mcl-action\" disabled={busy || enabledCount === 0} onClick={() => onToggleAll(false)}>{labels.clearAll}</button>\n </span>\n </div>\n <div className=\"dsh-mcl-list\" role=\"group\" aria-label={labels.list}>\n {items.map((item) => {\n const mark = modelBrandMark(item.id)\n return <button\n key={item.id}\n type=\"button\"\n role=\"checkbox\"\n aria-checked={item.enabled}\n className=\"dsh-mcl-option\"\n data-enabled={item.enabled}\n disabled={busy}\n title={item.id}\n onClick={() => onToggle(item.id, !item.enabled)}\n >\n {mark !== null ? <BrandMark mark={mark} size={18} /> : null}\n <span className=\"dsh-mcl-copy\">\n <span className=\"dsh-mcl-name\">{item.name}</span>\n {item.hint !== undefined ? <span className=\"dsh-mcl-hint\">{item.hint}</span> : null}\n </span>\n <span className=\"dsh-mcl-check\" aria-hidden=\"true\" dangerouslySetInnerHTML={{ __html: item.enabled ? CHECK_SVG : '' }} />\n </button>\n })}\n </div>\n </div>\n}\n","/**\n * One follow-up poll after a status answer that carried a background refresh.\n *\n * The host answers a status card from the snapshot it already has and refreshes\n * the quota behind that answer, so a tab renders immediately instead of waiting\n * on the upstream request. The refreshed numbers would otherwise only appear on\n * the next 60 s poll, so an answer that reports a refresh in flight schedules\n * one short follow-up.\n *\n * The chain is bounded. A refresh that keeps failing leaves the snapshot aged,\n * so every answer would keep asking for a follow-up; after a few consecutive\n * attempts the surface falls back to its ordinary polling and stops hammering\n * the host.\n */\n\nconst FOLLOW_UP_DELAY_MS = 1_500\nconst MAX_ATTEMPTS = 3\n\nexport interface QuotaFollowUp {\n /**\n * Record one status answer.\n *\n * @param refreshing - whether the host reported a refresh behind this answer.\n * @param reload - how to ask again; used only when a follow-up is owed.\n */\n observe(refreshing: boolean, reload: () => void): void\n /** Drop any pending follow-up; call when the surface unmounts. */\n cancel(): void\n}\n\nexport function createQuotaFollowUp(\n options: { delayMs?: number; maxAttempts?: number } = {},\n): QuotaFollowUp {\n const delayMs = options.delayMs ?? FOLLOW_UP_DELAY_MS\n const maxAttempts = options.maxAttempts ?? MAX_ATTEMPTS\n let attempts = 0\n let timer: ReturnType<typeof setTimeout> | undefined\n\n return {\n observe(refreshing: boolean, reload: () => void): void {\n if (!refreshing) {\n // A settled answer ends the chain, so the next stale answer starts fresh.\n attempts = 0\n return\n }\n // One follow-up at a time: a poll landing while one is pending must not\n // stack another.\n if (timer !== undefined || attempts >= maxAttempts) return\n attempts += 1\n timer = setTimeout(() => {\n timer = undefined\n reload()\n }, delayMs)\n },\n cancel(): void {\n if (timer !== undefined) clearTimeout(timer)\n timer = undefined\n attempts = 0\n },\n }\n}","import { useCallback, useEffect, useRef, useState } from 'react'\nimport type { PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\nimport type { CodexReasoningSummary, PluginStatusDto, QuotaBucketDto, QuotaWindowDto, SearchProviderPreference, SubscriptionPreferencesUpdateDto } from '../shared/contracts.ts'\nimport { CODEX_MODEL_CATALOG, DEFAULT_VISIBLE_CODEX_MODEL_IDS, GPT_56_MAX_CONTEXT_WINDOW, contextWindowLimitForModel, resolveCodexCatalogEntry } from '../shared/model-catalog.ts'\nimport type { CodexModelId } from '../shared/model-catalog.ts'\nimport { SubscriptionApi, parseLoginEvent } from './api.ts'\nimport { AccountPoolSection, type AccountPoolLabels } from './common/AccountPoolSection.tsx'\nimport { formatPoolLabel } from './common/account-pool-labels.ts'\nimport { ModelChecklist } from './common/ModelChecklist.tsx'\nimport { createQuotaFollowUp, type QuotaFollowUp } from './common/quota-follow-up.ts'\nimport type { AccountRotationStrategy } from '../shared/account-pool-contracts.ts'\nimport { NS } from './locales.ts'\nimport { quotaWindows } from './quota.ts'\n\ntype Props = PropsRuntime<'settings.section'> & PropsLocale<typeof NS>\ntype BusyAction = 'login' | 'token' | 'quota' | 'reset-credit' | 'test' | 'logout' | 'preferences'\n | 'set-primary' | 'delete' | 'clear-cooldown' | 'strategy' | 'adopt' | 'adopt-disable' | null\ntype Translate = Props['t']\n\nexport function CodexSubscriptionSection({ t }: Props): React.JSX.Element {\n const apiRef = useRef(new SubscriptionApi())\n const eventSourceRef = useRef<EventSource | null>(null)\n /** Follow-up poll owed while the host refreshes the quota behind an answer. */\n const quotaFollowUp = useRef<QuotaFollowUp | null>(null)\n const [status, setStatus] = useState<PluginStatusDto | null>(null)\n const [busy, setBusy] = useState<BusyAction>(null)\n const [error, setError] = useState<string | null>(null)\n const [authUrl, setAuthUrl] = useState<string | null>(null)\n const [popupBlocked, setPopupBlocked] = useState(false)\n const [resetCreditNotice, setResetCreditNotice] = useState<string | null>(null)\n const [connection, setConnection] = useState<{ latencyMs: number; checkedAt: number } | null>(null)\n const [contextDrafts, setContextDrafts] = useState<Record<string, string>>({})\n const [customProxyDraft, setCustomProxyDraft] = useState<string | null>(null)\n\n const load = useCallback(async (quiet = false) => {\n if (!quiet) setError(null)\n try {\n const next = await apiRef.current.status()\n setStatus(next)\n if (next.error !== undefined) setError(next.error.message)\n // An answer that refreshed the quota behind itself is followed up shortly,\n // so the fresh numbers land without waiting for the next poll.\n quotaFollowUp.current ??= createQuotaFollowUp()\n quotaFollowUp.current.observe(next.quotaRefreshing === true, () => { void load(true) })\n } catch (cause) {\n if (!quiet) setError(messageOf(cause))\n }\n }, [])\n\n useEffect(() => {\n void load()\n const refreshWhenVisible = (): void => {\n if (document.visibilityState === 'visible') void load(true)\n }\n document.addEventListener('visibilitychange', refreshWhenVisible)\n const timer = window.setInterval(refreshWhenVisible, 60_000)\n return () => {\n window.clearInterval(timer)\n document.removeEventListener('visibilitychange', refreshWhenVisible)\n quotaFollowUp.current?.cancel()\n eventSourceRef.current?.close()\n }\n }, [load])\n\n const watchLogin = useCallback((loginId: string) => {\n eventSourceRef.current?.close()\n const source = apiRef.current.events(loginId)\n eventSourceRef.current = source\n const finish = async (message?: string): Promise<void> => {\n source.close()\n eventSourceRef.current = null\n setBusy(null)\n setAuthUrl(null)\n if (message !== undefined) setError(message)\n // Preserve the terminal OAuth error while refreshing the account DTO.\n await load(true)\n }\n source.addEventListener('completed', (event) => {\n const parsed = parseLoginEvent(event as MessageEvent<string>)\n if (parsed?.type === 'completed') void finish()\n })\n source.addEventListener('cancelled', () => void finish())\n source.addEventListener('failed', (event) => {\n const parsed = parseLoginEvent(event as MessageEvent<string>)\n void finish(parsed?.type === 'failed' ? parsed.error.message : 'ChatGPT sign-in failed.')\n })\n }, [load])\n\n useEffect(() => {\n const loginId = status?.login.active ? status.login.loginId : null\n if (loginId !== null && loginId !== undefined && eventSourceRef.current === null) watchLogin(loginId)\n }, [status?.login.active, status?.login.loginId, watchLogin])\n\n const startLogin = async (): Promise<void> => {\n setBusy('login')\n setError(null)\n setPopupBlocked(false)\n const popup = window.open('about:blank', 'dsh-chatgpt-oauth', 'popup,width=560,height=760')\n try {\n const login = await apiRef.current.startLogin()\n setAuthUrl(login.authUrl)\n if (popup === null) setPopupBlocked(true)\n else popup.location.replace(login.authUrl)\n watchLogin(login.loginId)\n await load(true)\n } catch (cause) {\n popup?.close()\n setBusy(null)\n setError(messageOf(cause))\n }\n }\n\n const cancelLogin = async (): Promise<void> => {\n const loginId = status?.login.loginId\n if (loginId === null || loginId === undefined) return\n setBusy('login')\n try {\n await apiRef.current.cancelLogin(loginId)\n eventSourceRef.current?.close()\n eventSourceRef.current = null\n setAuthUrl(null)\n await load()\n } catch (cause) {\n setError(messageOf(cause))\n } finally {\n setBusy(null)\n }\n }\n\n const refreshToken = async (): Promise<void> => run('token', async () => {\n setStatus(await apiRef.current.refresh())\n })\n\n const refreshQuota = async (): Promise<void> => run('quota', async () => {\n const quota = await apiRef.current.refreshQuota()\n setStatus((current) => current === null ? current : { ...current, quota })\n })\n\n const useResetCredit = async (): Promise<void> => {\n if (!window.confirm(t('useResetCreditConfirm'))) return\n await run('reset-credit', async () => {\n const quota = await apiRef.current.useResetCredit()\n setStatus((current) => current === null ? current : { ...current, quota })\n setResetCreditNotice(t('resetCreditUsed'))\n })\n }\n\n const testConnection = async (): Promise<void> => run('test', async () => {\n const result = await apiRef.current.testConnection()\n setConnection({ latencyMs: result.latencyMs, checkedAt: result.checkedAt })\n })\n\n const updatePreferences = async (patch: SubscriptionPreferencesUpdateDto): Promise<void> => run('preferences', async () => {\n const preferences = await apiRef.current.updatePreferences(patch)\n setStatus((current) => current === null ? current : { ...current, preferences })\n })\n\n const selectSearchProvider = (provider: SearchProviderPreference): void => {\n setStatus(current => current ? { ...current, preferences: { ...current.preferences, searchProvider: provider } } : current)\n void updatePreferences({ searchProvider: provider })\n }\n\n const toggleVisibleModel = async (modelId: string, checked: boolean): Promise<void> => {\n const current = status?.preferences.visibleModelIds ?? [...DEFAULT_VISIBLE_CODEX_MODEL_IDS]\n const visibleModelIds = checked ? [...current, modelId] : current.filter(id => id !== modelId)\n await updatePreferences({ visibleModelIds })\n }\n\n const setAllVisibleModels = async (selectAll: boolean): Promise<void> => {\n const visibleModelIds = selectAll ? CODEX_MODEL_CATALOG.map(m => m.id) : []\n await updatePreferences({ visibleModelIds })\n }\n\n const updateContextWindow = async (model: CodexModelId): Promise<void> => {\n const current = status?.preferences.contextWindowOverrides[model] ?? resolveCodexCatalogEntry(model).contextWindow\n const parsed = parseCapacity(contextDrafts[model] ?? String(current), contextWindowLimitForModel(model))\n if (parsed === null) {\n setError(t('contextWindowInvalid'))\n return\n }\n await updatePreferences({ contextWindowOverrides: { [model]: parsed } })\n setContextDrafts((drafts) => ({ ...drafts, [model]: String(parsed) }))\n }\n\n /** Drop one model's override; the row falls back to the catalog value. */\n const resetContextWindow = async (model: CodexModelId): Promise<void> => {\n await updatePreferences({ contextWindowOverrides: { [model]: null } })\n setContextDrafts((drafts) => ({ ...drafts, [model]: formatCapacity(resolveCodexCatalogEntry(model).contextWindow) }))\n }\n\n /** Clear every stored override, including models the picker no longer shows. */\n const resetAllContextWindows = async (): Promise<void> => {\n const models = Object.keys(status?.preferences.contextWindowOverrides ?? {})\n if (models.length === 0) return\n if (!window.confirm(t('contextWindowResetAllConfirm'))) return\n await updatePreferences({ contextWindowOverrides: Object.fromEntries(models.map((model) => [model, null])) })\n setContextDrafts({})\n }\n\n const updateCustomProxyUrl = async (): Promise<void> => {\n const draft = customProxyDraft?.trim()\n await updatePreferences({ customProxyUrl: draft ? draft : null })\n setCustomProxyDraft(null)\n }\n\n /**\n * The shared card takes a label object while this tab translates by key, so\n * every pool label is resolved through the tab's own translator and follows\n * whichever locale is active.\n */\n const poolLabels: AccountPoolLabels = {\n accountPool: t('accountPool'),\n addAccount: t('addAccount'),\n accountCount: t('accountCount'),\n primaryAccount: t('primaryAccount'),\n activeAccount: t('activeAccount'),\n setPrimary: t('setPrimary'),\n deleteAccount: t('deleteAccount'),\n cooling: t('cooling'),\n cooldownLeft: t('cooldownLeft'),\n clearCooldown: t('clearCooldown'),\n needsRelogin: t('needsRelogin'),\n relogin: t('relogin'),\n rotationStrategy: t('rotationStrategy'),\n strategySequential: t('strategySequential'),\n strategyRoundRobin: t('strategyRoundRobin'),\n strategySticky: t('strategySticky'),\n noAccounts: t('noAccounts'),\n email: t('email'),\n expires: t('expires'),\n lastUsed: t('lastUsed'),\n accountId: t('accountId'),\n accountQuota: t('accountQuota'),\n quotaNone: t('quotaNone'),\n quotaSnapshot: t('quotaSnapshot'),\n quotaResets: t('quotaResets'),\n quotaExhausted: t('quotaExhausted'),\n quotaWindow: t('quotaWindow'),\n quotaUsed: t('quotaUsed'),\n quotaFactsScope: t('quotaFactsScope'),\n composerLabel: t('composerLabel'),\n }\n\n const accountAction = async (\n action: 'set-primary' | 'delete' | 'clear-cooldown',\n accountId: string,\n ): Promise<void> => {\n await run(action, async () => {\n const next = await apiRef.current.accountAction(action, { accountId })\n setStatus(next)\n })\n }\n\n /**\n * Forget every imported snapshot: the undo for the local sign-in import below.\n *\n * ONE control for the whole pool rather than one per row, because the host's\n * route deliberately ignores an accountId and clears every imported row at once.\n * That is not an oversight to route around: the pool refuses to delete an\n * adopted credential, so a per-row control here could only ever be a button that\n * silently clears its neighbours — a worse bug than offering no button at all.\n * The Codex CLI's own file is not deleted, rewritten or moved by this; it only\n * makes this plugin forget the copy it took.\n */\n const stopImporting = async (): Promise<void> => {\n await run('adopt-disable', async () => {\n setStatus(await apiRef.current.disableAdoptedLocalLogins())\n })\n }\n\n /**\n * Copy this machine's Codex CLI sign-in into the pool as a snapshot.\n *\n * The status is re-read rather than taken from the route's answer: the route\n * answers with the pool's refreshed status, which knows nothing about the\n * CLI file, so adopting from its value would flip the block to \"not detected\"\n * one click after the import succeeded. The file is still there — the import\n * copies it — so /status is the answer that tells the truth, and the row the\n * account just created comes back with it.\n */\n const importLocalSignIn = async (): Promise<void> => {\n await run('adopt', async () => {\n await apiRef.current.adoptLocalLogin('codex')\n await load(true)\n })\n }\n\n const setRotationStrategy = async (strategy: AccountRotationStrategy): Promise<void> => {\n await run('strategy', async () => {\n const next = await apiRef.current.accountAction('strategy', { strategy })\n setStatus(next)\n })\n }\n\n /**\n * Re-authorize one account.\n *\n * The failure marker is cleared first and nothing is deleted: the account\n * keeps its alias and place in the rotation.\n */\n const relogin = (accountId: string): void => {\n void (async () => {\n try {\n const next = await apiRef.current.accountAction('relogin', { accountId })\n setStatus(next)\n } catch (cause) {\n setError(messageOf(cause))\n return\n }\n await startLogin()\n })()\n }\n\n const logout = async (): Promise<void> => run('logout', async () => {\n await apiRef.current.logout()\n eventSourceRef.current?.close()\n eventSourceRef.current = null\n setAuthUrl(null)\n setConnection(null)\n await load()\n })\n\n const run = async (action: Exclude<BusyAction, null>, task: () => Promise<void>): Promise<void> => {\n setBusy(action)\n setError(null)\n setResetCreditNotice(null)\n try {\n await task()\n } catch (cause) {\n setError(messageOf(cause))\n } finally {\n setBusy(null)\n }\n }\n\n // `removable: false` is the shared summary DTO's own signal for a borrowed\n // credential (it is what suppresses Delete on the shared card). The Codex pool\n // also puts an `adopted` flag on the wire, but that field is not in the shared\n // contract this tab is typed against, so the declared one is what is read.\n const importedAccounts = (status?.accounts ?? []).filter((account) => account.removable === false)\n const account = status?.account\n const preferences = status?.preferences\n const quota = status?.quota\n const login = status?.login\n const visibleModelIds = preferences?.visibleModelIds ?? DEFAULT_VISIBLE_CODEX_MODEL_IDS\n // Only checked models get a context row, in catalog order.\n const contextModels = CODEX_MODEL_CATALOG.filter((entry) => visibleModelIds.some((id) => id === entry.id))\n const overrideCount = Object.keys(preferences?.contextWindowOverrides ?? {}).length\n return <section className=\"dsha-page\" aria-labelledby=\"dsh-codex-title\">\n <header>\n <h2 id=\"dsh-codex-title\" className=\"dsh-codex-title\">{t('title')}</h2>\n <p className=\"dsh-codex-intro\">{t('intro')}</p>\n </header>\n\n {error !== null ? <div className=\"dsh-codex-errorbar\" role=\"alert\">\n <span>{error}</span>\n {status === null ? <Button disabled={busy !== null} onClick={() => load()}>{t('retry')}</Button> : null}\n </div> : null}\n\n {status === null && error === null ? <Skeleton label={t('loading')} /> : <>\n <AccountPoolSection\n accounts={status?.accounts ?? []}\n activeAccountId={status?.activeAccountId}\n rotationStrategy={status?.rotationStrategy ?? 'sequential'}\n busy={busy}\n labels={poolLabels}\n loginBusyLabel={login?.active ? t('pending') : undefined}\n onLogin={() => void startLogin()}\n onSetPrimary={(accountId) => void accountAction('set-primary', accountId)}\n onDelete={(accountId) => void accountAction('delete', accountId)}\n onClearCooldown={(accountId) => void accountAction('clear-cooldown', accountId)}\n onRelogin={(accountId) => relogin(accountId)}\n onSetStrategy={(strategy) => void setRotationStrategy(strategy)}\n showQuota\n renderLoginActions={() => (\n // The pool card's own login row, in the shape the Claude section uses:\n // the sign-in keeps the primary treatment, and a sign-in that already\n // exists on this machine sits beside it as the alternative way in.\n //\n // The first button REPRODUCES the shared card's default login button\n // (same classes, same label, same disable rule), because taking the row\n // over means reproducing it — nothing about signing in changes here.\n <div className=\"dsha-account-add-actions\">\n <button\n className=\"dsha-btn dsha-btn-primary\"\n disabled={busy !== null}\n onClick={() => void startLogin()}\n >\n {login?.active ? t('pending') : t('addAccount')}\n </button>\n {/* The second entry: a local Codex CLI sign-in can be imported instead\n of running a fresh ChatGPT OAuth flow.\n\n ALWAYS RENDERED, exactly as the Claude section renders its own —\n including when the host found no sign-in, which is the decision\n stated here rather than left to drift: a button that DISAPPEARS\n when there is nothing to import cannot answer whether one exists,\n and \"is my CLI signed in here?\" is the question this row is here to\n answer. Clicking it with nothing there is not a dead end and needs\n no substitute prose: the host refuses in a sentence, and that\n sentence lands in the card's existing error strip. */}\n <button\n className=\"dsha-btn\"\n disabled={busy !== null}\n aria-label={t('localCodexLoginImport')}\n onClick={() => void importLocalSignIn()}\n >\n {busy === 'adopt' ? t('localCodexLoginImporting') : t('localCodexLoginImport')}\n </button>\n </div>\n )}\n renderDetails={(entry) => (\n <>\n {entry.planLabel && <span>{t('plan')}: {entry.planLabel}</span>}\n </>\n )}\n >\n {login?.active ? <p className=\"dsha-muted\" role=\"status\">{t('pending')}</p> : null}\n {popupBlocked ? <p className=\"dsh-codex-error\">{t('popupBlocked')}</p> : null}\n {authUrl !== null ? <a className=\"dsh-codex-link\" href={authUrl} target=\"_blank\" rel=\"noreferrer\">{t('continueLogin')}</a> : null}\n <div className=\"dsha-actions\">\n {login?.active ? <Button disabled={busy !== null} onClick={cancelLogin}>{t('cancel')}</Button> : null}\n {status?.authenticated ? <Button disabled={busy !== null} onClick={refreshToken}>{t('refreshToken')}</Button> : null}\n </div>\n {/* The imported rows have no Delete (the shared card hides it for a\n borrowed credential), so without the import button above this would be\n a one-way door. Rendered once, below the list, and its label says \"all\":\n the route it calls forgets every snapshot at once. */}\n {importedAccounts.length > 0 ? (\n <>\n <p className=\"dsha-muted\">{formatPoolLabel(t('stopImportingHint'), { count: importedAccounts.length })}</p>\n <div className=\"dsha-actions\">\n <button\n className=\"dsha-btn\"\n type=\"button\"\n disabled={busy !== null}\n aria-label={formatPoolLabel(t('stopImportingLabel'), { count: importedAccounts.length })}\n onClick={() => void stopImporting()}\n >{busy === 'adopt-disable' ? t('stopImportingBusy') : t('stopImporting')}</button>\n </div>\n </>\n ) : null}\n </AccountPoolSection>\n\n <Section title={t('connection')}>\n {connection !== null ? <InfoRow label={t('latency')} value={`${connection.latencyMs} ms · ${formatDate(connection.checkedAt)}`} /> : null}\n <p className=\"dsha-muted dsha-models-hint\">{t('modelsHint')}</p>\n <ModelChecklist\n items={CODEX_MODEL_CATALOG.map((model) => ({\n id: model.id,\n name: model.name,\n hint: `${formatCapacity(model.contextWindow)} ${t('tokens')}`,\n enabled: visibleModelIds.some(id => id === model.id),\n }))}\n busy={busy !== null}\n onToggle={(id, enabled) => void toggleVisibleModel(id, enabled)}\n onToggleAll={(enabled) => void setAllVisibleModels(enabled)}\n labels={{ selectAll: t('selectAll'), clearAll: t('unselectAll'), countTemplate: t('modelChecklistCount'), list: t('models') }}\n />\n <div className=\"dsha-actions\">\n <Button disabled={!status?.authenticated || busy !== null} onClick={testConnection}>{busy === 'test' ? t('testing') : t('testConnection')}</Button>\n </div>\n </Section>\n\n <Section title={t('proxySettings')}>\n <div className=\"dsha-pref-row\">\n <div>\n <strong>{t('proxyMode')}</strong>\n <p className=\"dsha-muted\">{t('proxyModeHint')}</p>\n </div>\n <select\n className=\"dsha-select\"\n aria-label={t('proxyMode')}\n value={preferences?.proxyMode ?? 'auto'}\n disabled={busy !== null}\n onChange={(event) => {\n const mode = event.currentTarget.value as 'auto' | 'custom' | 'direct'\n setStatus(current => current ? { ...current, preferences: { ...current.preferences, proxyMode: mode } } : current)\n void updatePreferences({ proxyMode: mode })\n }}\n >\n <option value=\"auto\">{t('proxyModeAuto')}</option>\n <option value=\"custom\">{t('proxyModeCustom')}</option>\n <option value=\"direct\">{t('proxyModeDirect')}</option>\n </select>\n </div>\n\n {(preferences?.proxyMode ?? 'auto') === 'auto' ? <div className=\"dsh-codex-proxy-status\">\n {status?.detectedProxy ? <>\n <span>{t('proxyDetected')}:</span>\n <code className=\"dsh-codex-proxy-tag\">{status.detectedProxy}</code>\n <span className=\"dsh-codex-success\">{t('proxyDetectedEffective')}</span>\n </> : <span className=\"dsha-muted\">{t('proxyNoneDetected')}</span>}\n </div> : null}\n\n {preferences?.proxyMode === 'direct' ? <p className=\"dsha-muted\" style={{ margin: '8px 0 0' }}>{t('proxyDirectHint')}</p> : null}\n\n {preferences?.proxyMode === 'custom' ? <div className=\"dsha-context-settings\">\n <div>\n <strong>{t('customProxyUrl')}</strong>\n <p className=\"dsha-muted\">{t('customProxyUrlHint')}</p>\n </div>\n <div className=\"dsha-context-row\">\n <span className=\"dsh-codex-proxy-control\">\n <input\n id=\"dsh-codex-custom-proxy\"\n type=\"text\"\n placeholder={t('customProxyUrlPlaceholder')}\n value={customProxyDraft ?? (preferences?.customProxyUrl ?? '')}\n disabled={busy !== null}\n aria-label={t('customProxyUrl')}\n onChange={(event) => {\n setCustomProxyDraft(event.currentTarget.value)\n }}\n onKeyDown={(event) => {\n if (event.key !== 'Enter') return\n event.preventDefault()\n void updateCustomProxyUrl()\n }}\n />\n <button\n className=\"dsha-context-save\"\n type=\"button\"\n aria-label={t('saveProxyUrl')}\n disabled={busy !== null || customProxyDraft === null}\n onClick={() => void updateCustomProxyUrl()}\n >\n {t('save')}\n </button>\n </span>\n </div>\n </div> : null}\n </Section>\n\n <Section title={t('enhancements')}>\n <div className=\"dsha-pref-row\">\n <div>\n <strong>{t('searchProvider')}</strong>\n <p className=\"dsha-muted\">{t('searchProviderHint')}</p>\n </div>\n <div className=\"dsh-codex-segments\" role=\"group\" aria-label={t('searchProvider')}>\n <button\n type=\"button\"\n className={preferences?.searchProvider === 'dsh' ? 'active' : ''}\n aria-pressed={preferences?.searchProvider === 'dsh'}\n disabled={busy !== null}\n onClick={() => selectSearchProvider('dsh')}\n >\n {t('searchProviderDsh')}\n </button>\n <button\n type=\"button\"\n className={preferences?.searchProvider === 'codex' ? 'active' : ''}\n aria-pressed={preferences?.searchProvider === 'codex'}\n disabled={busy !== null}\n onClick={() => selectSearchProvider('codex')}\n >\n {t('searchProviderCodex')}\n </button>\n </div>\n </div>\n <FetchProviderStatusCard status={status} t={t} />\n <div className=\"dsha-pref-row\">\n <div>\n <strong>{t('outputVerbosity')}</strong>\n <p className=\"dsha-muted\">{t('outputVerbosityHint')}</p>\n </div>\n <select className=\"dsha-select\" aria-label={t('outputVerbosity')} value={preferences?.outputVerbosity ?? ''} disabled={busy !== null} onChange={(event) => {\n const value = event.currentTarget.value\n void updatePreferences({ outputVerbosity: value === '' ? null : value as 'low' | 'medium' | 'high' })\n }}>\n <option value=\"\">{t('providerDefault')}</option>\n <option value=\"low\">{t('verbosityLow')}</option>\n <option value=\"medium\">{t('verbosityMedium')}</option>\n <option value=\"high\">{t('verbosityHigh')}</option>\n </select>\n </div>\n <div className=\"dsha-pref-row\">\n <div>\n <strong>{t('reasoningSummary')}</strong>\n <p className=\"dsha-muted\">{t('reasoningSummaryHint')}</p>\n </div>\n <select className=\"dsha-select\" aria-label={t('reasoningSummary')} value={preferences?.reasoningSummary ?? ''} disabled={busy !== null} onChange={(event) => {\n const value = event.currentTarget.value\n void updatePreferences({ reasoningSummary: value === '' ? null : value as CodexReasoningSummary })\n }}>\n <option value=\"\">{t('providerDefault')}</option>\n <option value=\"auto\">{t('summaryAuto')}</option>\n <option value=\"concise\">{t('summaryConcise')}</option>\n <option value=\"detailed\">{t('summaryDetailed')}</option>\n <option value=\"none\">{t('summaryNone')}</option>\n </select>\n </div>\n <div className=\"dsha-context-settings\">\n <div>\n <strong>{t('contextWindows')}</strong>\n <p className=\"dsha-muted\">{t('contextWindowsHint')}</p>\n </div>\n {contextModels.length === 0 ? <p className=\"dsha-muted\">{t('contextWindowsNoneEnabled')}</p> : null}\n {contextModels.map((entry) => {\n const model = entry.id\n const fallback = preferences?.contextWindowOverrides?.[model] ?? entry.contextWindow\n const draft = contextDrafts[model]\n const parsedDraft = draft === undefined ? fallback : parseCapacity(draft, contextWindowLimitForModel(model))\n const dirty = draft !== undefined && parsedDraft !== fallback\n const overridden = preferences?.contextWindowOverrides?.[model] !== undefined\n const inputId = `dsh-codex-context-${model}`\n return <div className=\"dsha-context-row\" key={model}>\n <label htmlFor={inputId}>{entry.name}</label>\n <span className=\"dsha-capacity-control\">\n <input id={inputId} type=\"text\" inputMode=\"numeric\" value={draft ?? formatCapacity(fallback)} disabled={busy !== null} aria-label={entry.name + ' ' + t('contextWindow')} onChange={(event) => {\n const value = event.currentTarget.value\n setContextDrafts((drafts) => ({ ...drafts, [model]: value }))\n }} onKeyDown={(event) => {\n if (event.key !== 'Enter' || !dirty) return\n event.preventDefault()\n void updateContextWindow(model)\n }} />\n <small>{t('tokens')}</small>\n <button className=\"dsha-context-save\" type=\"button\" data-model={model} aria-label={entry.name + ' ' + t('saveContextWindow')} disabled={busy !== null || !dirty} onClick={() => void updateContextWindow(model)}>{t('save')}</button>\n <button className=\"dsha-context-save dsha-context-reset\" type=\"button\" data-reset-model={model} aria-label={entry.name + ' ' + t('contextWindowReset')} disabled={busy !== null || !overridden} onClick={() => void resetContextWindow(model)}>{t('contextWindowReset')}</button>\n </span>\n </div>\n })}\n <div className=\"dsha-actions\">\n <Button disabled={busy !== null || overrideCount === 0} onClick={resetAllContextWindows}>{t('contextWindowResetAll')}</Button>\n </div>\n </div>\n <label className=\"dsh-codex-check\">\n <input type=\"checkbox\" checked={preferences?.fastMode === true} disabled={busy !== null} onChange={(event) => updatePreferences({ fastMode: event.currentTarget.checked })} />\n <span>\n <strong>{t('fastMode')}</strong>\n <small>{t('fastModeHint')}</small>\n </span>\n </label>\n <label className=\"dsh-codex-check\">\n <input type=\"checkbox\" checked={preferences?.quickQuotaVisible === true} disabled={busy !== null} onChange={(event) => updatePreferences({ quickQuotaVisible: event.currentTarget.checked })} />\n <span>\n <strong>{t('quickQuota')}</strong>\n <small>{t('quickQuotaHint')}</small>\n </span>\n </label>\n </Section>\n\n <Section title={t('quota')} aside={<Button disabled={!status?.authenticated || busy !== null} onClick={refreshQuota}>{busy === 'quota' ? t('refreshing') : t('refreshQuota')}</Button>}>\n <p className=\"dsha-muted\">{t('quotaIntro')}</p>\n {/* The progress bars moved into each account card: quota follows the\n account, so a bar here could only ever describe whichever account\n happened to be active when the snapshot was read. What stays is what\n has no per-account bar to live in — the plan, the credits, the\n monthly spend, the reset cards and the freshness of this reading. */}\n <p className=\"dsha-muted\">{poolLabels.quotaFactsScope}</p>\n {quota?.state === 'signed-out' || !status?.authenticated ? <p className=\"dsh-codex-empty\">{t('quotaSignedOut')}</p> : null}\n {quota?.buckets?.map((bucket) => <QuotaFact key={bucket.id} label={bucket.name} value={bucket.planType ?? '—'} />)}\n {quota?.credits !== null && quota?.credits !== undefined ? <QuotaFact label={t('credits')} value={quota.credits.unlimited ? t('unlimited') : quota.credits.balance ?? (quota.credits.hasCredits ? t('available') : t('unavailable'))} /> : null}\n {quota?.individualLimit !== null && quota?.individualLimit !== undefined ? <QuotaFact label={t('monthlySpend')} value={individualLimitLabel(quota.individualLimit, t)} /> : null}\n {quota?.resetCredits !== null && quota?.resetCredits !== undefined ? <ResetCreditsFact resetCredits={quota.resetCredits} busy={busy} onUse={useResetCredit} t={t} /> : null}\n {resetCreditNotice !== null ? <p className=\"dsh-codex-success\" role=\"status\">{resetCreditNotice}</p> : null}\n {quota?.spendControlReached === true ? <p className=\"dsh-codex-warning\" role=\"status\">{t('spendControlReached')}</p> : null}\n {quota?.state === 'empty' ? <p className=\"dsh-codex-empty\">{t('noQuota')}</p> : null}\n {quota?.stale ? <p className=\"dsh-codex-warning\" role=\"status\">{t('stale')}</p> : null}\n {quota?.error ? <p className=\"dsh-codex-error\" role=\"alert\">{quota.error.message}</p> : null}\n {quota?.fetchedAt ? <p className=\"dsh-codex-timestamp\">{t('updated')}: {formatDate(quota.fetchedAt)}</p> : null}\n </Section>\n </>}\n\n <span className=\"dsh-codex-sr\" aria-live=\"polite\">{busy === null ? '' : busy}</span>\n </section>\n}\n\nfunction Section({ title, aside, children }: { title: string; aside?: React.ReactNode; children: React.ReactNode }): React.JSX.Element {\n return <section className=\"dsha-group\">\n <div className=\"dsha-grouphead\"><h3>{title}</h3>{aside}</div>\n {children}\n </section>\n}\n\nfunction Button({ primary = false, disabled, onClick, children }: { primary?: boolean; disabled?: boolean; onClick: () => void | Promise<void>; children: React.ReactNode }): React.JSX.Element {\n return <button className={`dsha-btn${primary ? ' dsha-btn-primary' : ''}`} type=\"button\" disabled={disabled} onClick={() => void onClick()}>{children}</button>\n}\n\nfunction InfoRow({ label, value }: { label: string; value: string }): React.JSX.Element {\n return <div className=\"dsha-row\"><span className=\"dsha-label\">{label}</span><span className=\"dsha-value\">{value}</span></div>\n}\n\nconst SWITCHER_STATE_LABELS = {\n idle: 'switcherStateIdle',\n applying: 'switcherStateApplying',\n applied: 'switcherStateApplied',\n missing: 'switcherStateMissing',\n failed: 'switcherStateFailed',\n} as const\n\nconst FETCH_MODE_LABELS = {\n auto: 'fetchModeAuto',\n plugin: 'fetchModePlugin',\n dsh: 'fetchModeDsh',\n} as const\n\n/**\n * Read-only view of the fetch selection, shown under the search source.\n *\n * Both blocks are optional on the status DTO, so every row is rendered only from\n * a value the host actually reported. That distinction is load-bearing: a\n * missing `switcher` means the host tells us nothing and the row stays hidden,\n * while a reported `configuredFetchProvider: null` is a real answer — the host\n * pinned no provider, which is the DSH default. Guessing an id there would claim\n * a provider the settings page never observed.\n *\n * Nothing here is editable: the mode and the limits live in the plugin Config,\n * not in the preferences this card sits in, so the numbers cannot be mistaken for\n * a setting that this page can change.\n */\nexport function FetchProviderStatusCard({ status, t }: { status: PluginStatusDto | null | undefined; t: Translate }): React.JSX.Element | null {\n const switcher = status?.switcher\n const configuration = status?.fetchConfiguration\n if (switcher === undefined && configuration === undefined) return null\n const state = switcher !== null && switcher !== undefined && switcher.state in SWITCHER_STATE_LABELS\n ? switcher.state\n : null\n const mode = configuration !== undefined && configuration.fetchProvider in FETCH_MODE_LABELS\n ? configuration.fetchProvider\n : undefined\n const maxBodyChars = fetchLimit(configuration?.fetchMaxBodyChars)\n const maxResponseBytes = fetchLimit(configuration?.fetchMaxResponseBytes)\n return <div className=\"dsha-context-settings\" data-fetch-status={state ?? 'none'}>\n <div>\n <strong>{t('fetchStatus')}</strong>\n <p className=\"dsha-muted\">{t('fetchStatusHint')}</p>\n </div>\n {switcher !== null && switcher !== undefined ? <InfoRow\n label={t('fetchConfiguredProvider')}\n value={switcher.configuredFetchProvider || t('fetchProviderDshDefault')}\n /> : null}\n {state !== null ? <InfoRow label={t('switcherState')} value={t(SWITCHER_STATE_LABELS[state])} /> : null}\n {mode !== undefined ? <InfoRow label={t('fetchMode')} value={t(FETCH_MODE_LABELS[mode])} /> : null}\n {maxBodyChars !== null ? <InfoRow label={t('fetchMaxBodyChars')} value={`${maxBodyChars} ${t('characters')}`} /> : null}\n {maxResponseBytes !== null ? <InfoRow label={t('fetchMaxResponseBytes')} value={`${maxResponseBytes} ${t('bytes')}`} /> : null}\n {mode !== undefined && mode !== 'plugin' ? <p className=\"dsha-muted\">{t('fetchLimitsInactive')}</p> : null}\n <p className=\"dsha-muted\">{t('fetchConfigSource')}</p>\n </div>\n}\n\n/** A limit is shown only once it is the positive safe integer the Config promises. */\nfunction fetchLimit(value: number | undefined): number | null {\n return value !== undefined && Number.isSafeInteger(value) && value >= 1 ? value : null\n}\n\nfunction QuotaFact({ label, value }: { label: string; value: string }): React.JSX.Element {\n return <div className=\"dsh-codex-quota-fact\"><span>{label}</span><strong>{value}</strong></div>\n}\n\nexport function ResetCreditsFact({ resetCredits, busy, onUse, t }: { resetCredits: NonNullable<PluginStatusDto['quota']['resetCredits']>; busy: BusyAction; onUse: () => Promise<void>; t: Translate }): React.JSX.Element {\n const available = resetCredits.availableCount > 0\n return <div className=\"dsh-codex-reset-credits\">\n <div className=\"dsh-codex-reset-credits-info\">\n <span>{t('resetCredits')}</span>\n <strong>{resetCredits.availableCount}</strong>\n <small>{t('resetCreditExpires')}: {resetCredits.expiresAt == null ? t('unknown') : formatReset(resetCredits.expiresAt)}</small>\n </div>\n <Button primary disabled={!available || busy !== null} onClick={onUse}>{busy === 'reset-credit' ? t('usingResetCredit') : t('useResetCredit')}</Button>\n </div>\n}\n\nexport function QuotaBar({ label, window, t }: { label: string; window: QuotaWindowDto; t: Translate }): React.JSX.Element {\n const percent = typeof window?.usedPercent === 'number' && Number.isFinite(window.usedPercent) ? window.usedPercent : 0\n const level = percent >= 95 ? 'danger' : percent >= 80 ? 'warning' : 'normal'\n const remaining = Math.max(0, 100 - percent)\n return <div className=\"dsh-codex-meter-wrap\">\n <div className=\"dsh-codex-meter-label\"><span>{label}</span><strong>{formatPercent(percent)}</strong></div>\n <div className={`dsh-codex-meter dsh-codex-meter-${level}`} role=\"progressbar\" aria-label={`${label}: ${formatPercent(percent)} ${t('used')}`} aria-valuemin={0} aria-valuemax={100} aria-valuenow={percent}>\n <span style={{ width: `${Math.min(100, Math.max(0, percent))}%` }} />\n </div>\n <div className=\"dsh-codex-meter-meta\">\n <span>{percent >= 100 ? `${t('exhausted')} · ${formatPercent(remaining)} ${t('remaining')}` : `${formatPercent(percent)} ${t('used')} · ${formatPercent(remaining)} ${t('remaining')}`}</span>\n <span>{window?.resetsAt == null ? '—' : `${t('resets')}: ${formatReset(window.resetsAt)}`}</span>\n </div>\n </div>\n}\n\nfunction Skeleton({ label }: { label: string }): React.JSX.Element {\n return <div className=\"dsh-codex-skeleton\" role=\"status\" aria-label={label}><span /><span /></div>\n}\n\nexport function windowLabel(minutes: number | null | undefined, t: Translate): string {\n if (minutes === null || minutes === undefined || typeof minutes !== 'number' || !Number.isFinite(minutes) || minutes <= 0) return t('limitWindow')\n const [value, unit]: [number, Intl.NumberFormatOptions['unit']] = minutes >= 1440 && minutes % 1440 === 0\n ? [minutes / 1440, 'day']\n : minutes >= 60 && minutes % 60 === 0\n ? [minutes / 60, 'hour']\n : [Math.round(minutes), 'minute']\n try {\n return `${new Intl.NumberFormat(undefined, { style: 'unit', unit, unitDisplay: 'long' }).format(value)} ${t('limitWindow')}`\n } catch {\n return `${value} ${t('limitWindow')}`\n }\n}\n\nexport function parsePositiveCapacity(value: string): number | null {\n const normalized = value.trim().toLowerCase().replace(/[,_\\s]/g, '')\n const matched = normalized.match(/^(\\d+(?:\\.\\d+)?)(k|m)?$/)\n if (matched === null) return null\n const multiplier = matched[2] === 'm' ? 1_000_000 : matched[2] === 'k' ? 1_000 : 1\n const parsed = Number(matched[1]) * multiplier\n return Number.isSafeInteger(parsed) && parsed >= 1 ? parsed : null\n}\n\nexport function parseCapacity(value: string, maxContextWindow = GPT_56_MAX_CONTEXT_WINDOW): number | null {\n const parsed = parsePositiveCapacity(value)\n return parsed !== null && parsed <= maxContextWindow ? parsed : null\n}\n\nfunction formatCapacity(value: number): string {\n if (value % 1_000 === 0) return `${value / 1_000}K`\n return String(value)\n}\n\nfunction formatPercent(value: number | undefined | null): string {\n if (value === undefined || value === null || typeof value !== 'number' || !Number.isFinite(value)) return '0%'\n try {\n return `${new Intl.NumberFormat(undefined, { maximumFractionDigits: 1 }).format(value)}%`\n } catch {\n return `${value}%`\n }\n}\n\nfunction individualLimitLabel(limit: NonNullable<PluginStatusDto['quota']['individualLimit']>, t: Translate): string {\n const parts = [\n limit.remainingPercent !== null && limit.remainingPercent !== undefined ? `${formatPercent(limit.remainingPercent)} ${t('remaining')}` : null,\n limit.limit !== null && limit.limit !== undefined ? `${t('limit')}: ${limit.limit}` : null,\n limit.used !== null && limit.used !== undefined ? `${t('used')}: ${limit.used}` : null,\n limit.resetsAt !== null && limit.resetsAt !== undefined ? `${t('resets')}: ${formatReset(limit.resetsAt)}` : null,\n ].filter((part): part is string => part !== null)\n return parts.length > 0 ? parts.join(' · ') : t('unknown')\n}\n\nfunction formatDate(seconds: number | undefined | null): string {\n if (seconds === undefined || seconds === null || typeof seconds !== 'number' || !Number.isFinite(seconds) || seconds <= 0) return '—'\n const ms = seconds > 10_000_000_000 ? seconds : seconds * 1000\n try {\n return new Intl.DateTimeFormat(undefined, { dateStyle: 'medium', timeStyle: 'short' }).format(ms)\n } catch {\n return '—'\n }\n}\n\nexport function formatReset(seconds: number | undefined | null): string {\n if (seconds === undefined || seconds === null || typeof seconds !== 'number' || !Number.isFinite(seconds) || seconds <= 0) return '—'\n const ms = seconds > 10_000_000_000 ? seconds : seconds * 1000\n const absolute = formatDate(seconds)\n const diff = ms - Date.now()\n const abs = Math.abs(diff)\n const [amount, unit]: [number, Intl.RelativeTimeFormatUnit] = abs >= 86_400_000\n ? [Math.round(diff / 86_400_000), 'day']\n : abs >= 3_600_000\n ? [Math.round(diff / 3_600_000), 'hour']\n : [Math.round(diff / 60_000), 'minute']\n try {\n return `${absolute} (${new Intl.RelativeTimeFormat(undefined, { numeric: 'auto' }).format(amount, unit)})`\n } catch {\n return absolute\n }\n}\n\nfunction messageOf(error: unknown): string {\n return error instanceof Error ? error.message : String(error)\n}\n","/**\n * The capacity, date and countdown formatting every provider settings card shares.\n *\n * Each card used to carry its own copy of the capacity pair. The five copies\n * were byte-identical except Antigravity's `formatCapacity`, which had lost the\n * 1K floor and so rendered a zero as \"0K\" while its siblings rendered \"0\". The\n * parse has to mean the same thing on every line — it takes free-text user input\n * that feeds the overflow judgement — so this is the one place it lives. The\n * date helpers were copied the same way; WorkBuddy's countdown is here for the\n * same reason.\n */\n\n/**\n * Parse \"1M\", \"512K\", \"200000\" into a positive integer token count.\n *\n * Anything that is not a plain capacity — including `0`, which no model has —\n * returns null rather than a coerced number, so the caller can leave the draft\n * uncommitted instead of storing a length that would silently break compaction.\n */\nexport function parsePositiveCapacity(value: string): number | null {\n const normalized = value.trim().toLowerCase().replace(/[,_\\s]/g, '')\n const matched = normalized.match(/^(\\d+(?:\\.\\d+)?)(k|m)?$/)\n if (matched === null) return null\n const multiplier = matched[2] === 'm' ? 1_000_000 : matched[2] === 'k' ? 1_000 : 1\n const parsed = Number(matched[1]) * multiplier\n return Number.isSafeInteger(parsed) && parsed >= 1 ? parsed : null\n}\n\n/** Render a token capacity the way the capacity field seeds itself. */\nexport function formatCapacity(value: number): string {\n if (value >= 1_000_000 && value % 100_000 === 0) return `${value / 1_000_000}M`\n if (value >= 1_000 && value % 1_000 === 0) return `${value / 1_000}K`\n return String(value)\n}\n\n/** A stamp in the reader's own locale, or an em dash when there is none. */\nexport function formatDate(ms?: number | null): string {\n if (ms === undefined || ms === null || !Number.isFinite(ms) || ms <= 0) return '—'\n try {\n return new Intl.DateTimeFormat(undefined, { dateStyle: 'medium', timeStyle: 'short' }).format(ms)\n } catch {\n return '—'\n }\n}\n\n/**\n * Countdown to a reset instant (\"3d 4h\"), empty when there is nothing to count\n * down to. Empty rather than \"—\" because callers append it to a date they have\n * already rendered, and a dash there would read as a second missing value.\n */\nexport function formatReset(resetsAt?: number | null): string {\n if (resetsAt === undefined || resetsAt === null || resetsAt <= 0) return ''\n const diff = resetsAt - Date.now()\n if (diff <= 0) return 'now'\n const mins = Math.floor(diff / 60000)\n const hours = Math.floor(mins / 60)\n const days = Math.floor(hours / 24)\n if (days > 0) return `${days}d ${hours % 24}h`\n if (hours > 0) return `${hours}h ${mins % 60}m`\n return `${mins}m`\n}\n","/**\n * The shared \"model context windows\" block every provider settings card renders.\n *\n * Six cards had grown near-identical copies of this markup: one row per enabled\n * model, a free-text capacity input, a save button, a restore button, and a\n * batch restore. Only these things ever differed between them —\n *\n * - the words (each card's dictionary, plus WorkBuddy's hardcoded `tokens`\n * and the hardcoded English `context window` input label four of them carry);\n * - whether a row shows the model's effective window beside the name when it\n * exceeds the model's default, and which stylesheet class that figure wears;\n * - whether the capacity input carries an `aria-label` at all (Antigravity's\n * does not);\n * - how a save or a restore is carried out, which stays in each card because\n * WorkBuddy normalizes its status payload and Antigravity confirms the batch\n * restore first.\n *\n * Everything the rows and callbacks need is therefore the whole interface: the\n * editor parses, seeds and stores nothing.\n */\nimport { formatCapacity } from './format.ts'\n\nexport interface ContextWindowRow {\n /** Model id: the row key, the name's tooltip, and what the callbacks receive. */\n id: string\n name: string\n /**\n * The free-text draft the card owns. The editor never parses it and never\n * falls back to a default, because a half-typed value has to survive a render.\n */\n draft: string\n /** Window figure shown beside the name; the cards that show one format it themselves. */\n meta?: string\n /** `aria-label` of this row's input; the one card that labels it with nothing omits it. */\n inputLabel?: string\n /**\n * Whether the host stores an override for this model. A model with none has\n * nothing to drop, so its restore button stays disabled.\n */\n hasOverride: boolean\n /** True while this row's save or restore request is in flight. */\n saving: boolean\n}\n\nexport interface ContextWindowLabels {\n /** Unit rendered after every capacity input. */\n tokens: string\n save: string\n saving: string\n reset: string\n resetAll: string\n /** Sentence shown while no enabled model has a row. */\n empty: string\n}\n\n/** The slice of a line's status payload the draft seeding reads. */\nexport interface ContextWindowStatus {\n models: readonly { id: string; defaultContextWindow: number }[]\n contextWindowOverrides: Record<string, number>\n}\n\n/**\n * Seed one draft per model from a status payload, so the input shows the stored\n * override and falls back to the catalog length.\n *\n * Run after a model toggle too: a model that was just enabled has no draft yet,\n * and only enabled models get a row — without this, its row would render an\n * empty input that a save would then reject as unparsable.\n */\nexport function contextDraftsFor(status: ContextWindowStatus): Record<string, string> {\n const drafts: Record<string, string> = {}\n for (const model of status.models) {\n drafts[model.id] = formatCapacity(status.contextWindowOverrides[model.id] || model.defaultContextWindow)\n }\n return drafts\n}\n\ninterface Props {\n rows: ContextWindowRow[]\n labels: ContextWindowLabels\n /** Disables the batch restore while any other request is in flight. */\n busy: boolean\n /**\n * Counts every stored override, including keys left by models the picker no\n * longer lists — which is why the batch button can be live while no visible\n * row offers a restore.\n */\n overrideCount: number\n /** Class the meta figure wears; each line draws it from its own stylesheet. */\n metaClassName?: string\n onDraftChange(id: string, draft: string): void\n onCommit(id: string): void\n onReset(id: string): void\n onResetAll(): void\n}\n\nexport function ContextWindowEditor({\n rows,\n labels,\n busy,\n overrideCount,\n metaClassName,\n onDraftChange,\n onCommit,\n onReset,\n onResetAll,\n}: Props): React.JSX.Element {\n return <div className=\"dsha-context-settings\">\n {rows.length === 0 ? <p className=\"dsha-muted\">{labels.empty}</p> : null}\n {rows.map((row) => (\n <div key={row.id} className=\"dsha-context-row\">\n <span title={row.id}>\n {row.name}\n {row.meta !== undefined ? <span className={metaClassName}>{row.meta}</span> : null}\n </span>\n <div className=\"dsha-capacity-control\">\n <input\n type=\"text\"\n aria-label={row.inputLabel}\n value={row.draft}\n onChange={(event) => onDraftChange(row.id, event.currentTarget.value)}\n onKeyDown={(event) => {\n if (event.key === 'Enter') onCommit(row.id)\n }}\n />\n <small>{labels.tokens}</small>\n <button\n type=\"button\"\n className=\"dsha-context-save\"\n disabled={row.saving}\n onClick={() => onCommit(row.id)}\n >\n {row.saving ? labels.saving : labels.save}\n </button>\n <button\n type=\"button\"\n className=\"dsha-context-save dsha-context-reset\"\n aria-label={`${row.name} ${labels.reset}`}\n disabled={row.saving || !row.hasOverride}\n onClick={() => onReset(row.id)}\n >\n {labels.reset}\n </button>\n </div>\n </div>\n ))}\n <div className=\"dsha-actions\">\n <button type=\"button\" className=\"dsha-btn\" disabled={busy || overrideCount === 0} onClick={onResetAll}>\n {labels.resetAll}\n </button>\n </div>\n </div>\n}\n","/**\n * One line's host routes, behind one reader.\n *\n * Ten copies of this reader had drifted into ten slightly different ones, and\n * the differences were all failure handling — the part nobody looks at until it\n * fires:\n *\n * - nine of them read `json.error` as a string. That is the sibling lines'\n * shape, but the ChatGPT routes answer `{ ok: false, error: { code, message } }`,\n * so a structured refusal rendered as \"[object Object]\";\n * - one of them tolerated an empty body and a non-JSON body, which is exactly\n * what a stale host half produces (the browser reads client assets from disk\n * on demand; the host loads them only at startup). The other nine turned it\n * into a bare parse crash with no way to tell what happened.\n *\n * This is the union: both error shapes, both degenerate bodies, and the same\n * sentence for the same failure on every line.\n */\nimport type { PublicErrorDto } from '../../shared/contracts.ts'\n\nexport interface LineApi {\n /** Any route under the line's prefix, unwrapping whichever envelope arrives. */\n request<T>(path: string, init?: RequestInit): Promise<T>\n get<T>(path: string): Promise<T>\n post<T>(path: string, body?: object): Promise<T>\n}\n\ninterface Envelope {\n ok?: unknown\n value?: unknown\n error?: unknown\n}\n\n/**\n * A route's error field is a plain string on some routes and a structured\n * `PublicErrorDto` on others; the card must not care which one arrived.\n */\nfunction errorMessage(value: unknown, fallback: string): string {\n if (typeof value === 'string' && value !== '') return value\n if (value !== null && typeof value === 'object') {\n const message = (value as Partial<PublicErrorDto>).message\n if (typeof message === 'string' && message !== '') return message\n }\n return fallback\n}\n\nexport function createLineApi(prefix: string, label: string): LineApi {\n async function request<T>(path: string, init?: RequestInit): Promise<T> {\n const response = await fetch(`${prefix}${path}`, {\n ...init,\n credentials: 'same-origin',\n headers: {\n 'Content-Type': 'application/json',\n ...init?.headers,\n },\n })\n\n const raw = await response.text()\n if (raw.trim() === '') {\n throw new Error(\n `${label} settings route did not answer (HTTP ${response.status} ${response.statusText || 'no body'}). `\n + 'The plugin loaded in the browser may be newer than the one running in the host — '\n + 'restart DSH so both halves come from the same build.',\n )\n }\n\n let body: unknown = null\n try {\n body = JSON.parse(raw) as unknown\n } catch {\n throw new Error(`${label} settings route returned a non-JSON body (HTTP ${response.status}): ${raw.slice(0, 200)}`)\n }\n\n const envelope = body as Envelope | null\n // A boolean `ok` is what declares the envelope — not the presence of\n // `value`: a refusal carries `error` and no `value` at all, and demanding\n // both made a 200-with-`ok:false` answer look like a successful payload.\n const isEnvelope = envelope !== null && typeof envelope === 'object' && typeof envelope.ok === 'boolean'\n if (isEnvelope) {\n if (!response.ok || envelope.ok === false) {\n throw new Error(errorMessage(envelope.error, `HTTP ${response.status}`))\n }\n return envelope.value as T\n }\n // Some routes document their payload directly instead of wrapping it.\n if (!response.ok) throw new Error(errorMessage(envelope?.error, `HTTP ${response.status}`))\n return body as T\n }\n\n return {\n request,\n get: <T>(path: string): Promise<T> => request<T>(path),\n post: <T>(path: string, body: object = {}): Promise<T> => request<T>(path, { method: 'POST', body: JSON.stringify(body) }),\n }\n}\n","export const NS_ANTIGRAVITY = 'dsh-antigravity'\n\nimport { accountPoolEn, accountPoolZh } from '../common/account-pool-labels.ts'\n\nexport const zh = {\n // The account-management card is shared with every other provider tab.\n ...accountPoolZh,\n title: 'Antigravity',\n pageDesc: '登录 Google Antigravity / Cloud Code Assist,并查看当前账号的共享额度。',\n account: '已登录',\n signedIn: '已登录',\n signedOut: '未登录',\n accountPool: '账号管理',\n addAccount: '添加账号',\n primaryAccount: '主账号',\n activeAccount: '当前使用',\n setPrimary: '设为主账号',\n deleteAccount: '删除',\n cooling: '冷却中',\n clearCooldown: '重置冷却',\n rotationStrategy: '调度策略',\n strategySequential: '顺序耗尽(当前优先,遇限流自动切号)',\n strategyRoundRobin: '轮询调度(按账号循环均匀分摊)',\n strategySticky: '会话粘性(保持当前账号直到被限流)',\n noAccounts: '暂无账号,点击「添加账号」完成登录授权。',\n plan: '套餐',\n accountId: '账号 ID',\n expires: '令牌到期',\n signInAgain: '重新登录',\n refreshToken: '刷新凭据',\n signOut: '注销',\n signIn: '登录',\n signingIn: '登录中...',\n connection: '连接',\n modelsHint: '勾选后模型才会显示在对话页的模型选择列表中;全部取消勾选或关闭概览卡片上的开关可在列表中隐藏该供应商。',\n modelsSection: '模型',\n selectAll: '全选',\n unselectAll: '全不选',\n enhanced: '增强功能',\n defaultReasoningEffort: '默认思考深度',\n defaultReasoningEffortHint: '控制支持推理的模型在未单独指定时的思考强度。',\n defaultEffortAuto: '使用 Provider 默认值',\n contextWindowSection: '模型上下文窗口',\n contextWindowHint: '默认按模型标准;可选应用最高容量,该值用于 DSH 的压缩与溢出判断,可输入 1M、512K、200K 等容量。',\n contextWindowReset: '恢复默认',\n contextWindowResetAll: '全部恢复默认',\n contextWindowResetAllConfirm: '确定把已改过的模型上下文窗口全部恢复为默认值吗?',\n contextWindowNoneEnabled: '还没有勾选任何模型。在上方勾选后,这里会出现该模型的上下文窗口设置。',\n save: '保存',\n saved: '已保存',\n saving: '保存中...',\n quotaSection: '用量与配额',\n quotaDesc: '数据来自 Google Cloud Code Assist 配额服务,页面可见时最多每 60 秒刷新一次。',\n refreshQuota: '刷新用量',\n refreshingQuota: '刷新中...',\n quotaEmpty: '暂无配额数据,点击「刷新用量」重试。',\n googleValidation: '前往 Google 完成账号验证',\n resetPrefix: '重置: {time}',\n resetUnavailable: '重置: n/a',\n resetNow: '现在',\n timeDayHour: '{days}天 {hours}时',\n timeHourMin: '{hours}h {minutes}m',\n timeMin: '{minutes}m',\n updatedAt: '更新时间:{time}',\n loading: '加载中...',\n loginFailed: '登录失败',\n tokens: 'tokens',\n}\n\nexport const en: Record<keyof typeof zh, string> = {\n ...accountPoolEn,\n title: 'Antigravity',\n pageDesc: 'Sign in to Google Antigravity / Cloud Code Assist and view shared quotas.',\n account: 'Signed in',\n signedIn: 'Signed in',\n signedOut: 'Not signed in',\n accountPool: 'Account Management',\n addAccount: 'Add Account',\n primaryAccount: 'Primary',\n activeAccount: 'In Use',\n setPrimary: 'Set as Primary',\n deleteAccount: 'Delete',\n cooling: 'In Cooldown',\n clearCooldown: 'Clear Cooldown',\n rotationStrategy: 'Scheduling Strategy',\n strategySequential: 'Sequential Drain (Primary first, failover on 429)',\n strategyRoundRobin: 'Round-Robin (Evenly rotate across accounts)',\n strategySticky: 'Sticky session (hold the current account until it is limited)',\n noAccounts: 'No accounts yet. Click \"Add Account\" to authorize.',\n plan: 'Plan',\n accountId: 'Account ID',\n expires: 'Token expires',\n signInAgain: 'Sign in again',\n refreshToken: 'Refresh token',\n signOut: 'Sign out',\n signIn: 'Sign in',\n signingIn: 'Signing in...',\n connection: 'Connection',\n modelsHint: 'Checked models will appear in DSH conversation model list; unchecking all or turning off the switch on the overview card hides this provider.',\n modelsSection: 'Models',\n selectAll: 'Select all',\n unselectAll: 'Deselect all',\n enhanced: 'Enhanced Features',\n defaultReasoningEffort: 'Default reasoning effort',\n defaultReasoningEffortHint: 'Controls reasoning effort for reasoning models when not explicitly specified in conversation.',\n defaultEffortAuto: 'Use Provider default',\n contextWindowSection: 'Model Context Window',\n contextWindowHint: 'Defaults to model specification; configure custom capacity used by DSH for compaction and overflow judgments (e.g., 1M, 512K, 200K).',\n contextWindowReset: 'Restore default',\n contextWindowResetAll: 'Restore all defaults',\n contextWindowResetAllConfirm: 'Restore every changed model context window to its default?',\n contextWindowNoneEnabled: 'No model is checked yet. Check one above and its context window setting appears here.',\n save: 'Save',\n saved: 'Saved',\n saving: 'Saving...',\n quotaSection: 'Usage & Quota',\n quotaDesc: 'Data from Google Cloud Code Assist quota service; refreshes up to once every 60 seconds when visible.',\n refreshQuota: 'Refresh quota',\n refreshingQuota: 'Refreshing...',\n quotaEmpty: 'No quota data yet — use “Refresh quota” to retry.',\n googleValidation: 'Verify the account with Google',\n resetPrefix: 'Reset: {time}',\n resetUnavailable: 'Reset: n/a',\n resetNow: 'now',\n timeDayHour: '{days}d {hours}h',\n timeHourMin: '{hours}h {minutes}m',\n timeMin: '{minutes}m',\n updatedAt: 'Updated at: {time}',\n loading: 'Loading...',\n loginFailed: 'Login failed',\n tokens: 'tokens',\n}\n\nexport const dictionaries = {\n zh,\n 'zh-CN': zh,\n en,\n 'en-US': en,\n}\n\nexport type AntigravityLocaleKey = keyof typeof zh\n","import React, { useCallback, useEffect, useRef, useState } from 'react'\nimport type {\n AccountRotationStrategy,\n AntigravityWebStatus,\n} from '../../shared/antigravity-contracts.ts'\nimport { AccountPoolSection } from '../common/AccountPoolSection.tsx'\nimport { ContextWindowEditor, contextDraftsFor } from '../common/ContextWindowEditor.tsx'\nimport { ModelChecklist } from '../common/ModelChecklist.tsx'\nimport { createLineApi } from '../common/line-api.ts'\nimport { createQuotaFollowUp, type QuotaFollowUp } from '../common/quota-follow-up.ts'\nimport { formatCapacity, parsePositiveCapacity } from '../common/format.ts'\nimport { zh } from './locales.ts'\n\nconst API = '/antigravity/api'\nconst api = createLineApi(API, 'Antigravity')\n\ninterface Props {\n onModelChange?: () => void\n loadModelDirectory?: () => void\n}\n\nexport function AntigravitySection({ onModelChange, loadModelDirectory }: Props): React.ReactElement {\n const [status, setStatus] = useState<AntigravityWebStatus | null>(null)\n const [loading, setLoading] = useState(true)\n const [busy, setBusy] = useState<string | null>(null)\n const [error, setError] = useState<string | null>(null)\n const [validationUrl, setValidationUrl] = useState<string | null>(null)\n const [loginProgress, setLoginProgress] = useState<string | null>(null)\n const [contextDrafts, setContextDrafts] = useState<Record<string, string>>({})\n const [savingModel, setSavingModel] = useState<string | null>(null)\n\n /** Follow-up poll owed while the host refreshes the quota behind an answer. */\n const quotaFollowUp = useRef<QuotaFollowUp | null>(null)\n\n const t = zh\n\n const notifyChange = useCallback(() => {\n onModelChange?.()\n loadModelDirectory?.()\n }, [onModelChange, loadModelDirectory])\n\n const loadStatus = useCallback(async (quiet = false) => {\n if (!quiet) {\n setError(null)\n setValidationUrl(null)\n }\n try {\n // The host refreshes a stale quota cache while serving /status, so a second\n // client-side POST /quota here would double every upstream fetch.\n const data = await api.request<AntigravityWebStatus>('/status')\n setStatus(data)\n setContextDrafts(contextDraftsFor(data))\n // An answer that refreshed the quota behind itself is followed up shortly,\n // so the fresh numbers land without waiting for the next poll.\n quotaFollowUp.current ??= createQuotaFollowUp()\n quotaFollowUp.current.observe(data.quotaRefreshing === true, () => { void loadStatus(true) })\n } catch (err) {\n if (!quiet) setError(err instanceof Error ? err.message : String(err))\n } finally {\n setLoading(false)\n }\n }, [])\n\n useEffect(() => {\n void loadStatus()\n const refreshWhenVisible = () => {\n if (document.visibilityState === 'visible') void loadStatus(true)\n }\n document.addEventListener('visibilitychange', refreshWhenVisible)\n const timer = window.setInterval(refreshWhenVisible, 60_000)\n return () => {\n window.clearInterval(timer)\n document.removeEventListener('visibilitychange', refreshWhenVisible)\n quotaFollowUp.current?.cancel()\n }\n }, [loadStatus])\n\n const handleLogin = async () => {\n try {\n setBusy('login')\n setError(null)\n setValidationUrl(null)\n setLoginProgress(null)\n const flow = await api.request<{ authUrl?: string; status?: string }>('/login', { method: 'POST' })\n if (flow.authUrl) {\n window.open(flow.authUrl, '_blank')\n }\n const pollTimer = setInterval(async () => {\n try {\n const pollStatus = await api.request<{\n status: string\n error?: string\n validationUrl?: string\n progress?: string\n }>('/login/status')\n if (pollStatus.progress) {\n setLoginProgress(pollStatus.progress)\n }\n if (pollStatus.status === 'complete') {\n clearInterval(pollTimer)\n setBusy(null)\n setLoginProgress(null)\n await loadStatus()\n notifyChange()\n } else if (pollStatus.status === 'error') {\n clearInterval(pollTimer)\n setBusy(null)\n setLoginProgress(null)\n setError(pollStatus.error || t.loginFailed)\n if (pollStatus.validationUrl) {\n setValidationUrl(pollStatus.validationUrl)\n }\n }\n } catch {\n // ignore\n }\n }, 1500)\n\n setTimeout(() => {\n clearInterval(pollTimer)\n setBusy(null)\n setLoginProgress(null)\n }, 5 * 60 * 1000)\n } catch (err) {\n setBusy(null)\n setLoginProgress(null)\n setError(err instanceof Error ? err.message : String(err))\n }\n }\n\n const handleRefreshQuota = async () => {\n try {\n setBusy('quota')\n setError(null)\n const updated = await api.request<AntigravityWebStatus>('/quota', { method: 'POST' })\n setStatus(updated)\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n } finally {\n setBusy(null)\n }\n }\n\n const handleLogout = async () => {\n try {\n setBusy('logout')\n setError(null)\n const updated = await api.request<AntigravityWebStatus>('/logout', { method: 'POST' })\n setStatus(updated)\n notifyChange()\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n } finally {\n setBusy(null)\n }\n }\n\n const handleSetPrimary = async (accountId: string) => {\n try {\n setBusy(`primary-${accountId}`)\n setError(null)\n const updated = await api.request<AntigravityWebStatus>('/accounts', {\n method: 'POST',\n body: JSON.stringify({ action: 'set-primary', accountId }),\n })\n setStatus(updated)\n notifyChange()\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n } finally {\n setBusy(null)\n }\n }\n\n const handleDeleteAccount = async (accountId: string) => {\n try {\n setBusy(`delete-${accountId}`)\n setError(null)\n const updated = await api.request<AntigravityWebStatus>('/accounts', {\n method: 'POST',\n body: JSON.stringify({ action: 'delete', accountId }),\n })\n setStatus(updated)\n notifyChange()\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n } finally {\n setBusy(null)\n }\n }\n\n const handleClearCooldown = async (accountId: string) => {\n try {\n setBusy(`cooldown-${accountId}`)\n setError(null)\n const updated = await api.request<AntigravityWebStatus>('/accounts', {\n method: 'POST',\n body: JSON.stringify({ action: 'clear-cooldown', accountId }),\n })\n setStatus(updated)\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n } finally {\n setBusy(null)\n }\n }\n\n const handleSetStrategy = async (strategy: AccountRotationStrategy) => {\n try {\n setBusy('strategy')\n setError(null)\n const updated = await api.request<AntigravityWebStatus>('/accounts', {\n method: 'POST',\n body: JSON.stringify({ action: 'strategy', strategy }),\n })\n setStatus(updated)\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n } finally {\n setBusy(null)\n }\n }\n\n const toggleModel = async (modelId: string, checked: boolean) => {\n if (!status) return\n const currentEnabled = status.models.filter((m) => m.enabled).map((m) => m.id)\n const nextEnabled = checked\n ? [...new Set([...currentEnabled, modelId])]\n : currentEnabled.filter((id) => id !== modelId)\n\n try {\n const updated = await api.request<AntigravityWebStatus>('/models', {\n method: 'POST',\n body: JSON.stringify({ enabledModelIds: nextEnabled }),\n })\n setStatus(updated)\n // A model that was just checked has no draft yet; the context window\n // section only renders enabled models.\n setContextDrafts(contextDraftsFor(updated))\n notifyChange()\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n }\n }\n\n const setAllModels = async (selectAll: boolean) => {\n if (!status) return\n const nextEnabled = selectAll ? status.models.map((m) => m.id) : []\n try {\n const updated = await api.request<AntigravityWebStatus>('/models', {\n method: 'POST',\n body: JSON.stringify({ enabledModelIds: nextEnabled }),\n })\n setStatus(updated)\n setContextDrafts(contextDraftsFor(updated))\n notifyChange()\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n }\n }\n\n const handleUpdateEffort = async (effort: 'low' | 'medium' | 'high' | null) => {\n try {\n const updated = await api.request<AntigravityWebStatus>('/settings', {\n method: 'POST',\n body: JSON.stringify({ defaultReasoningEffort: effort }),\n })\n setStatus(updated)\n notifyChange()\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n }\n }\n\n const handleSaveContextWindow = async (modelId: string) => {\n const raw = contextDrafts[modelId] || ''\n const parsed = parsePositiveCapacity(raw)\n if (parsed === null) {\n setError(`无效的上下文容量值: ${raw}`)\n return\n }\n\n try {\n setSavingModel(modelId)\n setError(null)\n const updated = await api.request<AntigravityWebStatus>('/settings', {\n method: 'POST',\n body: JSON.stringify({\n contextWindowOverrides: {\n [modelId]: parsed,\n },\n }),\n })\n setStatus(updated)\n setContextDrafts((prev) => ({ ...prev, [modelId]: formatCapacity(parsed) }))\n notifyChange()\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n } finally {\n setSavingModel(null)\n }\n }\n\n /** Clear one override; the row falls back to the catalog length. */\n const handleResetContextWindow = async (modelId: string) => {\n try {\n setSavingModel(modelId)\n setError(null)\n const updated = await api.request<AntigravityWebStatus>('/settings', {\n method: 'POST',\n body: JSON.stringify({ contextWindowOverrides: { [modelId]: null } }),\n })\n setStatus(updated)\n setContextDrafts((prev) => {\n const model = updated.models.find((candidate) => candidate.id === modelId)\n return model === undefined ? prev : { ...prev, [modelId]: formatCapacity(model.defaultContextWindow) }\n })\n notifyChange()\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n } finally {\n setSavingModel(null)\n }\n }\n\n /** Clear every stored override, including models the picker no longer shows. */\n const handleResetAllContextWindows = async () => {\n const models = Object.keys(status?.contextWindowOverrides ?? {})\n if (models.length === 0) return\n if (typeof window !== 'undefined' && !window.confirm(t.contextWindowResetAllConfirm)) return\n try {\n setBusy('context')\n setError(null)\n const updated = await api.request<AntigravityWebStatus>('/settings', {\n method: 'POST',\n body: JSON.stringify({ contextWindowOverrides: Object.fromEntries(models.map((model) => [model, null])) }),\n })\n setStatus(updated)\n setContextDrafts(contextDraftsFor(updated))\n notifyChange()\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n } finally {\n setBusy(null)\n }\n }\n\n // Only checked models get a context row; the batch restore still covers every\n // stored override, including one left behind by a model the user unchecked.\n const contextModels = status?.models.filter((model) => model.enabled) ?? []\n const overrideCount = Object.keys(status?.contextWindowOverrides ?? {}).length\n\n if (loading) {\n return (\n <div className=\"dsha-page\">\n <div className=\"dsha-empty\">{t.loading}</div>\n </div>\n )\n }\n\n const quota = status?.quota\n const groups = quota?.groups || []\n const visibleCount = status?.models.filter((m) => m.enabled).length || 0\n\n return (\n <div className=\"dsha-page\">\n {/* 1. 账号管理分组:与其余三条线路共用同一张账号卡片 */}\n <AccountPoolSection\n accounts={status?.accounts ?? []}\n activeAccountId={status?.activeAccountId}\n rotationStrategy={status?.rotationStrategy ?? 'sequential'}\n busy={busy}\n labels={t}\n loginBusyLabel={busy === 'login' ? (loginProgress || t.signingIn) : undefined}\n onLogin={() => void handleLogin()}\n onSetPrimary={(accountId) => void handleSetPrimary(accountId)}\n onDelete={(accountId) => void handleDeleteAccount(accountId)}\n onClearCooldown={(accountId) => void handleClearCooldown(accountId)}\n onSetStrategy={(strategy) => void handleSetStrategy(strategy)}\n // Quota follows the account, so a row draws the snapshot the host holds\n // for that account rather than one line-level figure.\n showQuota\n // Only what the shared card cannot know: the line's own project id.\n // E-mail, expiry and last-used are the shared card's rows, and rendering\n // them here printed each of them twice.\n renderDetails={(account) => (\n <span>{t.accountId}: {account.projectId || 'antigravity-default'}</span>\n )}\n />\n\n {/* 2. 模型选择:这一组现在只做模型,连接事实(开关 / Provider / 连接状态)\n 已删——开关在概览卡片上,Provider 与「已连接」是内部细节。 */}\n <section className=\"dsha-group\">\n <div className=\"dsha-grouphead\">\n <h3>{t.modelsSection}</h3>\n </div>\n <p className=\"dsha-muted dsha-models-hint\">{t.modelsHint}</p>\n\n <ModelChecklist\n items={(status?.models ?? []).map((model) => ({\n id: model.id,\n name: model.name,\n hint: model.defaultContextWindow ? formatCapacity(model.defaultContextWindow) : undefined,\n enabled: model.enabled,\n }))}\n busy={busy !== null}\n onToggle={(id, enabled) => void toggleModel(id, enabled)}\n onToggleAll={setAllModels}\n labels={{ selectAll: t.selectAll, clearAll: t.unselectAll, list: t.modelsSection }}\n />\n </section>\n\n {/* 3. 增强功能(思考深度设置) */}\n <section className=\"dsha-group\">\n <div className=\"dsha-grouphead\">\n <h3>{t.enhanced}</h3>\n </div>\n <div className=\"dsha-pref-row\">\n <div>\n <strong>{t.defaultReasoningEffort}</strong>\n <p className=\"dsha-muted\">{t.defaultReasoningEffortHint}</p>\n </div>\n <select\n className=\"dsha-select\"\n aria-label={t.defaultReasoningEffort}\n value={status?.defaultReasoningEffort ?? ''}\n disabled={busy !== null}\n onChange={(e) => {\n const val = e.currentTarget.value\n void handleUpdateEffort(val === '' ? null : (val as 'low' | 'medium' | 'high'))\n }}\n >\n <option value=\"\">{t.defaultEffortAuto}</option>\n <option value=\"low\">Low</option>\n <option value=\"medium\">Medium</option>\n <option value=\"high\">High</option>\n </select>\n </div>\n </section>\n\n {/* 4. 模型上下文窗口设置(按模型独立配置) */}\n <section className=\"dsha-group\">\n <div className=\"dsha-grouphead\">\n <h3>{t.contextWindowSection}</h3>\n </div>\n <p className=\"dsha-muted\">{t.contextWindowHint}</p>\n\n <ContextWindowEditor\n rows={contextModels.map((model) => ({\n id: model.id,\n name: model.name,\n draft: contextDrafts[model.id] ?? '',\n hasOverride: status?.contextWindowOverrides[model.id] !== undefined,\n saving: savingModel === model.id,\n }))}\n labels={{\n tokens: t.tokens,\n save: t.save,\n saving: t.saving,\n reset: t.contextWindowReset,\n resetAll: t.contextWindowResetAll,\n empty: t.contextWindowNoneEnabled,\n }}\n busy={busy !== null}\n overrideCount={overrideCount}\n onDraftChange={(id, draft) => setContextDrafts((prev) => ({ ...prev, [id]: draft }))}\n onCommit={(id) => void handleSaveContextWindow(id)}\n onReset={(id) => void handleResetContextWindow(id)}\n onResetAll={() => void handleResetAllContextWindows()}\n />\n </section>\n\n {/* 5. 用量与配额卡片 */}\n <section className=\"dsha-group\">\n <div className=\"dsha-grouphead\">\n <h3>{t.quotaSection}</h3>\n <button\n className=\"dsha-btn\"\n disabled={busy !== null || !status?.authenticated}\n onClick={handleRefreshQuota}\n >\n {busy === 'quota' ? t.refreshingQuota : t.refreshQuota}\n </button>\n </div>\n <p className=\"dsha-muted\">{t.quotaDesc}</p>\n {/* The per-group/bucket rows went with the bars: every one of them — the\n remaining share, the reset countdown, the group and bucket names —\n is drawn on the account card now, where the snapshot actually\n belongs. What stays is what has no account-row home: the refresh\n action, the reading's freshness and the states below. */}\n <p className=\"dsha-muted\">{t.quotaFactsScope}</p>\n\n {!status?.authenticated\n ? <div className=\"dsha-empty\">{t.signedOut}</div>\n : groups.length === 0\n ? <div className=\"dsha-empty\">{busy === 'quota' ? t.refreshingQuota : t.quotaEmpty}</div>\n : null}\n\n {quota?.fetchedAt && (\n <div className=\"dsha-timestamp\">\n 更新时间: {new Date(quota.fetchedAt).toLocaleString()}\n </div>\n )}\n </section>\n\n {error && (\n <div className=\"dsha-error\">\n <div>{error}</div>\n {validationUrl && (\n <div style={{ marginTop: '8px' }}>\n <a\n href={validationUrl}\n target=\"_blank\"\n rel=\"noreferrer\"\n className=\"dsha-btn dsha-btn-primary\"\n style={{ display: 'inline-block', textDecoration: 'none', padding: '4px 10px', fontSize: '12px' }}\n >\n {t.googleValidation}\n </a>\n </div>\n )}\n </div>\n )}\n </div>\n )\n}\n","/**\n * Wire contracts between the Command Code host routes and the browser settings\n * card. Everything here is public: no credential ever crosses this boundary.\n */\n\nimport type {\n AccountRotationStrategy,\n PoolAccountSummaryDto,\n} from './account-pool-contracts.ts'\n\n/** Deployment of the Command Code API a credential was issued against. */\nexport type CommandCodeApiEnv = 'prod' | 'staging' | 'local'\n\n/**\n * Reasoning levels this route can expose. The exact set is per model —\n * `minimal` is the cheapest budget, `xhigh` sits between `high` and `max`, and\n * most models declare only a subset.\n *\n * `none` means \"do not think\". Command Code declares that level as `off` in its\n * own registry; the host translates it on the way out (the wire expresses it by\n * OMITTING the reasoning field entirely), so this vocabulary — and therefore\n * the settings card and DSH's picker — uses the name DSH already knows, the\n * same one the Kimi and Claude lines use.\n */\nexport type CommandCodeReasoningEffort = 'none' | 'minimal' | 'low' | 'medium' | 'high' | 'xhigh' | 'max'\n\n/** Every level, in escalating order; the settings card renders exactly these. */\nexport const COMMAND_CODE_REASONING_EFFORTS: readonly CommandCodeReasoningEffort[] =\n ['none', 'minimal', 'low', 'medium', 'high', 'xhigh', 'max']\n\n/** One model offered by the Command Code provider API. */\nexport interface CommandCodeModelOption {\n id: string\n name: string\n /** Enabled models are the ones DSH offers in the conversation model picker. */\n enabled: boolean\n /** Context window the live catalog reports for this model. */\n defaultContextWindow: number\n /** Effective context window: the override when one is saved, else the default. */\n contextWindow: number\n /** Maximum output tokens this route requests when a caller omits one. */\n defaultMaxTokens: number\n /** Reasoning levels this route exposes; absent for non-reasoning models. */\n reasoningEfforts?: string[]\n /** Reasoning dialect the adapter uses on the wire. */\n wire: CommandCodeWire\n}\n\n/**\n * Request/response dialect a model id is served over.\n *\n * The provider serves each model on exactly one route and answers 400 on the\n * wrong one, so this is a routing fact rather than a presentation choice.\n * `responses` is the OpenAI Responses API, which several GPT models require:\n * sending them to Chat Completions is a rejected request, not a degraded one.\n */\nexport type CommandCodeWire = 'openai' | 'anthropic' | 'responses'\n\n/** One credit / spend meter reported by the billing service. */\nexport interface CommandCodeMeter {\n id: string\n label: string\n /** Used fraction in [0, 1] when the service reports a bounded allowance. */\n usedFraction: number | null\n /** Remaining fraction in [0, 1], when the service reports one. */\n remainingFraction: number | null\n used: string | null\n limit: string | null\n /** Unix milliseconds the meter resets, when reported. */\n resetsAt: number | null\n description: string | null\n}\n\n/** Windowed request/token allowance reported by the usage service. */\nexport interface CommandCodeUsageWindow {\n id: string\n label: string\n usedPercent: number\n windowDurationMins: number | null\n resetsAt: number | null\n}\n\n/** Account identity returned by `/alpha/whoami`. */\nexport interface CommandCodeAccount {\n userId: string | null\n userName: string | null\n email: string | null\n organizationName: string | null\n keyName: string | null\n planLabel: string | null\n planId: string | null\n authenticatedAt: number | null\n}\n\n/** One point-in-time quota snapshot for the signed-in Command Code account. */\nexport interface CommandCodeAccountQuota {\n account: CommandCodeAccount\n /** Credit balance in the provider's own unit, when reported. */\n creditBalance: string | null\n /** True when the plan bills against an unlimited allowance. */\n unlimited: boolean\n /** Machine id the service reports, e.g. `individual-goat`. */\n planId: string | null\n /** Display name for {@link planId}, e.g. `GOAT`. */\n planName: string | null\n /** Monthly credits the plan grants, when the id is recognized. */\n planMonthlyCredits: number | null\n /** Subscription state the service reports, e.g. `active`. */\n subscriptionStatus: string | null\n /** End of the current billing period, as Unix milliseconds. */\n periodEndsAt: number | null\n meters: CommandCodeMeter[]\n windows: CommandCodeUsageWindow[]\n /** Raw service payloads, kept for diagnostics in the settings card. */\n fetchedAt: number\n sources: string[]\n}\n\n/** Everything the settings card and the composer badge render. */\nexport interface CommandCodeWebStatus {\n enabled?: boolean\n authenticated: boolean\n hasCredentials: boolean\n storagePath: string\n apiEnv: CommandCodeApiEnv\n account: CommandCodeAccount | null\n quota: CommandCodeAccountQuota | null\n lastFetchedAt: number | null\n /**\n * Whether a quota refresh is running behind this answer.\n *\n * The card renders the snapshot it already had instead of waiting on the\n * upstream request; when this is true the client asks again shortly so the\n * refreshed snapshot reaches the UI.\n */\n quotaRefreshing?: boolean\n /** Unix milliseconds the model catalog was fetched, when known. */\n catalogFetchedAt?: number | null\n /** True when the catalog in memory or storage is stale and awaiting revalidation. */\n catalogStale?: boolean\n /** Whether Zero Data Retention (ZDR) routing is active for Command Code requests. */\n zeroDataRetention?: boolean\n models: CommandCodeModelOption[]\n contextWindowOverrides: Record<string, number>\n defaultReasoningEffort: CommandCodeReasoningEffort | null\n /** Signed-in keys; empty or absent when no pool is installed. */\n accounts?: CommandCodeAccountSummaryDto[]\n /** Account the next request would use. */\n activeAccountId?: string\n rotationStrategy?: AccountRotationStrategy\n /** Route the plugin currently serves; false when another plugin owns it. */\n serving: boolean\n /** Diagnostic when the route is owned by a different adapter family. */\n conflict: string | null\n}\n\n/** One pooled key as the settings card renders it; never carries the key itself. */\nexport interface CommandCodeAccountSummaryDto extends PoolAccountSummaryDto {\n userName?: string\n keyName?: string\n organizationName?: string\n planId?: string\n userId?: string\n}\n\n/** Patch accepted by the models/settings routes. */\nexport interface CommandCodeSettingsUpdateDto {\n enabled?: boolean\n enabledModelIds?: string[]\n /** A number sets an override for that model; `null` restores the catalog default. */\n contextWindowOverrides?: Record<string, number | null>\n defaultReasoningEffort?: CommandCodeReasoningEffort | null\n}\n\n/** Result of a manual API-key submission or a compatibility probe. */\nexport interface CommandCodeConnectionDto {\n connected: boolean\n account: CommandCodeAccount | null\n checkedAt: number\n}\n","import { accountPoolEn, accountPoolZh } from '../common/account-pool-labels.ts'\n\nexport const NS_COMMAND_CODE = 'dsh-command-code'\n\nexport const zh = {\n // The account-management card is shared with every other provider tab, so its\n // labels come from one place instead of drifting per provider.\n ...accountPoolZh,\n title: 'Command Code',\n pageDesc: '登录 Command Code,管理可用模型、上下文窗口与额度。',\n account: '账号',\n signedIn: '已登录',\n signedOut: '未登录',\n keyName: '密钥名称',\n organization: '组织',\n plan: '套餐',\n planUnknown: '—',\n subscription: '订阅状态',\n renews: '续费于',\n authenticatedAt: '登录时间',\n signIn: '浏览器登录',\n signInAgain: '重新登录',\n signingIn: '登录中...',\n signOut: '注销',\n cancelSignIn: '取消登录',\n openSignInPage: '打开登录页面',\n apiKeySection: '手动填写 API Key',\n apiKeyHint: '在 Command Code Studio 创建 API Key 后粘贴到此处;浏览器登录不可用时使用。',\n apiKeyPlaceholder: '粘贴 Command Code API Key',\n apiKeySave: '保存并验证',\n apiKeySaving: '验证中...',\n apiKeySaved: '已保存',\n connection: '连接',\n testConnection: '测试连接',\n testingConnection: '测试中...',\n routeOwned: '模型路由由本插件提供',\n routeConflict: '模型路由已被其他 Provider 占用:{detail}。请在 DSH 设置中移除重复的 Provider 配置后重试。',\n modelsSection: '模型',\n modelsHint: '勾选后模型才会出现在对话页的模型选择列表中;全部取消勾选或关闭概览卡片上的开关可在列表中隐藏该供应商。',\n refreshCatalog: '刷新模型目录',\n refreshingCatalog: '刷新中...',\n catalogStale: '目录来自缓存,可能过期;可手动刷新',\n catalogFresh: '目录已同步',\n zdrEnabled: '已请求零数据保留(ZDR);服务端无符合条件的路由时将拒绝请求,不自动降低隐私要求。',\n selectAll: '全选',\n unselectAll: '全不选',\n wireAnthropic: 'Anthropic',\n wireOpenai: 'OpenAI',\n wireResponses: 'OpenAI Responses',\n enhanced: '增强功能',\n defaultReasoningEffort: '默认思考深度',\n defaultReasoningEffortHint: '控制支持推理的模型在未单独指定时的思考强度。Anthropic 模型会映射为 thinking 预算。',\n defaultEffortAuto: '使用 Provider 默认值',\n contextWindowSection: '模型上下文窗口',\n contextWindowHint: '默认取 Command Code 模型目录的 context length;可覆盖为自定义容量,该值用于 DSH 的压缩与溢出判断,可输入 1M、512K、200K 等容量。',\n contextWindowReset: '恢复默认',\n contextWindowResetAll: '全部恢复默认',\n contextWindowResetAllConfirm: '确定把已改过的模型上下文窗口全部恢复为默认值吗?',\n contextWindowNoneEnabled: '还没有勾选任何模型。在上方勾选后,这里会出现该模型的上下文窗口设置。',\n save: '保存',\n saved: '已保存',\n saving: '保存中...',\n quotaSection: '用量与配额',\n quotaDesc: '数据来自 Command Code 账户接口,页面可见时最多每 60 秒刷新一次。',\n refreshQuota: '刷新用量',\n refreshingQuota: '刷新中...',\n quotaEmpty: '暂无配额数据,点击「刷新用量」重试。',\n quotaCredits: '剩余额度',\n quotaUnlimited: '不限量',\n updatedAt: '更新时间:{time}',\n loading: '加载中...',\n loginFailed: '登录失败',\n tokens: 'tokens',\n} as const\n\nexport const en: Record<keyof typeof zh, string> = {\n ...accountPoolEn,\n title: 'Command Code',\n pageDesc: 'Sign in to Command Code and manage models, context windows, and quota.',\n account: 'Account',\n signedIn: 'Signed in',\n signedOut: 'Not signed in',\n keyName: 'Key name',\n organization: 'Organization',\n plan: 'Plan',\n planUnknown: '—',\n subscription: 'Subscription',\n renews: 'renews',\n authenticatedAt: 'Signed in at',\n signIn: 'Sign in with browser',\n signInAgain: 'Sign in again',\n signingIn: 'Signing in...',\n signOut: 'Sign out',\n cancelSignIn: 'Cancel',\n openSignInPage: 'Open the sign-in page',\n apiKeySection: 'Paste an API key',\n apiKeyHint: 'Create a key in Command Code Studio and paste it here; use this when the browser flow is unavailable.',\n apiKeyPlaceholder: 'Command Code API key',\n apiKeySave: 'Save and verify',\n apiKeySaving: 'Verifying...',\n apiKeySaved: 'Saved',\n connection: 'Connection',\n testConnection: 'Test connection',\n testingConnection: 'Testing...',\n routeOwned: 'This plugin serves the model route',\n routeConflict: 'Another provider already owns the model route: {detail}. Remove the duplicate provider configuration in DSH settings and reload.',\n modelsSection: 'Models',\n modelsHint: 'Checked models appear in the DSH conversation model list; unchecking all or turning off the switch on the overview card hides this provider.',\n refreshCatalog: 'Refresh catalog',\n refreshingCatalog: 'Refreshing...',\n catalogStale: 'Cached catalog may be stale; refresh to revalidate',\n catalogFresh: 'Catalog synchronized',\n zdrEnabled: 'Zero Data Retention requested; requests fail closed if no compliant route is available.',\n selectAll: 'Select all',\n unselectAll: 'Deselect all',\n wireAnthropic: 'Anthropic',\n wireOpenai: 'OpenAI',\n wireResponses: 'OpenAI Responses',\n enhanced: 'Enhanced features',\n defaultReasoningEffort: 'Default reasoning effort',\n defaultReasoningEffortHint: 'Reasoning effort for models that support it when the conversation does not specify one. Anthropic models map it to a thinking budget.',\n defaultEffortAuto: 'Use provider default',\n contextWindowSection: 'Model context window',\n contextWindowHint: 'Defaults to the context length in the Command Code catalog; override it with the capacity DSH should use for compaction and overflow decisions (e.g., 1M, 512K, 200K).',\n contextWindowReset: 'Restore default',\n contextWindowResetAll: 'Restore all defaults',\n contextWindowResetAllConfirm: 'Restore every changed model context window to its default?',\n contextWindowNoneEnabled: 'No model is checked yet. Check one above and its context window setting appears here.',\n save: 'Save',\n saved: 'Saved',\n saving: 'Saving...',\n quotaSection: 'Usage & quota',\n quotaDesc: 'Read from the Command Code account endpoints; refreshes at most once every 60 seconds while visible.',\n refreshQuota: 'Refresh quota',\n refreshingQuota: 'Refreshing...',\n quotaEmpty: 'No quota data yet — use “Refresh quota” to retry.',\n quotaCredits: 'Remaining credits',\n quotaUnlimited: 'Unlimited',\n updatedAt: 'Updated at: {time}',\n loading: 'Loading...',\n loginFailed: 'Sign-in failed',\n tokens: 'tokens',\n} as const\n\nexport const dictionaries = {\n zh,\n 'zh-CN': zh,\n en,\n 'en-US': en,\n}\n\nexport type CommandCodeLocaleKey = keyof typeof zh\n","import React, { useCallback, useEffect, useRef, useState } from 'react'\nimport type {\n CommandCodeModelOption,\n CommandCodeReasoningEffort,\n CommandCodeWebStatus,\n CommandCodeWire,\n} from '../../shared/command-code-contracts.ts'\nimport { COMMAND_CODE_REASONING_EFFORTS } from '../../shared/command-code-contracts.ts'\nimport { createQuotaFollowUp, type QuotaFollowUp } from '../common/quota-follow-up.ts'\n\n/**\n * Display label per reasoning level. The locale dictionary only accepts flat\n * string values, so this nested table lives with the control that renders it.\n */\nconst EFFORT_LABELS: Record<CommandCodeReasoningEffort, string> = {\n none: 'Off',\n minimal: 'Minimal',\n low: 'Low',\n medium: 'Medium',\n high: 'High',\n xhigh: 'X-High',\n max: 'Max',\n}\nimport { AccountPoolSection } from '../common/AccountPoolSection.tsx'\nimport { ContextWindowEditor, contextDraftsFor } from '../common/ContextWindowEditor.tsx'\nimport { ModelChecklist } from '../common/ModelChecklist.tsx'\nimport { createLineApi } from '../common/line-api.ts'\nimport { formatCapacity, formatDate, parsePositiveCapacity } from '../common/format.ts'\nimport type { AccountRotationStrategy } from '../../shared/account-pool-contracts.ts'\nimport { zh } from './locales.ts'\n\nconst API = '/command-code/api'\nconst api = createLineApi(API, 'Command Code')\n\ninterface Props {\n onModelChange?: () => void\n loadModelDirectory?: () => void\n}\n\ninterface LoginPollStatus {\n status: string\n authUrl?: string\n error?: string\n progress?: string\n}\n\n/**\n * Route name shown next to a model.\n *\n * The three routes are not interchangeable: the provider serves each model on\n * exactly one and rejects the others, so the label states which one this model\n * actually uses.\n */\nfunction wireLabel(wire: CommandCodeWire, t: { wireAnthropic: string; wireOpenai: string; wireResponses: string }): string {\n if (wire === 'anthropic') return t.wireAnthropic\n if (wire === 'responses') return t.wireResponses\n return t.wireOpenai\n}\n\nexport function CommandCodeSection({ onModelChange, loadModelDirectory }: Props): React.ReactElement {\n const [status, setStatus] = useState<CommandCodeWebStatus | null>(null)\n const [loading, setLoading] = useState(true)\n const [busy, setBusy] = useState<string | null>(null)\n const [error, setError] = useState<string | null>(null)\n const [loginProgress, setLoginProgress] = useState<string | null>(null)\n const [contextDrafts, setContextDrafts] = useState<Record<string, string>>({})\n const [savingModel, setSavingModel] = useState<string | null>(null)\n const [apiKey, setApiKey] = useState('')\n\n /** Follow-up poll owed while the host refreshes the quota behind an answer. */\n const quotaFollowUp = useRef<QuotaFollowUp | null>(null)\n\n const t = zh\n\n const notifyChange = useCallback(() => {\n onModelChange?.()\n loadModelDirectory?.()\n }, [onModelChange, loadModelDirectory])\n\n const loadStatus = useCallback(async (quiet = false) => {\n if (!quiet) {\n setError(null)\n }\n try {\n const data = await api.request<CommandCodeWebStatus>('/status')\n setStatus(data)\n setContextDrafts(contextDraftsFor(data))\n // An answer that refreshed the quota behind itself is followed up shortly,\n // so the fresh numbers land without waiting for the next poll.\n quotaFollowUp.current ??= createQuotaFollowUp()\n quotaFollowUp.current.observe(data.quotaRefreshing === true, () => { void loadStatus(true) })\n } catch (err) {\n if (!quiet) setError(err instanceof Error ? err.message : String(err))\n } finally {\n setLoading(false)\n }\n }, [])\n\n useEffect(() => {\n void loadStatus()\n const refreshWhenVisible = () => {\n if (document.visibilityState === 'visible') void loadStatus(true)\n }\n document.addEventListener('visibilitychange', refreshWhenVisible)\n const timer = window.setInterval(refreshWhenVisible, 60_000)\n return () => {\n window.clearInterval(timer)\n document.removeEventListener('visibilitychange', refreshWhenVisible)\n quotaFollowUp.current?.cancel()\n }\n }, [loadStatus])\n\n const handleLogin = async () => {\n try {\n setBusy('login')\n setError(null)\n setLoginProgress(null)\n const flow = await api.request<LoginPollStatus>('/login', { method: 'POST' })\n if (flow.authUrl) {\n window.open(flow.authUrl, '_blank')\n }\n const pollTimer = window.setInterval(() => {\n void (async () => {\n try {\n const poll = await api.request<LoginPollStatus>('/login/status')\n if (poll.progress) setLoginProgress(poll.progress)\n if (poll.status === 'complete') {\n window.clearInterval(pollTimer)\n setBusy(null)\n setLoginProgress(null)\n await loadStatus()\n notifyChange()\n } else if (poll.status === 'error') {\n window.clearInterval(pollTimer)\n setBusy(null)\n setLoginProgress(null)\n setError(poll.error || t.loginFailed)\n }\n } catch {\n // A failed poll is transient; the next tick retries.\n }\n })()\n }, 1500)\n window.setTimeout(() => {\n window.clearInterval(pollTimer)\n setBusy(null)\n setLoginProgress(null)\n }, 5 * 60 * 1000)\n } catch (err) {\n setBusy(null)\n setLoginProgress(null)\n setError(err instanceof Error ? err.message : String(err))\n }\n }\n\n const handleApiKey = async () => {\n try {\n setBusy('apikey')\n setError(null)\n const updated = await api.request<CommandCodeWebStatus>('/login/apikey', {\n method: 'POST',\n body: JSON.stringify({ apiKey }),\n })\n setStatus(updated)\n setApiKey('')\n notifyChange()\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n } finally {\n setBusy(null)\n }\n }\n\n /** One account-level action on the shared pool card. */\n const handleAccountAction = async (\n action: 'set-primary' | 'delete' | 'clear-cooldown',\n accountId: string,\n ) => {\n try {\n setBusy(`${action}-${accountId}`)\n setError(null)\n const updated = await api.request<CommandCodeWebStatus>('/accounts', {\n method: 'POST',\n body: JSON.stringify({ action, accountId }),\n })\n setStatus(updated)\n notifyChange()\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n } finally {\n setBusy(null)\n }\n }\n\n const handleSetStrategy = async (strategy: AccountRotationStrategy) => {\n try {\n setBusy('strategy')\n setError(null)\n const updated = await api.request<CommandCodeWebStatus>('/accounts', {\n method: 'POST',\n body: JSON.stringify({ action: 'strategy', strategy }),\n })\n setStatus(updated)\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n } finally {\n setBusy(null)\n }\n }\n\n /**\n * Re-authorize one key.\n *\n * Nothing is deleted: the failure marker is cleared and the ordinary sign-in\n * flow runs again, so the account keeps its alias and place in the rotation.\n */\n const handleRelogin = (accountId: string) => {\n void (async () => {\n try {\n const updated = await api.request<CommandCodeWebStatus>('/accounts', {\n method: 'POST',\n body: JSON.stringify({ action: 'relogin', accountId }),\n })\n setStatus(updated)\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n return\n }\n await handleLogin()\n })()\n }\n\n const handleRefreshQuota = async () => {\n try {\n setBusy('quota')\n setError(null)\n const updated = await api.request<CommandCodeWebStatus>('/quota', { method: 'POST' })\n setStatus(updated)\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n } finally {\n setBusy(null)\n }\n }\n\n const handleRefreshCatalog = async () => {\n try {\n setBusy('catalog')\n setError(null)\n const updated = await api.request<CommandCodeWebStatus>('/catalog/refresh', { method: 'POST' })\n setStatus(updated)\n setContextDrafts(contextDraftsFor(updated))\n notifyChange()\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n } finally {\n setBusy(null)\n }\n }\n\n const handleTestConnection = async () => {\n try {\n setBusy('connection')\n setError(null)\n await api.post('/connection/test')\n await loadStatus(true)\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n } finally {\n setBusy(null)\n }\n }\n\n const applyEnabled = async (enabledModelIds: string[]) => {\n try {\n const updated = await api.request<CommandCodeWebStatus>('/models', {\n method: 'POST',\n body: JSON.stringify({ enabledModelIds }),\n })\n setStatus(updated)\n // A model that was just checked has no draft yet; the context window\n // section only renders enabled models.\n setContextDrafts(contextDraftsFor(updated))\n notifyChange()\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n }\n }\n\n const toggleModel = (modelId: string, checked: boolean) => {\n if (!status) return\n const current = status.models.filter((model) => model.enabled).map((model) => model.id)\n const next = checked ? [...new Set([...current, modelId])] : current.filter((id) => id !== modelId)\n void applyEnabled(next)\n }\n\n const setAllModels = (selectAll: boolean) => {\n if (!status || status.models.length === 0) return\n void applyEnabled(selectAll ? status.models.map((model) => model.id) : [])\n }\n\n const handleUpdateEffort = async (effort: CommandCodeReasoningEffort | null) => {\n try {\n const updated = await api.request<CommandCodeWebStatus>('/settings', {\n method: 'POST',\n body: JSON.stringify({ defaultReasoningEffort: effort }),\n })\n setStatus(updated)\n notifyChange()\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n }\n }\n\n const handleSaveContextWindow = async (modelId: string) => {\n const raw = contextDrafts[modelId] || ''\n const parsed = parsePositiveCapacity(raw)\n if (parsed === null) {\n setError(`Invalid context capacity: ${raw}`)\n return\n }\n try {\n setSavingModel(modelId)\n setError(null)\n const updated = await api.request<CommandCodeWebStatus>('/settings', {\n method: 'POST',\n body: JSON.stringify({ contextWindowOverrides: { [modelId]: parsed } }),\n })\n setStatus(updated)\n setContextDrafts((prev) => ({ ...prev, [modelId]: formatCapacity(parsed) }))\n notifyChange()\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n } finally {\n setSavingModel(null)\n }\n }\n\n /** Clear one override; the row falls back to the catalog length. */\n const handleResetContextWindow = async (modelId: string) => {\n try {\n setSavingModel(modelId)\n setError(null)\n const updated = await api.request<CommandCodeWebStatus>('/settings', {\n method: 'POST',\n body: JSON.stringify({ contextWindowOverrides: { [modelId]: null } }),\n })\n setStatus(updated)\n setContextDrafts((prev) => {\n const model = updated.models.find((candidate) => candidate.id === modelId)\n return model === undefined ? prev : { ...prev, [modelId]: formatCapacity(model.defaultContextWindow) }\n })\n notifyChange()\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n } finally {\n setSavingModel(null)\n }\n }\n\n /** Clear every stored override, including models the picker no longer shows. */\n const handleResetAllContextWindows = async () => {\n const models = Object.keys(status?.contextWindowOverrides ?? {})\n if (models.length === 0) return\n if (typeof window !== 'undefined' && !window.confirm(t.contextWindowResetAllConfirm)) return\n try {\n setBusy('context')\n setError(null)\n const updated = await api.request<CommandCodeWebStatus>('/settings', {\n method: 'POST',\n body: JSON.stringify({ contextWindowOverrides: Object.fromEntries(models.map((model) => [model, null])) }),\n })\n setStatus(updated)\n setContextDrafts(contextDraftsFor(updated))\n notifyChange()\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n } finally {\n setBusy(null)\n }\n }\n\n // Only checked models get a context row; the batch restore still covers every\n // stored override, including one left behind by a model the user unchecked.\n const contextModels = status?.models.filter((model) => model.enabled) ?? []\n const overrideCount = Object.keys(status?.contextWindowOverrides ?? {}).length\n\n if (loading) {\n return (\n <div className=\"dsha-page\">\n <div className=\"dsha-empty\">{t.loading}</div>\n </div>\n )\n }\n\n const quota = status?.quota\n const account = status?.account\n const visibleCount = status?.models.filter((model) => model.enabled).length || 0\n\n return (\n <div className=\"dsha-page\">\n <AccountPoolSection\n accounts={status?.accounts ?? []}\n activeAccountId={status?.activeAccountId}\n rotationStrategy={status?.rotationStrategy ?? 'sequential'}\n busy={busy}\n labels={t}\n loginBusyLabel={busy === 'login' ? (loginProgress || t.signingIn) : undefined}\n onLogin={() => void handleLogin()}\n onSetPrimary={(accountId) => void handleAccountAction('set-primary', accountId)}\n onDelete={(accountId) => void handleAccountAction('delete', accountId)}\n onClearCooldown={(accountId) => void handleAccountAction('clear-cooldown', accountId)}\n onRelogin={(accountId) => handleRelogin(accountId)}\n onSetStrategy={(strategy) => void handleSetStrategy(strategy)}\n showQuota\n renderDetails={(entry) => (\n <>\n {entry.keyName && <span>{t.keyName}: {entry.keyName}</span>}\n {entry.planLabel && <span>{t.plan}: {entry.planLabel}</span>}\n </>\n )}\n >\n <p className=\"dsha-muted\" style={{ paddingTop: 12 }}>{t.apiKeyHint}</p>\n <div className=\"dsha-capacity-control\">\n <input\n type=\"password\"\n aria-label={t.apiKeySection}\n placeholder={t.apiKeyPlaceholder}\n value={apiKey}\n onChange={(event) => setApiKey(event.currentTarget.value)}\n onKeyDown={(event) => {\n if (event.key === 'Enter' && apiKey.trim() !== '') void handleApiKey()\n }}\n />\n <button\n type=\"button\"\n className=\"dsha-context-save\"\n disabled={busy !== null || apiKey.trim() === ''}\n onClick={() => void handleApiKey()}\n >\n {busy === 'apikey' ? t.apiKeySaving : t.apiKeySave}\n </button>\n </div>\n </AccountPoolSection>\n\n <section className=\"dsha-group\">\n <div className=\"dsha-grouphead\">\n <h3>{t.connection}</h3>\n </div>\n <p className=\"dsha-notice\">{status?.serving === false && status.conflict ? t.routeConflict.replace('{detail}', status.conflict) : t.routeOwned}</p>\n <div className=\"dsha-actions\">\n <button className=\"dsha-btn\" disabled={busy !== null || !status?.authenticated} onClick={() => void handleTestConnection()}>\n {busy === 'connection' ? t.testingConnection : t.testConnection}\n </button>\n </div>\n </section>\n\n <section className=\"dsha-group\">\n <div className=\"dsha-grouphead\">\n <h3>{t.modelsSection}</h3>\n <button className=\"dsha-btn\" disabled={busy !== null} onClick={() => void handleRefreshCatalog()}>\n {busy === 'catalog' ? t.refreshingCatalog : t.refreshCatalog}\n </button>\n </div>\n <p className=\"dsha-muted dsha-models-hint\">{t.modelsHint}</p>\n {status?.catalogStale !== undefined && (\n <p className=\"dsha-muted\" data-testid=\"command-code-catalog-freshness\">\n {status.catalogStale ? t.catalogStale : t.catalogFresh} · {formatDate(status.catalogFetchedAt)}\n </p>\n )}\n {status?.zeroDataRetention === true && <p className=\"dsha-notice\" data-testid=\"command-code-zdr\">{t.zdrEnabled}</p>}\n <ModelChecklist\n items={(status?.models ?? []).map((model: CommandCodeModelOption) => ({\n id: model.id,\n name: model.name,\n hint: wireLabel(model.wire, t),\n enabled: model.enabled,\n }))}\n busy={busy !== null}\n onToggle={toggleModel}\n onToggleAll={setAllModels}\n labels={{ selectAll: t.selectAll, clearAll: t.unselectAll, list: t.modelsSection }}\n />\n </section>\n\n <section className=\"dsha-group\">\n <div className=\"dsha-grouphead\">\n <h3>{t.enhanced}</h3>\n </div>\n <div className=\"dsha-pref-row\">\n <div>\n <strong>{t.defaultReasoningEffort}</strong>\n <p className=\"dsha-muted\">{t.defaultReasoningEffortHint}</p>\n </div>\n <select\n className=\"dsha-select\"\n aria-label={t.defaultReasoningEffort}\n value={status?.defaultReasoningEffort ?? ''}\n disabled={busy !== null}\n onChange={(event) => {\n const value = event.currentTarget.value\n void handleUpdateEffort(value === '' ? null : (value as CommandCodeReasoningEffort))\n }}\n >\n <option value=\"\">{t.defaultEffortAuto}</option>\n {COMMAND_CODE_REASONING_EFFORTS.map((effort) => (\n <option key={effort} value={effort}>{EFFORT_LABELS[effort]}</option>\n ))}\n </select>\n </div>\n </section>\n\n <section className=\"dsha-group\">\n <div className=\"dsha-grouphead\">\n <h3>{t.contextWindowSection}</h3>\n </div>\n <p className=\"dsha-muted\">{t.contextWindowHint}</p>\n <ContextWindowEditor\n rows={contextModels.map((model: CommandCodeModelOption) => ({\n id: model.id,\n name: model.name,\n draft: contextDrafts[model.id] ?? '',\n inputLabel: `${model.name} context window`,\n hasOverride: status?.contextWindowOverrides[model.id] !== undefined,\n saving: savingModel === model.id,\n }))}\n labels={{\n tokens: t.tokens,\n save: t.save,\n saving: t.saving,\n reset: t.contextWindowReset,\n resetAll: t.contextWindowResetAll,\n empty: t.contextWindowNoneEnabled,\n }}\n busy={busy !== null}\n overrideCount={overrideCount}\n onDraftChange={(id, draft) => setContextDrafts((prev) => ({ ...prev, [id]: draft }))}\n onCommit={(id) => void handleSaveContextWindow(id)}\n onReset={(id) => void handleResetContextWindow(id)}\n onResetAll={() => void handleResetAllContextWindows()}\n />\n </section>\n\n <section className=\"dsha-group\">\n <div className=\"dsha-grouphead\">\n <h3>{t.quotaSection}</h3>\n <button className=\"dsha-btn\" disabled={busy !== null || !status?.authenticated} onClick={() => void handleRefreshQuota()}>\n {busy === 'quota' ? t.refreshingQuota : t.refreshQuota}\n </button>\n </div>\n <p className=\"dsha-muted\">{t.quotaDesc}</p>\n {/* The progress bars moved into each account card: quota follows the\n account, so a bar here could only ever describe whichever account\n happened to be active when the snapshot was read. What stays is what\n has no per-account bar to live in — the credits, the meters that\n state no share, and the freshness of this reading. */}\n <p className=\"dsha-muted\">{t.quotaFactsScope}</p>\n\n {!status?.authenticated ? (\n <div className=\"dsha-empty\">{t.signedOut}</div>\n ) : quota === null || quota === undefined ? (\n <div className=\"dsha-empty\">{busy === 'quota' ? t.refreshingQuota : t.quotaEmpty}</div>\n ) : (\n <div className=\"dsha-quota-card\">\n <div className=\"dsha-quota-title\">\n <strong>{t.quotaCredits}</strong>\n <span>\n {quota.unlimited\n ? t.quotaUnlimited\n : quota.creditBalance !== null\n ? quota.creditBalance\n : '—'}\n </span>\n </div>\n\n {quota.meters.filter((meter) => meter.remainingFraction === null).map((meter) => (\n <div key={meter.id} className=\"dsha-meter-wrap\">\n <div className=\"dsha-meter-label\">\n <span>{meter.label}</span>\n <strong>{meter.limit ?? '—'}</strong>\n </div>\n {meter.used !== null && (\n <div className=\"dsha-meter-meta\"><span>{meter.used} / {meter.limit ?? '—'}</span></div>\n )}\n {meter.description !== null && (\n <div className=\"dsha-meter-meta\"><span>{meter.description}</span></div>\n )}\n </div>\n ))}\n\n {quota.meters.length === 0 && quota.windows.length === 0 && (\n <div className=\"dsha-empty\">{t.quotaEmpty}</div>\n )}\n\n <div className=\"dsha-timestamp\">\n {t.updatedAt.replace('{time}', new Date(quota.fetchedAt).toLocaleString())}\n </div>\n </div>\n )}\n </section>\n\n {error && (\n <div className=\"dsha-error\">\n <div>{error}</div>\n </div>\n )}\n </div>\n )\n}\n","/**\n * Wire contracts between the Kimi Code host routes and the browser settings\n * card. Everything here is public: no credential ever crosses this boundary.\n *\n * Kimi Code (https://www.kimi.com/code) is a Moonshot AI coding subscription,\n * distinct from the pay-as-you-go Moonshot Open Platform: its credentials come\n * from an OAuth device flow against auth.kimi.com and its inference lives at\n * https://api.kimi.com/coding/v1.\n */\n\nimport type { AccountRotationStrategy, PoolAccountSummaryDto } from './account-pool-contracts.ts'\n\n/** Region a Kimi Code account belongs to; decides which hosts the client uses. */\nexport type KimiCodeRegion = 'mainland-cn' | 'global'\n\n/**\n * Request/response dialect used for the model calls.\n *\n * The official Kimi Code CLI configures its managed provider as `type = \"kimi\"`,\n * an OpenAI-compatible chat-completions client, so that is the default here.\n * The Anthropic Messages dialect is offered too because the service documents\n * `https://api.kimi.com/coding/` as an Anthropic-compatible base URL for\n * third-party tools, and some models behave better with a thinking budget.\n */\nexport type KimiCodeWire = 'openai' | 'anthropic'\n\n/**\n * Thinking level a Kimi Code model accepts.\n *\n * Kimi Code maps a tool's effort onto exactly three K3 levels plus a thinking-off\n * switch. The documented mapping is authoritative and deliberately narrower than\n * the generic level set other providers use:\n *\n * - `low` <- `low` / `minimum` / `light`\n * - `high` <- `high` / `medium`\n * - `max` <- `ultra` / `max` / `xhigh`\n * - `none` -> thinking disabled (`thinking.type = \"disabled\"`)\n *\n * Anything else the client sends is rejected by the service with HTTP 400, so\n * no other level is ever put on the wire.\n */\nexport type KimiCodeReasoningEffort = 'low' | 'high' | 'max' | 'none'\n\n/**\n * Prompt-cache TTL the Kimi subscription accepts.\n *\n * The two wires spell the request differently (`prompt_cache_options` on the\n * OpenAI one, a TOP-LEVEL `cache_control` on the Anthropic one), but the tier\n * names are the same. `null` in the settings means \"send neither\", which is\n * the service's own default behaviour.\n */\nexport type KimiCodeCacheTtl = '5m' | '1h'\n\n/**\n * How the service says a model handles thinking, when it says so at all.\n *\n * The three-state declaration is strictly more informative than a boolean:\n * `only` distinguishes \"always reasons\" from \"no reasoning support\", which\n * a single boolean cannot express, and the two demand opposite treatment —\n * the first must not be offered a `none` effort, the second must be offered\n * nothing at all.\n */\nexport type KimiCodeThinkingType = 'only' | 'no' | 'both'\n\n/** Every level, in escalating order; the settings card renders exactly these. */\nexport const KIMI_CODE_REASONING_EFFORTS: readonly KimiCodeReasoningEffort[] =\n ['low', 'high', 'max', 'none']\n\n/** One model offered by the Kimi Code coding endpoint. */\nexport interface KimiCodeModelOption {\n id: string\n name: string\n /** Enabled models are the ones DSH offers in the conversation model picker. */\n enabled: boolean\n /** Context window the catalog reports for this model. */\n defaultContextWindow: number\n /** Effective context window: the override when one is saved, else the default. */\n contextWindow: number\n /**\n * Largest prompt the endpoint accepts, when the service states a cap below\n * the context window.\n *\n * A model can have a 1M window and a lower input limit. The window still\n * bounds the completion budget, but a prompt sized against it overshoots into\n * a rejected request instead of a compaction, so the two are reported\n * separately.\n */\n maxInputTokens?: number\n /**\n * Ceiling for the prompt of one turn.\n *\n * The smaller of the effective window and {@link maxInputTokens}; always a\n * number, so a caller never has to decide which of the two applies.\n */\n promptBudget: number\n /** Maximum output tokens this route requests when a caller omits one. */\n defaultMaxTokens: number\n /** Thinking levels this model accepts; absent for a model that cannot reason. */\n reasoningEfforts?: string[]\n /** Thinking level used when the conversation does not pick one. */\n defaultReasoningEffort?: string\n /** Request/response dialect the adapter uses on the wire. */\n wire: KimiCodeWire\n /** Human description from the official model table. */\n description: string | null\n /** Whether the model accepts video input as well as images. */\n supportsVideo: boolean\n /**\n * Whether the model accepts message-level tool declarations\n * (`messages[].tools`), Kimi's `dynamically_loaded_tools` capability.\n *\n * The card shows it because it is the one K3 feature that changes how a\n * client should be shaped rather than what it may send: a session that\n * progressively discloses tools keeps its top-level list stable, which is\n * what protects the prefix cache.\n */\n supportsDynamicTools: boolean\n /**\n * Whether the model accepts tool declarations at all.\n *\n * Wider than {@link supportsDynamicTools}, which asks only about message-level\n * declarations: a model may take tools at the top level and not per message.\n * The card shows both because a false here is the one that breaks every\n * coding session on the model.\n */\n supportsToolUse: boolean\n /** Subscription tier the model needs, when it is not open to every member. */\n minimumPlan: string | null\n}\n\n/** One quota window reported for the signed-in account. */\nexport interface KimiCodeUsageWindow {\n id: string\n label: string\n /** Used fraction in [0, 1]. */\n usedFraction: number\n /** Convenience integer for the card and badge. */\n usedPercent: number\n /** Nominal window length in minutes, when the service states one. */\n windowDurationMins: number | null\n /** Unix milliseconds the window resets, when reported. */\n resetsAt: number | null\n /** Allowance as the service reports it (request counts), when reported. */\n limit: string | null\n used: string | null\n remaining: string | null\n}\n\n/** Pay-as-you-go wallet the account can fall back on once a window is spent. */\nexport interface KimiCodeExtraUsage {\n /** Remaining wallet balance in the currency's minor unit. */\n balanceCents: number | null\n totalCents: number | null\n monthlyChargeLimitEnabled: boolean\n monthlyChargeLimitCents: number | null\n monthlyUsedCents: number | null\n currency: string | null\n}\n\n/** Account identity, resolved from the token and the usage response. */\nexport interface KimiCodeAccount {\n userId: string | null\n nickname: string | null\n email: string | null\n /** Subscription tier display name, for example Moderato. */\n planName: string | null\n /** Machine tier level when the service reports one. */\n planLevel: string | null\n region: KimiCodeRegion | null\n authenticatedAt: number | null\n}\n\n/** One point-in-time quota snapshot for the signed-in Kimi Code account. */\nexport interface KimiCodeAccountQuota {\n account: KimiCodeAccount\n /** Subscription tier display name, when the service reports one. */\n planName: string | null\n /** Every quota window the account currently has. */\n windows: KimiCodeUsageWindow[]\n /** Pay-as-you-go booster wallet, when the account has one. */\n extraUsage: KimiCodeExtraUsage | null\n /** Unix milliseconds this snapshot was fetched. */\n fetchedAt: number\n /** Endpoint paths that answered, kept for diagnostics in the card. */\n sources: string[]\n}\n\n/** Everything the settings card and the composer badge render. */\nexport interface KimiCodeWebStatus {\n enabled?: boolean\n authenticated: boolean\n hasCredentials: boolean\n storagePath: string\n region: KimiCodeRegion\n oauthHost: string\n codingBaseUrl: string\n account: KimiCodeAccount | null\n quota: KimiCodeAccountQuota | null\n lastFetchedAt: number | null\n /**\n * Whether a quota refresh is running behind this answer.\n *\n * The card renders the snapshot it already had instead of waiting on the\n * upstream request; when this is true the client asks again shortly so the\n * refreshed snapshot reaches the UI.\n */\n quotaRefreshing?: boolean\n /** When true the stored refresh token was rejected and sign-in is required. */\n credentialsRejected: boolean\n /**\n * Why the quota could not be read, when the last attempt failed.\n *\n * Reported beside the snapshot rather than in place of it: a transient\n * failure should explain itself without hiding the account that is signed in.\n */\n quotaError?: string | null\n /** Rolling prefix-cache effectiveness for this process, when requests ran. */\n cache: KimiCodeCacheStatsDto | null\n /**\n * Warning that this conversation's prompt cache has expired, when it has and\n * the context is large enough for reprocessing to be worth mentioning.\n */\n cacheHint?: KimiCodeCacheHintDto | null\n /** Whether Preserved Thinking is currently requested on the wire. */\n preserveThinking: boolean\n models: KimiCodeModelOption[]\n contextWindowOverrides: Record<string, number>\n defaultReasoningEffort: KimiCodeReasoningEffort | null\n /**\n * Prompt-cache tier this line asks for. `null` means \"send no cache field\",\n * which is Kimi's own default behaviour.\n */\n cacheTtl: KimiCodeCacheTtl | null\n /** Signed-in accounts; empty or absent when no pool is installed. */\n accounts?: KimiCodeAccountSummaryDto[]\n /** Account the next request would use. */\n activeAccountId?: string\n rotationStrategy?: AccountRotationStrategy\n /** Region used for the next login flow. */\n loginRegion: KimiCodeRegion\n /** Route the plugin currently serves; false when another plugin owns it. */\n serving: boolean\n /** Diagnostic when the route is owned by a different adapter family. */\n conflict: string | null\n}\n\n/**\n * How well Kimi's automatic prefix cache is working for this process.\n *\n * Reported because the cache is invisible otherwise: it is content-hash based\n * with no marker to set, so the read ratio is the only evidence a session is\n * actually reusing its prefix.\n */\nexport interface KimiCodeCacheStatsDto {\n requests: number\n cachedTokens: number\n freshTokens: number\n outputTokens: number\n /** Cached / (cached + fresh); null until a request reports usage. */\n hitRatio: number | null\n /**\n * Why the most recent request's prefix broke, when it did.\n *\n * Surfaces the diagnostic half of the hit ratio: `'stable'` means the prefix\n * should have held (so a miss implicates content below the head or the\n * service), while the other values name the input that invalidated the cache.\n */\n lastDrift?: 'first-request' | 'stable' | 'system-prompt' | 'tools' | 'cache-key' | 'cold-key'\n /**\n * Always 0 on this route: the endpoint writes cache entries without counting\n * them, so there is no write cost to track.\n *\n * Reported rather than dropped so the shape stays aligned with the sibling\n * providers that DO report writes, and so a route that starts counting them\n * needs no contract change.\n */\n cacheWriteTokensNote?: 'always-zero-on-this-route'\n}\n\n/**\n * A warning that the conversation's prompt cache has expired.\n *\n * Kimi's cache is content-hash based with no marker to set, so a client that\n * says nothing leaves the user paying a full reprocessing pass with no idea\n * why the next turn was slow. Absent means \"nothing to say\" — which is most\n * of the time, since the hint needs an idle period AND a context large enough\n * for reprocessing to matter.\n */\nexport interface KimiCodeCacheHintDto {\n /** How long the conversation has been idle, epoch ms. */\n idleMs: number\n /** Context that will be reprocessed on the next turn. */\n totalTokens: number\n}\n\n/** Patch accepted by the models/settings routes. */\nexport interface KimiCodeSettingsUpdateDto {\n enabled?: boolean\n enabledModelIds?: string[]\n /** A number sets an override for that model; `null` restores the catalog default. */\n contextWindowOverrides?: Record<string, number | null>\n defaultReasoningEffort?: KimiCodeReasoningEffort | null\n /** `null` clears the tier, returning to \"send no cache field\". */\n cacheTtl?: KimiCodeCacheTtl | null\n}\n\n/** One pooled Kimi Code account as the settings card renders it; never carries a token. */\nexport interface KimiCodeAccountSummaryDto extends PoolAccountSummaryDto {\n nickname?: string\n userId?: string\n planName?: string\n /** Region the credential was issued in; a pool may hold several. */\n region?: KimiCodeRegion\n}\n\n/** Live state of the device-code login flow the card polls. */\nexport interface KimiCodeLoginFlowStatus {\n status: 'idle' | 'pending' | 'complete' | 'error'\n /** Page the user must open, including the pre-filled user code. */\n verificationUriComplete?: string\n verificationUri?: string\n userCode?: string\n startedAt?: number\n completedAt?: number\n /** Unix milliseconds the device code stops being valid. */\n expiresAt?: number\n progress?: string\n error?: string\n}\n\n/** Result of an explicit connection test. */\nexport interface KimiCodeConnectionDto {\n connected: boolean\n latencyMs: number\n account: KimiCodeAccount | null\n}\n","import { accountPoolEn, accountPoolZh } from '../common/account-pool-labels.ts'\n\nexport const NS_KIMI_CODE = 'dsh-kimi-code'\n\nexport const zh = {\n // The account-management card is shared with every other provider tab.\n ...accountPoolZh,\n title: 'Kimi Code',\n pageDesc: '登录 Kimi Code 订阅,管理模型、思考档位、上下文窗口与额度。',\n account: '账号',\n signedIn: '已登录',\n signedOut: '未登录',\n nickname: '昵称',\n email: '邮箱',\n plan: '套餐',\n planUnknown: '—',\n region: '区域',\n regionMainland: '中国大陆 (kimi.com)',\n regionGlobal: '国际 (kimi.ai)',\n authenticatedAt: '登录时间',\n refreshRejected: '刷新令牌已被拒绝,请重新登录。',\n signIn: '设备码登录',\n signInAgain: '重新登录',\n signingIn: '登录中...',\n signOut: '注销',\n cancelSignIn: '取消登录',\n deviceCodeSection: '设备码授权',\n deviceCodeHint: '在浏览器中打开下方链接(已自动填充用户码),确认后用同一账号授权。',\n openSignInPage: '打开授权页面',\n copyCode: '复制用户码',\n copied: '已复制',\n userCode: '用户码',\n codeExpires: '有效期至',\n waitingAuthorization: '等待浏览器授权...',\n requestingCode: '正在申请设备码...',\n connection: '连接',\n oauthHost: 'OAuth 主机',\n codingEndpoint: '模型接口',\n testConnection: '测试连接',\n testingConnection: '测试中...',\n testSuccess: '连接正常',\n testFailed: '连接失败:Kimi Code 未接受当前凭据',\n routeOwned: '模型路由由本插件提供',\n routeConflict: '模型路由已被其他 Provider 占用:{detail}。请在 DSH 设置中移除重复的 Provider 配置后重试。',\n modelsSection: '模型',\n modelsHint: '勾选后模型才会出现在对话页的模型选择列表中;全部取消勾选或关闭概览卡片上的开关可在列表中隐藏该供应商。',\n refreshCatalog: '刷新模型目录',\n refreshingCatalog: '刷新中...',\n selectAll: '全选',\n unselectAll: '全不选',\n wireAnthropic: 'Anthropic',\n wireOpenai: 'OpenAI',\n capVideo: '视频*',\n capDynamicTools: '动态工具',\n capImageOnly: '仅图片',\n capNone: '—',\n capVideoFootnote: '* 视频输入需先由 kimi_attach_video 工具挂载(本地绝对路径或 http(s) 链接);直接粘贴的上传路径仍只支持图片。',\n capabilitiesTitle: '模型能力',\n capColMedia: '多模态',\n capColTools: '动态工具',\n capColNotes: '说明',\n capPlan: '需要套餐:{plan}',\n capInputCap: '输入上限 {tokens}',\n capNoTools: '不支持工具',\n speedRegular: '标准',\n speedHighspeed: '高速 (约 6×)',\n quotaCost: '额度倍率',\n minimumPlan: '所需套餐',\n enhanced: '思考设置',\n defaultReasoningEffort: '默认思考档位',\n defaultReasoningEffortHint: 'Kimi Code 只接受 low / high / max 三档;none 表示关闭思考。切换档位会使上下文缓存失效,建议在同一会话中保持一致。',\n cacheTtl: '上下文缓存时长',\n cacheTtlHint: 'Kimi 按前缀自动缓存,这里选择写入时长。1h 写入更贵,只有当同一前缀会在一小时内被反复读取才划算;档位在首次写入时锁定,之后无法改写。留空表示不指定,由 Kimi 自己决定。',\n cacheTtlDefault: '不指定(Kimi 默认)',\n cacheTtl5m: '5 分钟',\n cacheTtl1h: '1 小时',\n defaultEffortAuto: '使用模型默认值',\n effortLow: '低 (low)',\n effortHigh: '高 (high)',\n effortMax: '最高 (max)',\n effortNone: '关闭思考',\n contextWindowSection: '模型上下文窗口',\n contextWindowHint: '默认取模型目录的上下文长度。k3 的 1M 上下文需要 Allegretto 及以上套餐,因此默认按 256K 计算;如已升级可在此覆盖为 1M。',\n contextWindowPlan: '完整上下文需要 {plan} 套餐',\n contextWindowReset: '恢复默认',\n contextWindowResetAll: '全部恢复默认',\n contextWindowResetAllConfirm: '确定把已改过的模型上下文窗口全部恢复为默认值吗?',\n contextWindowNoneEnabled: '还没有勾选任何模型。在上方勾选后,这里会出现该模型的上下文窗口设置。',\n save: '保存',\n saved: '已保存',\n saving: '保存中...',\n cacheSection: '缓存与 K3 调优',\n cacheDesc: 'Kimi 的前缀缓存按请求内容自动命中,无需也无法手动声明,因此这里用读缓存比例反映实际效果。',\n cacheEmpty: '本进程还没有带用量回报的请求。',\n cacheHitRatio: '缓存命中率',\n cacheCached: '命中 tokens',\n cacheFresh: '新处理 tokens',\n cacheOutput: '输出 tokens',\n cacheRequests: '请求数',\n cacheHint: '同一会话内:系统提示与工具列表一旦变化会使缓存整体失效,因此保持工具集合稳定、把新增内容追加在末尾,命中率最高。',\n cacheExpired: '本会话已空闲超过缓存有效期,下一轮将重新处理约 {tokens} 个 token。',\n cacheDrift: '最近前缀状态',\n cacheDriftFirst: '首个请求(缓存为空)',\n cacheDriftStable: '稳定(前缀未变)',\n cacheDriftSystemPrompt: '系统提示已变化(缓存失效)',\n cacheDriftTools: '工具列表已变化(缓存失效)',\n cacheDriftCacheKey: '缓存键已变化(会话切换)',\n cacheDriftColdKey: '未发送缓存键(无法命中)',\n preserveThinking: '保留思考 (Preserved Thinking)',\n preserveOn: '已开启(官方默认):跨轮保留 reasoning_content,多轮工具调用更连贯,但思考 token 也计入输出。',\n preserveOff: '已关闭:不要求服务回传推理内容。可设置 DSH_KIMI_CODE_PRESERVE_THINKING=0 关闭。',\n outputCap: '输出上限跟随上下文窗口,长思考不会被 32K 截断',\n quotaSection: '用量与额度',\n quotaDesc: '数据来自 Kimi Code 账户接口,页面可见时最多每 60 秒刷新一次。',\n refreshQuota: '刷新用量',\n refreshingQuota: '刷新中...',\n quotaEmpty: '暂无配额数据,点击「刷新用量」重试。',\n quotaPlan: '当前套餐',\n quotaWallet: '加油包余额',\n quotaWalletLimit: '月度上限',\n quotaWalletUsed: '本月已用',\n updatedAt: '更新时间:{time}',\n resetAt: '重置:{time}',\n loading: '加载中...',\n loginFailed: '登录失败',\n requests: '次请求',\n tokens: 'tokens',\n} as const\n\nexport const en: Record<keyof typeof zh, string> = {\n ...accountPoolEn,\n title: 'Kimi Code',\n pageDesc: 'Sign in to the Kimi Code subscription and manage models, thinking level, context windows, and quota.',\n account: 'Account',\n signedIn: 'Signed in',\n signedOut: 'Not signed in',\n nickname: 'Nickname',\n email: 'Email',\n plan: 'Plan',\n planUnknown: '—',\n region: 'Region',\n regionMainland: 'Mainland China (kimi.com)',\n regionGlobal: 'Global (kimi.ai)',\n authenticatedAt: 'Signed in at',\n refreshRejected: 'The refresh token was rejected — sign in again.',\n signIn: 'Sign in with device code',\n signInAgain: 'Sign in again',\n signingIn: 'Signing in...',\n signOut: 'Sign out',\n cancelSignIn: 'Cancel',\n deviceCodeSection: 'Device authorization',\n deviceCodeHint: 'Open the link below in a browser (the user code is pre-filled) and approve it with the same account.',\n openSignInPage: 'Open the sign-in page',\n copyCode: 'Copy user code',\n copied: 'Copied',\n userCode: 'User code',\n codeExpires: 'Expires at',\n waitingAuthorization: 'Waiting for browser authorization...',\n requestingCode: 'Requesting a device code...',\n connection: 'Connection',\n oauthHost: 'OAuth host',\n codingEndpoint: 'Model endpoint',\n testConnection: 'Test connection',\n testingConnection: 'Testing...',\n testSuccess: 'Connection OK',\n testFailed: 'Connection failed: Kimi Code did not accept the stored credential',\n routeOwned: 'This plugin serves the model route',\n routeConflict: 'Another provider already owns the model route: {detail}. Remove the duplicate provider configuration in DSH settings and reload.',\n modelsSection: 'Models',\n modelsHint: 'Checked models appear in the DSH conversation model list; unchecking all or turning off the switch on the overview card hides this provider.',\n refreshCatalog: 'Refresh catalog',\n refreshingCatalog: 'Refreshing...',\n selectAll: 'Select all',\n unselectAll: 'Deselect all',\n wireAnthropic: 'Anthropic',\n wireOpenai: 'OpenAI',\n capVideo: 'Video*',\n capDynamicTools: 'Dynamic tools',\n capImageOnly: 'Images',\n capNone: '—',\n capVideoFootnote: '* Video input is attached with the kimi_attach_video tool (an absolute local path or an http(s) URL); the paste/upload path still accepts images only.',\n capabilitiesTitle: 'Capabilities',\n capColMedia: 'Multimodal',\n capColTools: 'Dynamic tools',\n capColNotes: 'Notes',\n capPlan: 'Requires plan: {plan}',\n capInputCap: 'Input cap {tokens}',\n capNoTools: 'No tools',\n speedRegular: 'Regular',\n speedHighspeed: 'HighSpeed (~6x)',\n quotaCost: 'Quota cost',\n minimumPlan: 'Required plan',\n enhanced: 'Thinking',\n defaultReasoningEffort: 'Default thinking level',\n defaultReasoningEffortHint: 'Kimi Code accepts only low / high / max; none disables thinking. Switching the level invalidates the context cache, so keep it steady within a session.',\n cacheTtl: 'Context cache duration',\n cacheTtlHint: 'Kimi caches prefixes automatically; this chooses the write duration. A 1h write costs more and only pays off when the same prefix is re-read within the hour. The tier is locked when first written and cannot be changed afterwards. Leave unset to send no cache field and let Kimi decide.',\n cacheTtlDefault: 'Unset (Kimi default)',\n cacheTtl5m: '5 minutes',\n cacheTtl1h: '1 hour',\n defaultEffortAuto: 'Use the model default',\n effortLow: 'Low',\n effortHigh: 'High',\n effortMax: 'Max',\n effortNone: 'Thinking off',\n contextWindowSection: 'Model context window',\n contextWindowHint: 'Defaults to the catalog context length. k3 reaches 1M only on Allegretto and above, so it defaults to 256K; raise the override here after upgrading.',\n contextWindowPlan: 'Full context requires the {plan} plan',\n contextWindowReset: 'Restore default',\n contextWindowResetAll: 'Restore all defaults',\n contextWindowResetAllConfirm: 'Restore every changed model context window to its default?',\n contextWindowNoneEnabled: 'No model is checked yet. Check one above and its context window setting appears here.',\n save: 'Save',\n saved: 'Saved',\n saving: 'Saving...',\n cacheSection: 'Cache & K3 tuning',\n cacheDesc: \"Kimi's prefix cache is automatic and content-hash based — there is no marker to set — so the cache-read ratio is the only evidence it is working.\",\n cacheEmpty: 'No request in this process has reported usage yet.',\n cacheExpired: 'This conversation sat idle past the cache lifetime, so the next turn reprocesses about {tokens} tokens.',\n cacheHitRatio: 'Cache hit ratio',\n cacheCached: 'Cached tokens',\n cacheFresh: 'Fresh tokens',\n cacheOutput: 'Output tokens',\n cacheRequests: 'Requests',\n cacheHint: 'Within one session: any change to the system prompt or the tool list invalidates the whole prefix cache, so keep the tool set stable and append new material at the tail for the best hit rate.',\n cacheDrift: 'Last prefix state',\n cacheDriftFirst: 'First request (cache cold)',\n cacheDriftStable: 'Stable (prefix unchanged)',\n cacheDriftSystemPrompt: 'System prompt changed (cache invalidated)',\n cacheDriftTools: 'Tool list changed (cache invalidated)',\n cacheDriftCacheKey: 'Cache key changed (session switch)',\n cacheDriftColdKey: 'No cache key sent (cannot hit)',\n preserveThinking: 'Preserved Thinking',\n preserveOn: 'On (the official default): reasoning_content is retained across turns, which keeps multi-step tool use coherent — its tokens are billed as output.',\n preserveOff: 'Off: the service is not asked to return reasoning. Set DSH_KIMI_CODE_PRESERVE_THINKING=0 to disable.',\n outputCap: 'Output cap follows the context window, so long reasoning is not cut off at 32K',\n quotaSection: 'Usage & quota',\n quotaDesc: 'Read from the Kimi Code account endpoints; refreshes at most once every 60 seconds while visible.',\n refreshQuota: 'Refresh quota',\n refreshingQuota: 'Refreshing...',\n quotaEmpty: 'No quota data yet — use \"Refresh quota\" to retry.',\n quotaPlan: 'Current plan',\n quotaWallet: 'Booster wallet',\n quotaWalletLimit: 'Monthly cap',\n quotaWalletUsed: 'Used this month',\n updatedAt: 'Updated at: {time}',\n resetAt: 'Reset: {time}',\n loading: 'Loading...',\n loginFailed: 'Sign-in failed',\n requests: 'requests',\n tokens: 'tokens',\n} as const\n\nexport const dictionaries = {\n zh,\n 'zh-CN': zh,\n en,\n 'en-US': en,\n}\n\nexport type KimiCodeLocaleKey = keyof typeof zh\n","/**\n * Capability table for the Kimi model list.\n *\n * Extracted from the settings card so the layout is testable: an earlier\n * revision inlined each capability as prose beside the model name, which\n * stretched the name column and pushed the descriptions out of alignment.\n * Capabilities are now short tags in their own columns, with the per-model\n * detail kept in a hover title.\n */\nimport React from 'react'\nimport type { KimiCodeModelOption } from '../../shared/kimi-code-contracts.ts'\nimport { zh } from './locales.ts'\n\nconst t = zh\n\nexport interface KimiModelCapabilitiesProps {\n models: KimiCodeModelOption[]\n}\n\nexport function KimiModelCapabilities({ models }: KimiModelCapabilitiesProps): React.ReactElement {\n return (\n <div className=\"dsha-cap-table\">\n <table>\n <thead>\n <tr>\n <th>{t.capabilitiesTitle}</th>\n <th>{t.capColMedia}</th>\n <th>{t.capColTools}</th>\n <th>{t.capColNotes}</th>\n </tr>\n </thead>\n <tbody>\n {models.map((model) => {\n // Hover text keeps the per-model facts that would otherwise bloat\n // the table: wire, default effort, input cap and required plan.\n const facts = [\n model.id,\n model.wire === 'anthropic' ? t.wireAnthropic : t.wireOpenai,\n ...(model.defaultReasoningEffort ? [t.defaultReasoningEffort + ': ' + model.defaultReasoningEffort] : []),\n ...(model.maxInputTokens === undefined\n ? []\n : [t.capInputCap.replace('{tokens}', String(model.maxInputTokens))]),\n ...(model.minimumPlan ? [t.capPlan.replace('{plan}', model.minimumPlan)] : []),\n ]\n return (\n <tr key={model.id}>\n <td title={facts.join(' · ')}>{model.name}</td>\n <td>\n <span className={model.supportsVideo ? 'dsha-cap-on' : 'dsha-cap-off'}>\n {model.supportsVideo ? t.capVideo : t.capImageOnly}\n </span>\n </td>\n <td>\n {model.supportsDynamicTools\n ? <span className=\"dsha-cap-on\">{t.capDynamicTools}</span>\n // Tools work but per-message disclosure does not: a dash.\n : model.supportsToolUse\n ? <span className=\"dsha-cap-off\">{t.capNone}</span>\n // No tools at all, which breaks every coding session on\n // the model — worth naming rather than another dash.\n : <span className=\"dsha-cap-off\">{t.capNoTools}</span>}\n </td>\n <td className=\"dsha-cap-notes\">{model.description ?? ''}</td>\n </tr>\n )\n })}\n </tbody>\n </table>\n {models.some((model) => model.supportsVideo) && (\n <p className=\"dsha-muted dsha-cap-footnote\">{t.capVideoFootnote}</p>\n )}\n </div>\n )\n}\n","import React, { useCallback, useEffect, useRef, useState } from 'react'\nimport type {\n KimiCodeCacheTtl,\n KimiCodeLoginFlowStatus,\n KimiCodeModelOption,\n KimiCodeReasoningEffort,\n KimiCodeWebStatus,\n} from '../../shared/kimi-code-contracts.ts'\nimport { KIMI_CODE_REASONING_EFFORTS } from '../../shared/kimi-code-contracts.ts'\nimport { AccountPoolSection } from '../common/AccountPoolSection.tsx'\nimport { ContextWindowEditor, contextDraftsFor } from '../common/ContextWindowEditor.tsx'\nimport { ModelChecklist } from '../common/ModelChecklist.tsx'\nimport { createLineApi } from '../common/line-api.ts'\nimport { createQuotaFollowUp, type QuotaFollowUp } from '../common/quota-follow-up.ts'\nimport { formatCapacity, formatDate, parsePositiveCapacity } from '../common/format.ts'\nimport type { AccountRotationStrategy } from '../../shared/account-pool-contracts.ts'\nimport { zh } from './locales.ts'\nimport { KimiModelCapabilities } from './KimiModelCapabilities.tsx'\n\nconst API = '/kimi-code/api'\nconst api = createLineApi(API, 'Kimi Code')\n\ninterface Props {\n onModelChange?: () => void\n loadModelDirectory?: () => void\n}\n\n/** Money the service reports in minor units, rendered in its own currency. */\nfunction formatMoney(cents: number | null, currency: string | null): string {\n if (cents === null) return '—'\n const code = currency ?? 'USD'\n try {\n return new Intl.NumberFormat(undefined, { style: 'currency', currency: code }).format(cents / 100)\n } catch {\n return `${(cents / 100).toFixed(2)} ${code}`\n }\n}\n\nconst EFFORT_LABEL: Record<KimiCodeReasoningEffort, string> = {\n low: zh.effortLow,\n high: zh.effortHigh,\n max: zh.effortMax,\n none: zh.effortNone,\n}\n\n/** Human label for the last request's prefix-drift cause. */\nfunction driftLabel(\n cause: NonNullable<NonNullable<KimiCodeWebStatus['cache']>['lastDrift']>,\n t: typeof zh,\n): string {\n switch (cause) {\n case 'first-request': return t.cacheDriftFirst\n case 'stable': return t.cacheDriftStable\n case 'system-prompt': return t.cacheDriftSystemPrompt\n case 'tools': return t.cacheDriftTools\n case 'cache-key': return t.cacheDriftCacheKey\n case 'cold-key': return t.cacheDriftColdKey\n default: return String(cause)\n }\n}\n\nexport function KimiCodeSection({ onModelChange, loadModelDirectory }: Props): React.ReactElement {\n const [status, setStatus] = useState<KimiCodeWebStatus | null>(null)\n const [loading, setLoading] = useState(true)\n const [busy, setBusy] = useState<string | null>(null)\n const [error, setError] = useState<string | null>(null)\n const [flow, setFlow] = useState<KimiCodeLoginFlowStatus | null>(null)\n const [contextDrafts, setContextDrafts] = useState<Record<string, string>>({})\n const [savingModel, setSavingModel] = useState<string | null>(null)\n const [copied, setCopied] = useState(false)\n // Result of an explicit connection test. The button used to end silently on\n // success, which is indistinguishable from a click that never registered.\n const [connectionNotice, setConnectionNotice] = useState<string | null>(null)\n\n /** Follow-up poll owed while the host refreshes the quota behind an answer. */\n const quotaFollowUp = useRef<QuotaFollowUp | null>(null)\n\n const t = zh\n\n const notifyChange = useCallback(() => {\n onModelChange?.()\n loadModelDirectory?.()\n }, [onModelChange, loadModelDirectory])\n\n const loadStatus = useCallback(async (quiet = false) => {\n if (!quiet) setError(null)\n try {\n const data = await api.request<KimiCodeWebStatus>('/status')\n setStatus(data)\n setContextDrafts(contextDraftsFor(data))\n // An answer that refreshed the quota behind itself is followed up shortly,\n // so the fresh numbers land without waiting for the next poll.\n quotaFollowUp.current ??= createQuotaFollowUp()\n quotaFollowUp.current.observe(data.quotaRefreshing === true, () => { void loadStatus(true) })\n } catch (err) {\n if (!quiet) setError(err instanceof Error ? err.message : String(err))\n } finally {\n setLoading(false)\n }\n }, [])\n\n useEffect(() => {\n void loadStatus()\n const refreshWhenVisible = () => {\n if (document.visibilityState === 'visible') void loadStatus(true)\n }\n document.addEventListener('visibilitychange', refreshWhenVisible)\n const timer = window.setInterval(refreshWhenVisible, 60_000)\n return () => {\n window.clearInterval(timer)\n document.removeEventListener('visibilitychange', refreshWhenVisible)\n quotaFollowUp.current?.cancel()\n }\n }, [loadStatus])\n\n // The login flow runs on the host and is polled here, because authorization\n // happens in a browser the card does not control.\n useEffect(() => {\n if (flow?.status !== 'pending') return\n const timer = window.setInterval(() => {\n void (async () => {\n try {\n const poll = await api.request<KimiCodeLoginFlowStatus>('/login/status')\n setFlow(poll)\n if (poll.status === 'complete') {\n await loadStatus()\n notifyChange()\n } else if (poll.status === 'error') {\n setError(poll.error || t.loginFailed)\n }\n } catch {\n // A failed poll is transient; the next tick retries.\n }\n })()\n }, 2000)\n return () => window.clearInterval(timer)\n }, [flow?.status, loadStatus, notifyChange, t.loginFailed])\n\n const handleLogin = async () => {\n try {\n setBusy('login')\n setError(null)\n setCopied(false)\n const next = await api.request<KimiCodeLoginFlowStatus>('/login', {\n method: 'POST',\n body: JSON.stringify({}),\n })\n setFlow(next)\n // The host already opened the browser; a failed launch is recoverable\n // because the card always renders the URL and the user code.\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n } finally {\n setBusy(null)\n }\n }\n\n const handleCancelLogin = async () => {\n try {\n await api.request<KimiCodeLoginFlowStatus>('/login/cancel', { method: 'POST' })\n setFlow({ status: 'idle' })\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n }\n }\n\n const handleCopyCode = async () => {\n const code = flow?.userCode\n if (!code) return\n try {\n await navigator.clipboard.writeText(code)\n setCopied(true)\n window.setTimeout(() => setCopied(false), 2000)\n } catch {\n // Clipboard access can be denied; the code stays visible to copy by hand.\n }\n }\n\n /** One account-level action on the shared pool card. */\n const handleAccountAction = async (\n action: 'set-primary' | 'delete' | 'clear-cooldown',\n accountId: string,\n ) => {\n try {\n setBusy(`${action}-${accountId}`)\n setError(null)\n const updated = await api.request<KimiCodeWebStatus>('/accounts', {\n method: 'POST',\n body: JSON.stringify({ action, accountId }),\n })\n setStatus(updated)\n setFlow({ status: 'idle' })\n notifyChange()\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n } finally {\n setBusy(null)\n }\n }\n\n const handleSetStrategy = async (strategy: AccountRotationStrategy) => {\n try {\n setBusy('strategy')\n setError(null)\n const updated = await api.request<KimiCodeWebStatus>('/accounts', {\n method: 'POST',\n body: JSON.stringify({ action: 'strategy', strategy }),\n })\n setStatus(updated)\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n } finally {\n setBusy(null)\n }\n }\n\n /**\n * Re-authorize one account.\n *\n * Nothing is deleted: the failure marker is cleared and the device-code flow\n * runs again, so the account keeps its alias and place in the rotation.\n */\n const handleRelogin = (accountId: string) => {\n void (async () => {\n try {\n const updated = await api.request<KimiCodeWebStatus>('/accounts', {\n method: 'POST',\n body: JSON.stringify({ action: 'relogin', accountId }),\n })\n setStatus(updated)\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n return\n }\n await handleLogin()\n })()\n }\n\n const handleRefreshQuota = async () => {\n try {\n setBusy('quota')\n setError(null)\n // The host reports the real outcome; a failure arrives as a thrown error\n // carrying the upstream reason rather than an indistinguishable 200.\n const updated = await api.request<KimiCodeWebStatus>('/quota', { method: 'POST' })\n setStatus(updated)\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n // Re-read so the card still shows the account and any recorded reason.\n await loadStatus(true)\n } finally {\n setBusy(null)\n }\n }\n\n const handleRefreshCatalog = async () => {\n try {\n setBusy('catalog')\n setError(null)\n const updated = await api.request<KimiCodeWebStatus>('/catalog/refresh', { method: 'POST' })\n setStatus(updated)\n setContextDrafts(contextDraftsFor(updated))\n notifyChange()\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n } finally {\n setBusy(null)\n }\n }\n\n const handleTestConnection = async () => {\n try {\n setBusy('connection')\n setError(null)\n setConnectionNotice(null)\n const result = await api.request<{ connected: boolean; latencyMs: number }>('/connection/test', {\n method: 'POST',\n })\n setConnectionNotice(result.connected ? `${t.testSuccess} · ${result.latencyMs} ms` : t.testFailed)\n // The probe is a real usage call, so the quota shown is now current.\n await loadStatus(true)\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n } finally {\n setBusy(null)\n }\n }\n\n const applyEnabled = async (enabledModelIds: string[]) => {\n try {\n const updated = await api.request<KimiCodeWebStatus>('/models', {\n method: 'POST',\n body: JSON.stringify({ enabledModelIds }),\n })\n setStatus(updated)\n // A model that was just checked has no draft yet; the context window\n // section only renders enabled models.\n setContextDrafts(contextDraftsFor(updated))\n notifyChange()\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n }\n }\n\n const toggleModel = (modelId: string, checked: boolean) => {\n if (!status) return\n const current = status.models.filter((model) => model.enabled).map((model) => model.id)\n const next = checked ? [...new Set([...current, modelId])] : current.filter((id) => id !== modelId)\n void applyEnabled(next)\n }\n\n const setAllModels = (selectAll: boolean) => {\n if (!status || status.models.length === 0) return\n void applyEnabled(selectAll ? status.models.map((model) => model.id) : [])\n }\n\n const handleUpdateEffort = async (effort: KimiCodeReasoningEffort | null) => {\n try {\n const updated = await api.request<KimiCodeWebStatus>('/settings', {\n method: 'POST',\n body: JSON.stringify({ defaultReasoningEffort: effort }),\n })\n setStatus(updated)\n notifyChange()\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n }\n }\n\n const handleUpdateCacheTtl = async (ttl: KimiCodeCacheTtl | null) => {\n try {\n const updated = await api.request<KimiCodeWebStatus>('/settings', {\n method: 'POST',\n body: JSON.stringify({ cacheTtl: ttl }),\n })\n setStatus(updated)\n notifyChange()\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n }\n }\n\n const handleSaveContextWindow = async (modelId: string) => {\n const raw = contextDrafts[modelId] || ''\n const parsed = parsePositiveCapacity(raw)\n if (parsed === null) {\n setError(`Invalid context capacity: ${raw}`)\n return\n }\n try {\n setSavingModel(modelId)\n setError(null)\n const updated = await api.request<KimiCodeWebStatus>('/settings', {\n method: 'POST',\n body: JSON.stringify({ contextWindowOverrides: { [modelId]: parsed } }),\n })\n setStatus(updated)\n setContextDrafts((prev) => ({ ...prev, [modelId]: formatCapacity(parsed) }))\n notifyChange()\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n } finally {\n setSavingModel(null)\n }\n }\n\n /** Clear one override; the row falls back to the catalog length. */\n const handleResetContextWindow = async (modelId: string) => {\n try {\n setSavingModel(modelId)\n setError(null)\n const updated = await api.request<KimiCodeWebStatus>('/settings', {\n method: 'POST',\n body: JSON.stringify({ contextWindowOverrides: { [modelId]: null } }),\n })\n setStatus(updated)\n setContextDrafts((prev) => {\n const model = updated.models.find((candidate) => candidate.id === modelId)\n return model === undefined ? prev : { ...prev, [modelId]: formatCapacity(model.defaultContextWindow) }\n })\n notifyChange()\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n } finally {\n setSavingModel(null)\n }\n }\n\n /** Clear every stored override, including models the picker no longer shows. */\n const handleResetAllContextWindows = async () => {\n const models = Object.keys(status?.contextWindowOverrides ?? {})\n if (models.length === 0) return\n if (typeof window !== 'undefined' && !window.confirm(t.contextWindowResetAllConfirm)) return\n try {\n setBusy('context')\n setError(null)\n const updated = await api.request<KimiCodeWebStatus>('/settings', {\n method: 'POST',\n body: JSON.stringify({ contextWindowOverrides: Object.fromEntries(models.map((model) => [model, null])) }),\n })\n setStatus(updated)\n setContextDrafts(contextDraftsFor(updated))\n notifyChange()\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n } finally {\n setBusy(null)\n }\n }\n\n // Only checked models get a context row; the batch restore still covers every\n // stored override, including one left behind by a model the user unchecked.\n const contextModels = status?.models.filter((model) => model.enabled) ?? []\n const overrideCount = Object.keys(status?.contextWindowOverrides ?? {}).length\n\n if (loading) {\n return (\n <div className=\"dsha-page\">\n <div className=\"dsha-empty\">{t.loading}</div>\n </div>\n )\n }\n\n const quota = status?.quota\n const account = status?.account\n const visibleCount = status?.models.filter((model) => model.enabled).length || 0\n const loginPending = flow?.status === 'pending'\n\n return (\n <div className=\"dsha-page\">\n <AccountPoolSection\n accounts={status?.accounts ?? []}\n activeAccountId={status?.activeAccountId}\n rotationStrategy={status?.rotationStrategy ?? 'sequential'}\n busy={busy}\n labels={t}\n loginBusyLabel={loginPending ? t.waitingAuthorization : busy === 'login' ? t.requestingCode : undefined}\n onLogin={() => void handleLogin()}\n onSetPrimary={(accountId) => void handleAccountAction('set-primary', accountId)}\n onDelete={(accountId) => void handleAccountAction('delete', accountId)}\n onClearCooldown={(accountId) => void handleAccountAction('clear-cooldown', accountId)}\n onRelogin={(accountId) => handleRelogin(accountId)}\n onSetStrategy={(strategy) => void handleSetStrategy(strategy)}\n showQuota\n renderDetails={(entry) => (\n <>\n {entry.planName && <span>{t.plan}: {entry.planName}</span>}\n {entry.region && (\n <span>{t.region}: {entry.region === 'global' ? t.regionGlobal : t.regionMainland}</span>\n )}\n </>\n )}\n >\n {loginPending && (\n <div className=\"dsha-device-box\">\n <strong>{t.deviceCodeSection}</strong>\n <p className=\"dsha-muted\">{t.deviceCodeHint}</p>\n {flow?.userCode && (\n <div className=\"dsha-code-row\">\n <span className=\"dsha-code\">{flow.userCode}</span>\n <button className=\"dsha-btn\" onClick={() => void handleCopyCode()}>\n {copied ? t.copied : t.copyCode}\n </button>\n </div>\n )}\n {flow?.verificationUriComplete && (\n <a\n className=\"dsha-link\"\n href={flow.verificationUriComplete}\n target=\"_blank\"\n rel=\"noreferrer noopener\"\n >\n {flow.verificationUriComplete}\n </a>\n )}\n <div className=\"dsha-row\">\n <span className=\"dsha-label\">{t.codeExpires}</span>\n <span className=\"dsha-value\">{formatDate(flow?.expiresAt)}</span>\n </div>\n <div className=\"dsha-actions\">\n {flow?.verificationUriComplete && (\n <a\n className=\"dsha-btn\"\n href={flow.verificationUriComplete}\n target=\"_blank\"\n rel=\"noreferrer noopener\"\n >\n {t.openSignInPage}\n </a>\n )}\n <button className=\"dsha-btn\" disabled={busy !== null} onClick={() => void handleCancelLogin()}>\n {t.cancelSignIn}\n </button>\n </div>\n </div>\n )}\n </AccountPoolSection>\n\n <section className=\"dsha-group\">\n <div className=\"dsha-grouphead\">\n <h3>{t.connection}</h3>\n </div>\n <div className=\"dsha-row\">\n <span className=\"dsha-label\">{t.oauthHost}</span>\n <span className=\"dsha-value\">{status?.oauthHost || '—'}</span>\n </div>\n <div className=\"dsha-row\">\n <span className=\"dsha-label\">{t.codingEndpoint}</span>\n <span className=\"dsha-value\">{status?.codingBaseUrl || '—'}</span>\n </div>\n <p className=\"dsha-notice\">\n {status?.serving === false && status.conflict\n ? t.routeConflict.replace('{detail}', status.conflict)\n : t.routeOwned}\n </p>\n {connectionNotice && <p className=\"dsha-muted\">{connectionNotice}</p>}\n <div className=\"dsha-actions\">\n <button\n className=\"dsha-btn\"\n disabled={busy !== null || !status?.authenticated}\n onClick={() => void handleTestConnection()}\n >\n {busy === 'connection' ? t.testingConnection : t.testConnection}\n </button>\n </div>\n </section>\n\n <section className=\"dsha-group\">\n <div className=\"dsha-grouphead\">\n <h3>{t.cacheSection}</h3>\n </div>\n <p className=\"dsha-muted\">{t.cacheDesc}</p>\n {status?.cacheHint != null && (\n // Shown above the card rather than inside it: the card is about how\n // well the cache worked, and this says the next turn will not.\n <div className=\"dsha-warn\">{t.cacheExpired.replace('{tokens}', status.cacheHint.totalTokens.toLocaleString())}</div>\n )}\n {status?.cache == null ? (\n <div className=\"dsha-empty\">{t.cacheEmpty}</div>\n ) : (\n <div className=\"dsha-quota-card\">\n <div className=\"dsha-meter-wrap\">\n <div className=\"dsha-meter-label\">\n <span>{t.cacheHitRatio}</span>\n <strong>\n {status.cache.hitRatio === null ? '—' : `${(status.cache.hitRatio * 100).toFixed(1)}%`}\n </strong>\n </div>\n <div className={`dsha-meter ${(status.cache.hitRatio ?? 0) >= 0.9 ? 'dsha-meter-green' : 'dsha-meter-cyan'}`}>\n <span style={{ width: `${Math.round((status.cache.hitRatio ?? 0) * 100)}%` }} />\n </div>\n <div className=\"dsha-meter-meta\">\n <span>{t.cacheCached}: {status.cache.cachedTokens.toLocaleString()}</span>\n <span>{t.cacheFresh}: {status.cache.freshTokens.toLocaleString()}</span>\n <span>{t.cacheOutput}: {status.cache.outputTokens.toLocaleString()}</span>\n <span>{t.cacheRequests}: {status.cache.requests}</span>\n </div>\n </div>\n {status.cache.lastDrift !== undefined && (\n <div className=\"dsha-row\">\n <span className=\"dsha-label\">{t.cacheDrift}</span>\n <span className=\"dsha-value\">{driftLabel(status.cache.lastDrift, t)}</span>\n </div>\n )}\n <p className=\"dsha-muted\">{t.cacheHint}</p>\n </div>\n )}\n </section>\n\n <section className=\"dsha-group\">\n <div className=\"dsha-grouphead\">\n <h3>{t.modelsSection}</h3>\n <button className=\"dsha-btn\" disabled={busy !== null} onClick={() => void handleRefreshCatalog()}>\n {busy === 'catalog' ? t.refreshingCatalog : t.refreshCatalog}\n </button>\n </div>\n <p className=\"dsha-muted dsha-models-hint\">{t.modelsHint}</p>\n <ModelChecklist\n items={(status?.models ?? []).map((model: KimiCodeModelOption) => ({\n id: model.id,\n name: model.name,\n hint: [\n model.wire === 'anthropic' ? t.wireAnthropic : t.wireOpenai,\n ...(model.supportsVideo ? [t.capVideo] : []),\n ...(model.supportsDynamicTools ? [t.capDynamicTools] : []),\n ...(model.minimumPlan ? [t.capPlan.replace('{plan}', model.minimumPlan)] : []),\n ].join(' · '),\n enabled: model.enabled,\n }))}\n busy={busy !== null}\n onToggle={toggleModel}\n onToggleAll={setAllModels}\n labels={{ selectAll: t.selectAll, clearAll: t.unselectAll, list: t.modelsSection }}\n />\n {status !== null && status.models.length > 0 && <KimiModelCapabilities models={status.models} />}\n </section>\n\n <section className=\"dsha-group\">\n <div className=\"dsha-grouphead\">\n <h3>{t.enhanced}</h3>\n </div>\n <div className=\"dsha-pref-row\">\n <div>\n <strong>{t.defaultReasoningEffort}</strong>\n <p className=\"dsha-muted\">{t.defaultReasoningEffortHint}</p>\n </div>\n <select\n className=\"dsha-select\"\n aria-label={t.defaultReasoningEffort}\n value={status?.defaultReasoningEffort ?? ''}\n disabled={busy !== null}\n onChange={(event) => {\n const value = event.currentTarget.value\n void handleUpdateEffort(value === '' ? null : (value as KimiCodeReasoningEffort))\n }}\n >\n <option value=\"\">{t.defaultEffortAuto}</option>\n {KIMI_CODE_REASONING_EFFORTS.map((effort) => (\n <option key={effort} value={effort}>{EFFORT_LABEL[effort]}</option>\n ))}\n </select>\n </div>\n <div className=\"dsha-pref-row\">\n <div>\n <strong>{t.cacheTtl}</strong>\n <p className=\"dsha-muted\">{t.cacheTtlHint}</p>\n </div>\n <select\n className=\"dsha-select\"\n aria-label={t.cacheTtl}\n value={status?.cacheTtl ?? ''}\n disabled={busy !== null}\n onChange={(event) => {\n const value = event.currentTarget.value\n void handleUpdateCacheTtl(value === '' ? null : (value as KimiCodeCacheTtl))\n }}\n >\n <option value=\"\">{t.cacheTtlDefault}</option>\n <option value=\"5m\">{t.cacheTtl5m}</option>\n <option value=\"1h\">{t.cacheTtl1h}</option>\n </select>\n </div>\n </section>\n\n <section className=\"dsha-group\">\n <div className=\"dsha-grouphead\">\n <h3>{t.contextWindowSection}</h3>\n </div>\n <p className=\"dsha-muted\">{t.contextWindowHint}</p>\n <ContextWindowEditor\n rows={contextModels.map((model: KimiCodeModelOption) => ({\n id: model.id,\n name: model.name,\n draft: contextDrafts[model.id] ?? '',\n meta: model.defaultContextWindow < model.contextWindow\n ? formatCapacity(model.contextWindow)\n : undefined,\n inputLabel: `${model.name} context window`,\n hasOverride: status?.contextWindowOverrides[model.id] !== undefined,\n saving: savingModel === model.id,\n }))}\n labels={{\n tokens: t.tokens,\n save: t.save,\n saving: t.saving,\n reset: t.contextWindowReset,\n resetAll: t.contextWindowResetAll,\n empty: t.contextWindowNoneEnabled,\n }}\n busy={busy !== null}\n overrideCount={overrideCount}\n metaClassName=\"dsha-model-meta\"\n onDraftChange={(id, draft) => setContextDrafts((prev) => ({ ...prev, [id]: draft }))}\n onCommit={(id) => void handleSaveContextWindow(id)}\n onReset={(id) => void handleResetContextWindow(id)}\n onResetAll={() => void handleResetAllContextWindows()}\n />\n </section>\n\n <section className=\"dsha-group\">\n <div className=\"dsha-grouphead\">\n <h3>{t.quotaSection}</h3>\n <button\n className=\"dsha-btn\"\n disabled={busy !== null || !status?.authenticated}\n onClick={() => void handleRefreshQuota()}\n >\n {busy === 'quota' ? t.refreshingQuota : t.refreshQuota}\n </button>\n </div>\n <p className=\"dsha-muted\">{t.quotaDesc}</p>\n {/* The progress bars moved into each account card: quota follows the\n account, so a bar here could only ever describe whichever account\n happened to be active when the snapshot was read. What stays is what\n has no per-account bar to live in — the plan, the pay-as-you-go\n wallet, the errors and the freshness of this reading. */}\n <p className=\"dsha-muted\">{t.quotaFactsScope}</p>\n\n {status?.quotaError && <p className=\"dsha-notice\">{status.quotaError}</p>}\n\n {!status?.authenticated ? (\n <div className=\"dsha-empty\">{t.signedOut}</div>\n ) : quota === null || quota === undefined ? (\n <div className=\"dsha-empty\">{busy === 'quota' ? t.refreshingQuota : t.quotaEmpty}</div>\n ) : (\n <div className=\"dsha-quota-card\">\n <div className=\"dsha-quota-title\">\n <strong>{t.quotaPlan}</strong>\n <span>{quota.planName || t.planUnknown}</span>\n </div>\n\n {quota.extraUsage !== null && (\n <div className=\"dsha-meter-wrap\">\n <div className=\"dsha-meter-label\">\n <span>{t.quotaWallet}</span>\n <strong>{formatMoney(quota.extraUsage.balanceCents, quota.extraUsage.currency)}</strong>\n </div>\n <div className=\"dsha-meter-meta\">\n <span>{formatMoney(quota.extraUsage.totalCents, quota.extraUsage.currency)}</span>\n {quota.extraUsage.monthlyChargeLimitEnabled && quota.extraUsage.monthlyChargeLimitCents !== null && (\n <span>\n {t.quotaWalletLimit}: {formatMoney(quota.extraUsage.monthlyChargeLimitCents, quota.extraUsage.currency)}\n </span>\n )}\n </div>\n </div>\n )}\n\n {quota.windows.length === 0 && quota.extraUsage === null && (\n <div className=\"dsha-empty\">{t.quotaEmpty}</div>\n )}\n\n <div className=\"dsha-timestamp\">\n {t.updatedAt.replace('{time}', new Date(quota.fetchedAt).toLocaleString())}\n </div>\n </div>\n )}\n </section>\n\n {error && (\n <div className=\"dsha-error\">\n <div>{error}</div>\n </div>\n )}\n </div>\n )\n}\n","/**\n * Wire contracts between the WorkBuddy host routes and the browser settings\n * card. Everything here is public: no credential ever crosses this boundary.\n */\n\nimport type { AccountPoolStatusDto, PoolAccountSummaryDto } from './account-pool-contracts.ts'\n\n/**\n * Which deployment region an account belongs to.\n *\n * The two regions are separate backends serving overlapping-but-different model\n * catalogs, and a model asked of the wrong region answers 400 `code 11102`\n * (\"service info not found\") rather than failing over. The region is therefore\n * a property of the credential, not of the request.\n */\nexport type WorkBuddyRegion = 'cn' | 'intl'\n\n/**\n * Reasoning levels this route can name.\n *\n * Deliberately the widest set any model declares, so a saved default is not\n * discarded merely because the model that suggested it is no longer selected.\n * The settings card renders the subset the account's models actually declare.\n */\nexport type WorkBuddyReasoningEffort = 'minimal' | 'low' | 'medium' | 'high' | 'xhigh' | 'max'\n\n/** Every level this route can name, in escalating order (the card's sort key). */\nexport const WORKBUDDY_REASONING_EFFORTS: readonly WorkBuddyReasoningEffort[] =\n ['minimal', 'low', 'medium', 'high', 'xhigh', 'max']\n\n/**\n * Ladder of a WorkBuddy model that leaves the level choice to the gateway.\n *\n * `/v3/config` publishes a model's ladder in two shapes: an explicit\n * `supportedEfforts` list, or a lone `{ effort }` field that names only the\n * DEFAULT. Conflating them was a real bug — the lone field first became a\n * one-entry ladder, which rejected an explicit `low`; widening it to every\n * level this route can name then advertised `minimal`/`xhigh` on a model that\n * has three. Measured against the live gateway, such a model accepts exactly\n * `low`/`high`/`max` — the same three `glm-5.3-flash` and\n * `kimi-k2.8-preview` declare explicitly — and every other value is routed\n * into the nearest of them rather than honoured as a level of its own.\n */\nexport const WORKBUDDY_STANDARD_EFFORTS: readonly WorkBuddyReasoningEffort[] =\n ['low', 'high', 'max']\n\n/**\n * Snap a level onto the nearest rung a model's ladder actually exposes.\n *\n * The gateway names a default from a wider vocabulary than the ladder it\n * publishes for the same model: an effort-only entry (minimax-m3, kimi-k3,\n * `glm-5.3` in the cn region) reports `effort: 'medium'` while exposing only\n * `low`/`high`/`max`. Letting that value through is not cosmetic — a default\n * outside the ladder is discarded by the level-resolution step, the request\n * then carries no `reasoning_effort`, and the model returns an EMPTY\n * `reasoning_content` (measured on minimax-m3: 0 characters across three\n * samples, versus 282-659 with the field). Ties resolve upward, which is the\n * mapping the sibling Kimi line documents for `medium`. A ladder that names\n * no level (a text-only model) yields nothing to converge to.\n */\nexport function convergeWorkBuddyEffort(\n effort: string,\n ladder: readonly string[],\n): WorkBuddyReasoningEffort | null {\n if (ladder.length === 0) return null\n const rank = (value: string): number => {\n const index = WORKBUDDY_REASONING_EFFORTS.indexOf(value.trim().toLowerCase() as WorkBuddyReasoningEffort)\n // An unrecognised level is placed at the middle rung rather than at an\n // extreme, so it can never silently pick the cheapest or the most costly.\n return index === -1 ? WORKBUDDY_REASONING_EFFORTS.indexOf('high') : index\n }\n const target = rank(effort)\n let best = ladder[0]!\n for (const candidate of ladder) {\n const distance = Math.abs(rank(candidate) - target)\n const bestDistance = Math.abs(rank(best) - target)\n if (distance < bestDistance || (distance === bestDistance && rank(candidate) > rank(best))) {\n best = candidate\n }\n }\n // The ladder is the model's own declaration, so a hit is always a nameable\n // level; the cast only records what the caller's data already guarantees.\n return best as WorkBuddyReasoningEffort\n}\n\n/** One model offered by the WorkBuddy subscription. */\nexport interface WorkBuddyModelOption {\n id: string\n name: string\n /** Enabled models are the ones DSH offers in the conversation model picker. */\n enabled: boolean\n /** Context window this route assumes when the caller saves no override. */\n defaultContextWindow: number\n /** Effective context window: the override when one is saved, else the default. */\n contextWindow: number\n /** Maximum output tokens this route requests when a caller omits one. */\n defaultMaxTokens: number\n /** Reasoning levels this route exposes; absent for non-reasoning models. */\n reasoningEfforts?: string[]\n /** Whether the model accepts image input on this route. */\n supportsImage: boolean\n /** Regions that serve this model; the account's own region must be listed. */\n regions: WorkBuddyRegion[]\n /** One-line description shown beside the model in the settings card. */\n description?: string\n}\n\n/**\n * Daily check-in preference for the CN-region billing activity.\n *\n * The activity is CN-only: the international deployment answers no check-in\n * surface, so the scheduler skips those accounts outright. There is no window\n * to configure: the first tick after the host starts is the daily run.\n */\nexport interface WorkBuddyCheckinSettings {\n /** Whether the in-process scheduler signs eligible accounts in. */\n enabled: boolean\n}\n\n/**\n * Aggregate check-in state the settings card renders.\n *\n * Deliberately account-less: the card shows one line (\"checked in x/y today\"),\n * not a per-account breakdown, so no account identity crosses here either.\n */\nexport interface WorkBuddyCheckinSummary {\n enabled: boolean\n /** CN-region accounts eligible for the check-in activity. */\n totalAccounts: number\n /** Accounts confirmed signed in today (already signed, or signed by a run). */\n doneToday: number\n /**\n * Accounts whose activity reported no entitlement today.\n *\n * Kept apart from {@link doneToday} because \"the activity is inactive\" is not\n * \"you are checked in\": counting them together let the card claim a sign-in\n * that never happened.\n */\n skippedToday: number\n /** Accounts that exhausted today's retry cap without signing in. */\n failedToday: number\n /** Unix milliseconds the scheduler last ran, automatic or manual. */\n lastRunAt: number | null\n}\n\n/** One credit allowance reported by the billing service. */\nexport interface WorkBuddyMeter {\n id: string\n label: string\n /** Used fraction in [0, 1] when the service reports a bounded allowance. */\n usedFraction: number | null\n /** Remaining fraction in [0, 1], when the service reports one. */\n remainingFraction: number | null\n used: string | null\n limit: string | null\n /** Unix milliseconds the meter resets, when reported. */\n resetsAt: number | null\n description: string | null\n}\n\n/** Account identity read from the local CodeBuddy credential file. */\nexport interface WorkBuddyAccount {\n /** Stable, non-secret selection key derived from region + account identity. */\n id: string\n uid: string | null\n nickname: string | null\n /** Tencent UIN, masked by the card rather than sent in full. */\n uin: string | null\n /** Account kind the client reports, e.g. `personal`. */\n accountType: string | null\n /** Enterprise/tenant id when the account is an enterprise one. */\n enterpriseId: string | null\n region: WorkBuddyRegion\n /** Backend base URL this account's region resolves to. */\n backend: string\n /** Auth domain recorded in the credential, e.g. `copilot.tencent.com`. */\n domain: string\n /** Unix milliseconds the access token expires. */\n expiresAt: number | null\n /** File the credential was read from; null for plugin-managed accounts. */\n sourceFile: string | null\n /** Desktop credentials are external; managed credentials belong to this plugin. */\n source: 'desktop' | 'managed'\n /** Managed credentials may be deleted; desktop credentials may only be hidden. */\n removable: boolean\n /** Hidden desktop accounts do not participate in automatic selection. */\n hidden: boolean\n}\n\n/** One WorkBuddy account as the shared pool card renders it. Never carries a token. */\nexport interface WorkBuddyAccountSummaryDto extends PoolAccountSummaryDto {\n region: WorkBuddyRegion\n /** Which store owns the credential; only managed accounts may be deleted. */\n source: 'desktop' | 'managed'\n /** Whether the card may offer Delete for this account. */\n removable: boolean\n nickname?: string\n /** Tencent UIN, masked by the card rather than shown in full. */\n uin?: string\n /** IDE file a desktop account was adopted from. */\n sourceFile?: string\n /** Auth domain recorded in the credential, e.g. `copilot.tencent.com`. */\n domain?: string\n /** Backend base URL the account's region resolves to. */\n backend?: string\n /** Account kind the client reports, e.g. `personal`. */\n accountType?: string\n /**\n * Whether the plugin currently routes to this account.\n *\n * Distinct from the pool's `activeAccountId`: a hidden account keeps its\n * place in the pool but is not offered for routing while hidden.\n */\n hidden?: boolean\n}\n\n/** One point-in-time quota snapshot for the signed-in WorkBuddy account. */\nexport interface WorkBuddyAccountQuota {\n account: WorkBuddyAccount\n /** Package name the billing service reports, e.g. `Free Plan Subscription`. */\n packageName: string | null\n /** Total credits the package grants, as reported. */\n totalCredits: number | null\n /** Credits remaining in the current cycle. */\n remainingCredits: number | null\n /** Credits consumed in the current cycle. */\n cycleUsedCredits: number | null\n /** Cycle allowance, when the service reports a per-cycle cap. */\n cycleCredits: number | null\n /** Start of the current billing cycle, as Unix milliseconds. */\n cycleStartsAt: number | null\n /** End of the current billing cycle, as Unix milliseconds. */\n cycleEndsAt: number | null\n meters: WorkBuddyMeter[]\n /** When this snapshot was read. */\n fetchedAt: number\n /** Billing routes that answered, for diagnostics in the settings card. */\n sources: string[]\n}\n\n/** Everything the settings card and the composer badge render. */\nexport interface WorkBuddyWebStatus extends Partial<AccountPoolStatusDto> {\n enabled?: boolean\n authenticated: boolean\n hasCredentials: boolean\n /** Where credentials are read from; the local CodeBuddy auth directory. */\n authDirectory: string\n /** Storage description for the plugin's own settings file. */\n storagePath: string\n account: WorkBuddyAccount | null\n quota: WorkBuddyAccountQuota | null\n lastFetchedAt: number | null\n /**\n * Whether a quota refresh is running behind this answer.\n *\n * The card renders the snapshot it already had instead of waiting on the\n * upstream request; when this is true the client asks again shortly so the\n * refreshed snapshot reaches the UI.\n */\n quotaRefreshing?: boolean\n models: WorkBuddyModelOption[]\n contextWindowOverrides: Record<string, number>\n defaultReasoningEffort: WorkBuddyReasoningEffort | null\n /** Account selected for model discovery and all requests; null means automatic. */\n selectedAccountId: string | null\n /** Encrypted storage used for accounts added from this plugin. */\n managedStoragePath: string\n /** Route the plugin currently serves; false when another plugin owns it. */\n serving: boolean\n /** Diagnostic when the route is owned by a different adapter family. */\n conflict: string | null\n /** Pool summaries the shared account card renders; empty without a pool. */\n accounts?: WorkBuddyAccountSummaryDto[]\n /** Aggregate daily check-in state; absent when the host predates check-in. */\n checkin?: WorkBuddyCheckinSummary | null\n}\n\n/** Patch accepted by the models/settings route. */\nexport interface WorkBuddySettingsUpdateDto {\n enabled?: boolean\n enabledModelIds?: string[]\n /** A number sets an override for that model; `null` restores the catalog default. */\n contextWindowOverrides?: Record<string, number | null>\n defaultReasoningEffort?: WorkBuddyReasoningEffort | null\n selectedAccountId?: string | null\n /** Partial check-in update; omitted fields keep their stored value. */\n checkin?: Partial<WorkBuddyCheckinSettings>\n}\n\n/** Result of a connection test against the upstream chat endpoint. */\nexport interface WorkBuddyConnectionDto {\n connected: boolean\n account: WorkBuddyAccount | null\n /** Round-trip time of the probe request. */\n latencyMs: number\n /** Model the probe asked for. */\n model: string\n checkedAt: number\n}\n","export const NS_WORKBUDDY = 'dsh-workbuddy'\n\nexport const zh = {\n title: 'WorkBuddy',\n pageDesc: '复用本机 CodeBuddy 桌面端登录态,管理 WorkBuddy(CodeBuddy 订阅)模型、上下文窗口与额度。',\n account: '账号',\n noAccounts: '暂无账号。点击右上角「添加账号」完成浏览器授权,或登录 CodeBuddy 桌面端后重新扫描;桌面账号只能从本插件隐藏,绝不删除 CodeBuddy 的原凭据。',\n signedOut: '未找到凭据',\n nickname: '昵称',\n uin: 'UIN',\n region: '区域',\n regionCn: '国区',\n regionIntl: '国际区',\n accountType: '账号类型',\n routeUnreachable: '无法读取 WorkBuddy 设置路由',\n routeUnreachableHint: '浏览器里加载的插件版本可能比 Host 进程里运行的新(客户端资源是现读磁盘的,Host 只在启动时加载)。请重启 DSH,让两端来自同一份构建。',\n rescan: '重新扫描',\n rescanning: '扫描中...',\n accounts: '账号管理',\n addCnAccount: '添加国区账号',\n addIntlAccount: '添加国际区账号',\n authorizing: '授权中…',\n loginWaiting: '请在新打开的浏览器页面完成登录与授权。',\n loginFailed: '账号授权失败',\n hiddenAccount: '已隐藏',\n hideAccount: '从插件隐藏',\n restoreAccount: '恢复显示',\n deleteAccount: '删除账号',\n deleteConfirm: '确定删除这个插件托管的账号吗?加密存储中的登录凭据会被移除。',\n connection: '连接',\n testConnection: '测试连接',\n testingConnection: '测试中...',\n latency: '延迟',\n routeOwned: '模型路由由本插件提供',\n routeConflict: '模型路由已被其他 Provider 占用:{detail}。请在 DSH 设置中移除重复的 Provider 配置后重试。',\n modelsSection: '模型',\n modelsHint: '勾选后模型才会出现在对话页的模型选择列表中;未勾选或关闭上方开关可在列表中隐藏该供应商。目录与上下文窗口来自订阅网关的模型目录,并按账号所在区域过滤——跨区调用会被上游拒绝。',\n refreshCatalog: '刷新模型目录',\n refreshingCatalog: '刷新中...',\n selectAll: '全选',\n unselectAll: '全不选',\n imageSupport: '图片',\n textOnly: '纯文本',\n regionBadge: '区域',\n unavailableHere: '当前区域不可用',\n enhanced: '增强功能',\n defaultReasoningEffort: '默认思考深度',\n defaultReasoningEffortHint: '控制支持推理的模型在未单独指定时的思考强度。',\n defaultEffortAuto: '使用模型默认值',\n effortUnsupported: '当前模型不支持',\n noReasoningModels: '当前账号的模型都没有声明可用的思考档位,因此没有可选的默认档位。',\n defaultEffortKept: '已保存的档位不被当前任何模型支持,已保留但不会生效。',\n contextWindowSection: '模型上下文窗口',\n contextWindowHint: '默认值来自订阅网关的模型目录(每个模型的真实上下文上限);可覆盖为自定义容量,该值用于 DSH 的压缩与溢出判断,可输入 1M、512K、200K 等容量。',\n contextWindowReset: '恢复默认',\n contextWindowResetAll: '全部恢复默认',\n contextWindowResetAllConfirm: '确定把已改过的模型上下文窗口全部恢复为默认值吗?',\n contextWindowNoneEnabled: '还没有勾选任何模型。在上方勾选后,这里会出现该模型的上下文窗口设置。',\n save: '保存',\n saved: '已保存',\n saving: '保存中...',\n quotaSection: '用量与配额',\n quotaDesc: '数据来自订阅的计费接口,页面可见时最多每 60 秒刷新一次。',\n refreshQuota: '刷新用量',\n refreshingQuota: '刷新中...',\n quotaEmpty: '暂无配额数据,点击「刷新用量」重试。',\n quotaPackage: '套餐',\n quotaRemaining: '剩余额度',\n quotaCycle: '本周期已用',\n quotaReset: '重置时间',\n updatedAt: '更新时间:{time}',\n loading: '加载中...',\n credits: 'credits',\n composerLabel: '额度',\n dailyCheckin: '每日签到',\n checkinHint: '仅国区账号参与;DSH 启动时自动签到一次,运行期间每 10 分钟补检,进程关闭的当天不会签到。',\n checkinAuto: '自动签到',\n checkinToday: '今日已签 {done}/{total}',\n checkinSkipped: '{count} 个无签到活动',\n checkinFailed: '{count} 个失败',\n checkinLastRun: '上次运行:{time}',\n checkinNever: '尚未运行',\n checkinNow: '立即签到',\n checkinRunning: '签到中…',\n} as const\n\nexport const en = {\n title: 'WorkBuddy',\n pageDesc: 'Reuse the local CodeBuddy desktop sign-in to manage WorkBuddy (CodeBuddy subscription) models, context windows, and quota.',\n account: 'Account',\n noAccounts: 'No accounts yet. Use “Add account” above to authorize, or sign in with the CodeBuddy desktop client and rescan; desktop accounts can only be hidden here, never removed from CodeBuddy.',\n signedOut: 'No credential found',\n nickname: 'Nickname',\n uin: 'UIN',\n region: 'Region',\n regionCn: 'China',\n regionIntl: 'International',\n accountType: 'Account type',\n routeUnreachable: 'The WorkBuddy settings route could not be read',\n routeUnreachableHint: 'The plugin loaded in the browser may be newer than the one running in the Host: client assets are read from disk on demand, while the Host loads them only at startup. Restart DSH so both halves come from the same build.',\n rescan: 'Rescan',\n rescanning: 'Scanning...',\n accounts: 'Account Management',\n addCnAccount: 'Add China account',\n addIntlAccount: 'Add international account',\n authorizing: 'Authorizing…',\n loginWaiting: 'Complete sign-in and authorization in the newly opened browser page.',\n loginFailed: 'Account authorization failed',\n hiddenAccount: 'Hidden',\n hideAccount: 'Hide from plugin',\n restoreAccount: 'Restore',\n deleteAccount: 'Delete account',\n deleteConfirm: 'Delete this plugin-managed account? Its encrypted credential will be removed.',\n connection: 'Connection',\n testConnection: 'Test connection',\n testingConnection: 'Testing...',\n latency: 'Latency',\n routeOwned: 'This plugin serves the model route',\n routeConflict: 'Another provider already owns the model route: {detail}. Remove the duplicate provider configuration in DSH settings and reload.',\n modelsSection: 'Models',\n modelsHint: 'Checked models appear in the DSH conversation model list. The catalog and its context windows come from the subscription gateway and are filtered by the account’s region — the upstream rejects a model asked of the wrong region.',\n refreshCatalog: 'Refresh catalog',\n refreshingCatalog: 'Refreshing...',\n selectAll: 'Select all',\n unselectAll: 'Deselect all',\n imageSupport: 'Images',\n textOnly: 'Text only',\n regionBadge: 'Regions',\n unavailableHere: 'Unavailable in this region',\n enhanced: 'Enhanced features',\n defaultReasoningEffort: 'Default reasoning effort',\n defaultReasoningEffortHint: 'Reasoning effort for models that support it when the conversation does not specify one.',\n defaultEffortAuto: 'Use the model default',\n effortUnsupported: 'unsupported by the current models',\n noReasoningModels: 'None of this account\\u2019s models declare a reasoning level, so there is no default to choose.',\n defaultEffortKept: 'The saved level is not supported by any current model; it is kept but has no effect.',\n contextWindowSection: 'Model context window',\n contextWindowHint: 'Defaults come from the subscription gateway’s own catalog (each model’s real context cap); override one with the capacity DSH should use for compaction and overflow decisions (e.g., 1M, 512K, 200K).',\n contextWindowReset: 'Restore default',\n contextWindowResetAll: 'Restore all defaults',\n contextWindowResetAllConfirm: 'Restore every changed model context window to its default?',\n contextWindowNoneEnabled: 'No model is checked yet. Check one above and its context window setting appears here.',\n save: 'Save',\n saved: 'Saved',\n saving: 'Saving...',\n quotaSection: 'Usage & quota',\n quotaDesc: 'Read from the subscription billing endpoint; refreshes at most once every 60 seconds while visible.',\n refreshQuota: 'Refresh quota',\n refreshingQuota: 'Refreshing...',\n quotaEmpty: 'No quota data yet — use “Refresh quota” to retry.',\n quotaPackage: 'Package',\n quotaRemaining: 'Remaining credits',\n quotaCycle: 'Used this cycle',\n quotaReset: 'Resets',\n updatedAt: 'Updated at: {time}',\n loading: 'Loading...',\n credits: 'credits',\n composerLabel: 'Quota',\n dailyCheckin: 'Daily check-in',\n checkinHint: 'CN-region accounts only. The host signs in once at startup and re-checks every 10 minutes while running; a day the process never runs is not signed.',\n checkinAuto: 'Auto check-in',\n checkinToday: 'Checked in today {done}/{total}',\n checkinSkipped: '{count} with no activity',\n checkinFailed: '{count} failed',\n checkinLastRun: 'Last run: {time}',\n checkinNever: 'Never run',\n checkinNow: 'Check in now',\n checkinRunning: 'Checking in…',\n} as const\n\nexport const dictionaries = {\n zh,\n 'zh-CN': zh,\n en,\n 'en-US': en,\n}\n\nexport type WorkBuddyLocaleKey = keyof typeof zh\n","/**\n * The WorkBuddy card's state, effects and actions.\n *\n * Split out of 'WorkBuddySection.tsx' so that file is markup and this one is\n * behaviour: what the card tracks, what it derives from a status answer, and\n * every request a control can make. The view reads one named shape — see\n * `WorkBuddySectionView` — so the contract between the two is visible here\n * rather than inferred from the JSX.\n */\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react'\nimport type { AccountRotationStrategy } from '../../shared/account-pool-contracts.ts'\nimport type {\n WorkBuddyAccount,\n WorkBuddyAccountQuota,\n WorkBuddyAccountSummaryDto,\n WorkBuddyCheckinSettings,\n WorkBuddyModelOption,\n WorkBuddyReasoningEffort,\n WorkBuddyWebStatus,\n} from '../../shared/workbuddy-contracts.ts'\nimport { WORKBUDDY_REASONING_EFFORTS } from '../../shared/workbuddy-contracts.ts'\nimport { accountPoolZh, type AccountPoolLabels } from '../common/account-pool-labels.ts'\nimport { contextDraftsFor } from '../common/ContextWindowEditor.tsx'\nimport { formatCapacity, parsePositiveCapacity } from '../common/format.ts'\nimport { createLineApi } from '../common/line-api.ts'\nimport { createQuotaFollowUp, type QuotaFollowUp } from '../common/quota-follow-up.ts'\nimport { zh } from './locales.ts'\n\nconst API = '/workbuddy/api'\n\n/** The seats the settings hub hands the card; both optional, so a bare render works. */\nexport interface WorkBuddySectionProps {\n onModelChange?: () => void\n loadModelDirectory?: () => void\n}\n\n/**\n * The shared card's label set.\n *\n * Only the three labels WorkBuddy genuinely words differently are taken from\n * this tab's dictionary; everything else is the shared set, so the five\n * provider tabs cannot drift apart in wording.\n */\nfunction accountPoolLabels(t: typeof zh): AccountPoolLabels {\n return {\n ...accountPoolZh,\n noAccounts: t.noAccounts,\n // A WorkBuddy identity reads as a nickname, not an e-mail address.\n email: t.nickname,\n }\n}\n\ninterface LoginPollStatus {\n status: 'idle' | 'pending' | 'complete' | 'error'\n region?: 'cn' | 'intl'\n authUrl?: string\n progress?: string\n accountId?: string\n error?: string\n}\n\ninterface ConnectionPayload {\n connected: boolean\n account: WorkBuddyAccount | null\n latencyMs: number\n model: string\n checkedAt: number\n}\n\n/**\n * Call one settings route through the shared reader.\n *\n * This line is where the shared reader's tolerance came from: reading the body\n * as text first is what lets a route that is not mounted (an empty body, which\n * is exactly what a stale host half produces) be reported as such instead of as\n * a bare \"Unexpected end of JSON input\".\n */\nconst api = createLineApi(API, 'WorkBuddy')\n\n/** One selectable default reasoning level, with the models that declare it. */\nexport interface ReasoningEffortChoice {\n value: WorkBuddyReasoningEffort\n /** Model names that accept this level, in catalog order. */\n models: string[]\n}\n\n/**\n * Reasoning levels the default-effort control may offer.\n *\n * The levels come from what this account's models actually declare — never from\n * the shipped enum alone. The setting is one global default applied to whichever\n * model a conversation uses, so the list is their union; each entry carries the\n * models behind it, and a level only some models accept is labelled as such.\n * Order follows {@link WORKBUDDY_REASONING_EFFORTS}, which is the escalating\n * order the upstream ladder uses.\n */\nexport function reasoningEffortChoices(models: WorkBuddyModelOption[]): ReasoningEffortChoice[] {\n const declared = new Map<string, string[]>()\n for (const model of models) {\n for (const effort of model.reasoningEfforts ?? []) {\n const names = declared.get(effort)\n if (names === undefined) declared.set(effort, [model.name])\n else names.push(model.name)\n }\n }\n return WORKBUDDY_REASONING_EFFORTS\n .filter((effort) => declared.has(effort))\n .map((effort) => ({ value: effort, models: declared.get(effort)! }))\n}\n\n/**\n * Whether a saved default is unusable for every model on this account.\n *\n * The adapter drops a level the chosen model does not accept instead of sending\n * it, so a value that no model declares silently does nothing. Reporting it is\n * what keeps that from looking like the setting was applied.\n */\nexport function unsupportedReasoningEffort(\n configured: WorkBuddyReasoningEffort | null | undefined,\n models: WorkBuddyModelOption[],\n): WorkBuddyReasoningEffort | null {\n if (configured === null || configured === undefined) return null\n const supported = models.some((model) => (model.reasoningEfforts ?? []).includes(configured))\n return supported ? null : configured\n}\n\n/** Defend against a response that omits the arrays the card renders. */\nfunction normalizeStatus(data: WorkBuddyWebStatus): WorkBuddyWebStatus {\n return {\n ...data,\n models: Array.isArray(data?.models) ? data.models : [],\n contextWindowOverrides: data?.contextWindowOverrides ?? {},\n accounts: Array.isArray(data?.accounts) ? data.accounts : [],\n }\n}\n\n/**\n * Everything the card's view consumes, grouped by kind.\n *\n * Returned as one named shape instead of one status blob: a reader can see at a\n * glance what the hook tracks, what it computes from a status answer, and what\n * the view is allowed to ask it to do.\n */\nexport interface WorkBuddySectionView {\n /** Values that change as the card runs. */\n state: {\n /** Last status answer; null until the first read lands. */\n status: WorkBuddyWebStatus | null\n /** True until the first status read settles, whatever its outcome. */\n loading: boolean\n /** Id of the action in flight, or null; every disabled control reads it. */\n busy: string | null\n /** The failure the card's error strip shows. */\n error: string | null\n /** Result of the last explicit connection test. */\n connection: ConnectionPayload | null\n /** Line the host reports while a regional sign-in is being polled. */\n loginProgress: string | null\n /** One free-text capacity draft per model, keyed by model id. */\n contextDrafts: Record<string, string>\n /** Model id whose context-window save or restore is in flight. */\n savingModel: string | null\n }\n /** Facts read straight off the current status answer. */\n derived: {\n /** Every account row the shared pool card lists. */\n poolAccounts: WorkBuddyAccountSummaryDto[]\n /** Levels this account's models declare, each with the models behind it. */\n effortChoices: ReasoningEffortChoice[]\n /** Every catalog model, enabled or not; the effort labels count them. */\n allModels: WorkBuddyModelOption[]\n /**\n * A saved default no current model declares, when there is one.\n *\n * The adapter drops a level the chosen model does not accept, so reporting\n * this is what keeps an inert setting from looking applied.\n */\n strayEffort: WorkBuddyReasoningEffort | null\n /** Models the context-window editor offers: the enabled ones only. */\n contextModels: WorkBuddyModelOption[]\n /** How many stored overrides exist, whether or not a row still shows them. */\n overrideCount: number\n /** The displayed account's quota snapshot, when the host has one. */\n quota: WorkBuddyAccountQuota | null | undefined\n /** Whether a credential is signed in; every authenticated control reads it. */\n authenticated: boolean\n /**\n * A failed status read with no answer to fall back on.\n *\n * A failed read leaves `status` null, which must NOT be rendered as \"no\n * credential found\": that claims a credential problem when the real cause is\n * an unreachable route.\n */\n unreachable: boolean\n /**\n * The line's dictionary, handed to the shared pool card as one object.\n *\n * The hook already owns it for its own sentences, so the view takes the same\n * object from here rather than reaching for a second import.\n */\n poolLabels: AccountPoolLabels\n }\n /** Everything the view can trigger. */\n actions: {\n /** Start a regional sign-in; its flow is polled until it settles. */\n login(region: 'cn' | 'intl'): Promise<void>\n /** Re-read the credentials the host can find on this machine. */\n rescan(): Promise<void>\n /**\n * One account action, whether it is a pool action (`set-primary`, `hide`,\n * `restore`, `relogin`, `clear-cooldown`) or a credential action (`delete`).\n * The host route dispatches on `action`.\n */\n accountAction(action: string, accountId: string): Promise<void>\n /** Delete one plugin-owned credential, after the user confirms. */\n deleteAccount(accountId: string): Promise<void>\n setStrategy(strategy: AccountRotationStrategy): Promise<void>\n testConnection(): Promise<void>\n refreshQuota(): Promise<void>\n /** Run the daily check-in for every eligible account, now. */\n checkinNow(): Promise<void>\n /** Patch the check-in preference; omitted fields keep their stored value. */\n updateCheckin(checkin: Partial<WorkBuddyCheckinSettings>): Promise<void>\n toggleModel(modelId: string, enabled: boolean): Promise<void>\n setAllModels(enabled: boolean): Promise<void>\n updateEffort(effort: WorkBuddyReasoningEffort | null): Promise<void>\n refreshCatalog(): Promise<void>\n saveContextWindow(modelId: string): Promise<void>\n resetContextWindow(modelId: string): Promise<void>\n resetAllContextWindows(): Promise<void>\n /** Edit one capacity draft mid-typing; the editor never parses it. */\n updateContextDraft(modelId: string, draft: string): void\n }\n}\n\nexport function useWorkBuddySection({ onModelChange, loadModelDirectory }: WorkBuddySectionProps): WorkBuddySectionView {\n const [status, setStatus] = useState<WorkBuddyWebStatus | null>(null)\n const [loading, setLoading] = useState(true)\n const [busy, setBusy] = useState<string | null>(null)\n const [error, setError] = useState<string | null>(null)\n // Whether the last `/status` call failed. A failed status read leaves\n // `status` null, which must NOT be rendered as \"no credential found\": that\n // claims a credential problem when the real cause is an unreachable route.\n const [statusFailed, setStatusFailed] = useState(false)\n const [connection, setConnection] = useState<ConnectionPayload | null>(null)\n const [loginProgress, setLoginProgress] = useState<string | null>(null)\n const loginIntervalRef = useRef<number | null>(null)\n const loginTimeoutRef = useRef<number | null>(null)\n /** Follow-up poll owed while the host refreshes the quota behind an answer. */\n const quotaFollowUp = useRef<QuotaFollowUp | null>(null)\n const [contextDrafts, setContextDrafts] = useState<Record<string, string>>({})\n const [savingModel, setSavingModel] = useState<string | null>(null)\n\n const t = zh\n\n const notifyChange = useCallback(() => {\n onModelChange?.()\n loadModelDirectory?.()\n }, [onModelChange, loadModelDirectory])\n\n // The level list follows the models this account actually declares, so the\n // control cannot offer a level none of them accepts.\n const effortChoices = useMemo(\n () => reasoningEffortChoices(status?.models ?? []),\n [status?.models],\n )\n const allModels = status?.models ?? []\n // The pool summaries the shared card renders; the legacy single-account view\n // below stays for a caller whose host has no pool installed.\n const poolAccounts = useMemo<WorkBuddyAccountSummaryDto[]>(\n () => (Array.isArray(status?.accounts) ? status.accounts : []),\n [status?.accounts],\n )\n const strayEffort = unsupportedReasoningEffort(status?.defaultReasoningEffort, allModels)\n\n const loadStatus = useCallback(async (quiet = false) => {\n if (!quiet) setError(null)\n try {\n const data = await api.request<WorkBuddyWebStatus>('/status')\n // A response without the expected arrays must still render, so they are\n // normalized rather than trusted.\n const normalized = normalizeStatus(data)\n setStatus(normalized)\n setStatusFailed(false)\n setContextDrafts(contextDraftsFor(normalized))\n // An answer that refreshed the quota behind itself is followed up shortly,\n // so the fresh numbers land without waiting for the next poll.\n quotaFollowUp.current ??= createQuotaFollowUp()\n quotaFollowUp.current.observe(data.quotaRefreshing === true, () => { void loadStatus(true) })\n } catch (err) {\n setStatusFailed(true)\n if (!quiet) setError(err instanceof Error ? err.message : String(err))\n } finally {\n setLoading(false)\n }\n }, [])\n\n useEffect(() => {\n void loadStatus()\n const refreshWhenVisible = () => {\n if (document.visibilityState === 'visible') void loadStatus(true)\n }\n document.addEventListener('visibilitychange', refreshWhenVisible)\n return () => {\n document.removeEventListener('visibilitychange', refreshWhenVisible)\n quotaFollowUp.current?.cancel()\n if (loginIntervalRef.current !== null) window.clearInterval(loginIntervalRef.current)\n if (loginTimeoutRef.current !== null) window.clearTimeout(loginTimeoutRef.current)\n }\n }, [loadStatus])\n\n const rescan = async () => {\n try {\n setBusy('rescan')\n setError(null)\n const updated = await api.request<WorkBuddyWebStatus>('/rescan', { method: 'POST' })\n setStatus(normalizeStatus(updated))\n notifyChange()\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n } finally {\n setBusy(null)\n }\n }\n\n const login = async (region: 'cn' | 'intl') => {\n try {\n setBusy(`login:${region}`)\n setError(null)\n setLoginProgress(t.loginWaiting)\n const flow = await api.request<LoginPollStatus>('/accounts/login', {\n method: 'POST',\n body: JSON.stringify({ region }),\n })\n if (flow.authUrl) window.open(flow.authUrl, '_blank', 'noopener,noreferrer')\n if (loginIntervalRef.current !== null) window.clearInterval(loginIntervalRef.current)\n if (loginTimeoutRef.current !== null) window.clearTimeout(loginTimeoutRef.current)\n const timer = window.setInterval(() => {\n void (async () => {\n try {\n const poll = await api.request<LoginPollStatus>('/accounts/login/status')\n if (poll.progress) setLoginProgress(poll.progress)\n if (poll.status === 'complete') {\n window.clearInterval(timer)\n loginIntervalRef.current = null\n if (loginTimeoutRef.current !== null) window.clearTimeout(loginTimeoutRef.current)\n loginTimeoutRef.current = null\n setBusy(null)\n setLoginProgress(null)\n if (poll.accountId) {\n await api.request<WorkBuddyWebStatus>('/settings', {\n method: 'POST',\n body: JSON.stringify({ selectedAccountId: poll.accountId }),\n })\n }\n await loadStatus()\n notifyChange()\n } else if (poll.status === 'error') {\n window.clearInterval(timer)\n loginIntervalRef.current = null\n if (loginTimeoutRef.current !== null) window.clearTimeout(loginTimeoutRef.current)\n loginTimeoutRef.current = null\n setBusy(null)\n setLoginProgress(null)\n setError(poll.error || t.loginFailed)\n }\n } catch {\n // Transient polling failure; the next interval retries.\n }\n })()\n }, 1500)\n loginIntervalRef.current = timer\n loginTimeoutRef.current = window.setTimeout(() => {\n window.clearInterval(timer)\n loginIntervalRef.current = null\n loginTimeoutRef.current = null\n setBusy(null)\n setLoginProgress(null)\n }, 5 * 60 * 1000)\n } catch (err) {\n setBusy(null)\n setLoginProgress(null)\n setError(err instanceof Error ? err.message : String(err))\n }\n }\n\n /**\n * One account action, whether it is a pool action (`set-primary`, `hide`) or a\n * credential action (`delete`). The host route dispatches on `action`.\n */\n const accountAction = async (action: string, accountId: string) => {\n try {\n setBusy(`${action}:${accountId}`)\n setError(null)\n const updated = await api.request<WorkBuddyWebStatus>('/accounts/action', {\n method: 'POST',\n body: JSON.stringify({ action, accountId }),\n })\n setStatus(normalizeStatus(updated))\n notifyChange()\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n } finally {\n setBusy(null)\n }\n }\n\n const deleteAccount = async (accountId: string) => {\n if (!window.confirm(t.deleteConfirm)) return\n await accountAction('delete', accountId)\n }\n\n const setStrategy = async (strategy: AccountRotationStrategy) => {\n try {\n setBusy('strategy')\n setError(null)\n const updated = await api.request<WorkBuddyWebStatus>('/accounts/strategy', {\n method: 'POST',\n body: JSON.stringify({ strategy }),\n })\n setStatus(normalizeStatus(updated))\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n } finally {\n setBusy(null)\n }\n }\n\n const testConnection = async () => {\n try {\n setBusy('connection')\n setError(null)\n setConnection(await api.request<ConnectionPayload>('/connection/test', { method: 'POST' }))\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n } finally {\n setBusy(null)\n }\n }\n\n const refreshQuota = async () => {\n try {\n setBusy('quota')\n setError(null)\n const updated = await api.request<WorkBuddyWebStatus>('/quota', { method: 'POST' })\n setStatus(updated)\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n } finally {\n setBusy(null)\n }\n }\n\n const checkinNow = async () => {\n try {\n setBusy('checkin')\n setError(null)\n const updated = await api.request<WorkBuddyWebStatus>('/checkin/now', { method: 'POST' })\n setStatus(normalizeStatus(updated))\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n } finally {\n setBusy(null)\n }\n }\n\n const updateCheckin = async (checkin: Partial<WorkBuddyCheckinSettings>) => {\n try {\n setBusy('checkin')\n setError(null)\n const updated = await api.request<WorkBuddyWebStatus>('/settings', {\n method: 'POST',\n body: JSON.stringify({ checkin }),\n })\n setStatus(normalizeStatus(updated))\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n } finally {\n setBusy(null)\n }\n }\n\n const toggleModel = async (modelId: string, enabled: boolean) => {\n if (status === null) return\n const current = status.models.filter((model) => model.enabled).map((model) => model.id)\n const next = enabled\n ? [...new Set([...current, modelId])]\n : current.filter((id) => id !== modelId)\n try {\n setBusy(`model:${modelId}`)\n setError(null)\n const updated = await api.request<WorkBuddyWebStatus>('/settings', {\n method: 'POST',\n body: JSON.stringify({ enabledModelIds: next }),\n })\n const normalized = normalizeStatus(updated)\n setStatus(normalized)\n // A model that was just checked has no draft yet; the context window\n // section only renders enabled models.\n setContextDrafts(contextDraftsFor(normalized))\n notifyChange()\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n } finally {\n setBusy(null)\n }\n }\n\n const setAllModels = async (enabled: boolean) => {\n if (status === null) return\n try {\n setBusy('models-all')\n setError(null)\n const updated = await api.request<WorkBuddyWebStatus>('/settings', {\n method: 'POST',\n body: JSON.stringify({ enabledModelIds: enabled ? status.models.map((model) => model.id) : [] }),\n })\n const normalized = normalizeStatus(updated)\n setStatus(normalized)\n setContextDrafts(contextDraftsFor(normalized))\n notifyChange()\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n } finally {\n setBusy(null)\n }\n }\n\n const updateEffort = async (effort: WorkBuddyReasoningEffort | null) => {\n try {\n setBusy('effort')\n setError(null)\n const updated = await api.request<WorkBuddyWebStatus>('/settings', {\n method: 'POST',\n body: JSON.stringify({ defaultReasoningEffort: effort }),\n })\n setStatus(updated)\n notifyChange()\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n } finally {\n setBusy(null)\n }\n }\n\n const refreshCatalog = async () => {\n try {\n setBusy('catalog')\n setError(null)\n const updated = await api.request<WorkBuddyWebStatus>('/catalog/refresh', { method: 'POST' })\n const normalized = normalizeStatus(updated)\n setStatus(normalized)\n setContextDrafts(contextDraftsFor(normalized))\n notifyChange()\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n } finally {\n setBusy(null)\n }\n }\n\n const saveContextWindow = async (modelId: string) => {\n const raw = contextDrafts[modelId] || ''\n const parsed = parsePositiveCapacity(raw)\n if (parsed === null) {\n setError(`Invalid context capacity: ${raw}`)\n return\n }\n try {\n setSavingModel(modelId)\n setError(null)\n const updated = await api.request<WorkBuddyWebStatus>('/settings', {\n method: 'POST',\n body: JSON.stringify({ contextWindowOverrides: { [modelId]: parsed } }),\n })\n setStatus(updated)\n setContextDrafts((prev) => ({ ...prev, [modelId]: formatCapacity(parsed) }))\n notifyChange()\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n } finally {\n setSavingModel(null)\n }\n }\n\n /** Clear one override; the row falls back to the catalog length. */\n const resetContextWindow = async (modelId: string) => {\n try {\n setSavingModel(modelId)\n setError(null)\n const updated = normalizeStatus(await api.request<WorkBuddyWebStatus>('/settings', {\n method: 'POST',\n body: JSON.stringify({ contextWindowOverrides: { [modelId]: null } }),\n }))\n setStatus(updated)\n setContextDrafts((prev) => {\n const model = updated.models.find((candidate) => candidate.id === modelId)\n return model === undefined ? prev : { ...prev, [modelId]: formatCapacity(model.defaultContextWindow) }\n })\n notifyChange()\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n } finally {\n setSavingModel(null)\n }\n }\n\n /** Clear every stored override, including models the picker no longer shows. */\n const resetAllContextWindows = async () => {\n const models = Object.keys(status?.contextWindowOverrides ?? {})\n if (models.length === 0) return\n if (!window.confirm(t.contextWindowResetAllConfirm)) return\n try {\n setBusy('context')\n setError(null)\n const updated = normalizeStatus(await api.request<WorkBuddyWebStatus>('/settings', {\n method: 'POST',\n body: JSON.stringify({ contextWindowOverrides: Object.fromEntries(models.map((model) => [model, null])) }),\n }))\n setStatus(updated)\n setContextDrafts(contextDraftsFor(updated))\n notifyChange()\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n } finally {\n setBusy(null)\n }\n }\n\n const updateContextDraft = (modelId: string, draft: string): void => {\n setContextDrafts((prev) => ({ ...prev, [modelId]: draft }))\n }\n\n // Only checked models get a context row; the batch restore still covers every\n // stored override, including one left behind by a model the user unchecked.\n const contextModels = status?.models.filter((model) => model.enabled) ?? []\n const overrideCount = Object.keys(status?.contextWindowOverrides ?? {}).length\n const quota = status?.quota\n const authenticated = status?.authenticated === true\n // A failed status read is not \"no credential\": showing the credential hint\n // here would send the user chasing a problem that does not exist.\n const unreachable = statusFailed && status === null\n\n return {\n state: {\n status,\n loading,\n busy,\n error,\n connection,\n loginProgress,\n contextDrafts,\n savingModel,\n },\n derived: {\n poolAccounts,\n effortChoices,\n allModels,\n strayEffort,\n contextModels,\n overrideCount,\n quota,\n authenticated,\n unreachable,\n poolLabels: accountPoolLabels(t),\n },\n actions: {\n login,\n rescan,\n accountAction,\n deleteAccount,\n setStrategy,\n testConnection,\n refreshQuota,\n checkinNow,\n updateCheckin,\n toggleModel,\n setAllModels,\n updateEffort,\n refreshCatalog,\n saveContextWindow,\n resetContextWindow,\n resetAllContextWindows,\n updateContextDraft,\n },\n }\n}\n","/**\n * The WorkBuddy subscription settings card.\n *\n * Markup only: every piece of state, every effect and every request this card\n * makes lives in 'useWorkBuddySection.ts', which returns one named shape the JSX\n * below reads. The two files are the split of a single 885-line component — the\n * behaviour is unchanged, and this one should stay render-shaped.\n */\nimport React from 'react'\nimport type {\n WorkBuddyAccountSummaryDto,\n WorkBuddyModelOption,\n WorkBuddyReasoningEffort,\n} from '../../shared/workbuddy-contracts.ts'\nimport { AccountPoolSection } from '../common/AccountPoolSection.tsx'\nimport { ContextWindowEditor } from '../common/ContextWindowEditor.tsx'\nimport { ModelChecklist } from '../common/ModelChecklist.tsx'\nimport { formatCapacity, formatDate, formatReset } from '../common/format.ts'\nimport { useWorkBuddySection, type WorkBuddySectionProps } from './useWorkBuddySection.ts'\nimport { zh } from './locales.ts'\n\n/**\n * Display label per reasoning level. The locale dictionary only accepts flat\n * string values, so this nested table lives with the control that renders it.\n */\nconst EFFORT_LABELS: Record<WorkBuddyReasoningEffort, string> = {\n minimal: 'Minimal',\n low: 'Low',\n medium: 'Medium',\n high: 'High',\n xhigh: 'X-High',\n max: 'Max',\n}\n\n/** Mask a UIN so the card shows identity without publishing the full number. */\nexport function maskUin(uin?: string | null): string {\n if (uin === undefined || uin === null || uin === '') return '—'\n if (uin.length <= 6) return uin\n return `${uin.slice(0, 4)}****${uin.slice(-2)}`\n}\n\nexport function WorkBuddySection({ onModelChange, loadModelDirectory }: WorkBuddySectionProps): React.ReactElement {\n const { state, derived, actions } = useWorkBuddySection({ onModelChange, loadModelDirectory })\n const { status, loading, busy, error, connection, loginProgress, contextDrafts, savingModel } = state\n const {\n poolAccounts, effortChoices, allModels, strayEffort, contextModels, overrideCount,\n quota, authenticated, unreachable, poolLabels,\n } = derived\n const {\n login, rescan, accountAction, deleteAccount, setStrategy, testConnection, refreshQuota,\n checkinNow, updateCheckin, toggleModel, setAllModels, updateEffort, refreshCatalog,\n saveContextWindow, resetContextWindow, resetAllContextWindows, updateContextDraft,\n } = actions\n\n const t = zh\n\n if (loading) {\n return (\n <div className=\"dsha-page\">\n <div className=\"dsha-empty\">{t.loading}</div>\n </div>\n )\n }\n\n return (\n <div className=\"dsha-page\">\n <AccountPoolSection<WorkBuddyAccountSummaryDto>\n accounts={poolAccounts}\n activeAccountId={status?.activeAccountId}\n rotationStrategy={status?.rotationStrategy ?? 'sequential'}\n labels={poolLabels}\n busy={busy}\n showQuota\n onLogin={() => void login('cn')}\n onSetPrimary={(id) => void accountAction('set-primary', id)}\n onDelete={(id) => void deleteAccount(id)}\n onClearCooldown={(id) => void accountAction('clear-cooldown', id)}\n onRelogin={(id) => void accountAction('relogin', id)}\n onSetStrategy={(strategy) => void setStrategy(strategy)}\n renderLoginActions={() => (\n <div className=\"dsha-account-add-actions\">\n <button className=\"dsha-btn dsha-btn-primary\" disabled={busy !== null} onClick={() => void login('cn')}>\n {busy === 'login:cn' ? t.authorizing : t.addCnAccount}\n </button>\n <button className=\"dsha-btn dsha-btn-primary\" disabled={busy !== null} onClick={() => void login('intl')}>\n {busy === 'login:intl' ? t.authorizing : t.addIntlAccount}\n </button>\n </div>\n )}\n renderAccountActions={(candidate) => (\n // Only an account this plugin owns may be deleted; a desktop account\n // is the IDE's, so the card offers hide/restore for it instead.\n candidate.removable ? null : (\n <>\n {candidate.hidden === true && (\n <button className=\"dsha-btn\" disabled={busy !== null} onClick={() => void accountAction('restore', candidate.id)}>\n {t.restoreAccount}\n </button>\n )}\n {candidate.hidden !== true && (\n <button className=\"dsha-btn\" disabled={busy !== null} onClick={() => void accountAction('hide', candidate.id)}>\n {t.hideAccount}\n </button>\n )}\n </>\n )\n )}\n renderDetails={(candidate) => (\n <>\n {candidate.uin ? <span>{t.uin}: {maskUin(candidate.uin)}</span> : null}\n {candidate.accountType ? <span>{t.accountType}: {candidate.accountType}</span> : null}\n <span>\n {t.region}: {candidate.region === 'intl' ? t.regionIntl : t.regionCn}\n </span>\n {candidate.domain ? (\n <span className=\"dshwb-mono\" title={`${candidate.domain} · ${candidate.backend ?? ''}`}>\n {candidate.domain}\n </span>\n ) : null}\n {candidate.hidden === true ? <span>{t.hiddenAccount}</span> : null}\n </>\n )}\n >\n {/* The shared empty state already covers \"no account signed in\"; only\n an unreachable route needs a panel of its own, because it must not\n read as a credential problem. */}\n {unreachable ? (\n <>\n <div className=\"dsha-empty\">{t.routeUnreachable}</div>\n <p className=\"dsha-notice\">{t.routeUnreachableHint}</p>\n </>\n ) : null}\n {loginProgress ? <p className=\"dsha-notice\">{loginProgress}</p> : null}\n <div className=\"dsha-actions\">\n <button className=\"dsha-btn\" disabled={busy !== null} onClick={() => void rescan()}>\n {busy === 'rescan' ? t.rescanning : t.rescan}\n </button>\n </div>\n </AccountPoolSection>\n\n {status?.checkin != null ? (\n <section className=\"dsha-group\">\n <div className=\"dsha-grouphead\">\n <h3>{t.dailyCheckin}</h3>\n </div>\n <p className=\"dsha-muted\">{t.checkinHint}</p>\n <div className=\"dsha-row\" style={{ marginBottom: 8 }}>\n <span className=\"dsha-label\" style={{ fontWeight: 600 }}>{t.checkinAuto}</span>\n <input\n type=\"checkbox\"\n checked={status.checkin.enabled}\n disabled={busy !== null}\n onChange={(event) => void updateCheckin({ enabled: event.currentTarget.checked })}\n />\n </div>\n <div className=\"dsha-row\">\n <span className=\"dsha-label\">{t.dailyCheckin}</span>\n <span className=\"dsha-value\">\n {t.checkinToday.replace('{done}', String(status.checkin.doneToday)).replace('{total}', String(status.checkin.totalAccounts))}\n {status.checkin.skippedToday > 0\n ? ` · ${t.checkinSkipped.replace('{count}', String(status.checkin.skippedToday))}`\n : ''}\n {status.checkin.failedToday > 0\n ? ` · ${t.checkinFailed.replace('{count}', String(status.checkin.failedToday))}`\n : ''}\n {` · ${status.checkin.lastRunAt === null ? t.checkinNever : t.checkinLastRun.replace('{time}', new Date(status.checkin.lastRunAt).toLocaleString())}`}\n </span>\n </div>\n <div className=\"dsha-actions\">\n <button className=\"dsha-btn\" disabled={busy !== null} onClick={() => void checkinNow()}>\n {busy === 'checkin' ? t.checkinRunning : t.checkinNow}\n </button>\n </div>\n </section>\n ) : null}\n\n <section className=\"dsha-group\">\n <div className=\"dsha-grouphead\">\n <h3>{t.connection}</h3>\n </div>\n <p className=\"dsha-notice\">\n {status?.serving === false && status.conflict\n ? t.routeConflict.replace('{detail}', status.conflict)\n : t.routeOwned}\n </p>\n <div className=\"dsha-actions\">\n <button\n className=\"dsha-btn\"\n disabled={busy !== null || !authenticated}\n onClick={() => void testConnection()}\n >\n {busy === 'connection' ? t.testingConnection : t.testConnection}\n </button>\n </div>\n </section>\n\n <section className=\"dsha-group\">\n <div className=\"dsha-grouphead\">\n <h3>{t.modelsSection}</h3>\n <button\n className=\"dsha-btn\"\n disabled={busy !== null || !authenticated}\n onClick={() => void refreshCatalog()}\n >\n {busy === 'catalog' ? t.refreshingCatalog : t.refreshCatalog}\n </button>\n </div>\n <p className=\"dsha-muted dsha-models-hint\">{t.modelsHint}</p>\n <ModelChecklist\n items={(status?.models ?? []).map((model: WorkBuddyModelOption) => ({\n id: model.id,\n name: model.name,\n hint: [\n formatCapacity(model.contextWindow),\n model.supportsImage ? t.imageSupport : t.textOnly,\n ...(model.reasoningEfforts && model.reasoningEfforts.length > 0\n ? [model.reasoningEfforts.join('/')]\n : []),\n ].join(' · '),\n enabled: model.enabled,\n }))}\n busy={busy !== null}\n onToggle={(id, enabled) => void toggleModel(id, enabled)}\n onToggleAll={(enabled) => void setAllModels(enabled)}\n labels={{ selectAll: t.selectAll, clearAll: t.unselectAll, list: t.modelsSection }}\n />\n </section>\n\n <section className=\"dsha-group\">\n <div className=\"dsha-grouphead\">\n <h3>{t.enhanced}</h3>\n </div>\n <div className=\"dsha-pref-row\">\n <div>\n <strong>{t.defaultReasoningEffort}</strong>\n <p className=\"dsha-muted\">{t.defaultReasoningEffortHint}</p>\n {strayEffort !== null ? <p className=\"dsha-muted\">{t.defaultEffortKept}</p> : null}\n </div>\n <select\n className=\"dsha-select\"\n aria-label={t.defaultReasoningEffort}\n value={status?.defaultReasoningEffort ?? ''}\n disabled={busy !== null}\n onChange={(event) => {\n const value = event.currentTarget.value\n void updateEffort(value === '' ? null : (value as WorkBuddyReasoningEffort))\n }}\n >\n <option value=\"\">{t.defaultEffortAuto}</option>\n {/* A saved level no model declares is kept selectable so opening\n the card does not silently rewrite the stored value. */}\n {strayEffort !== null ? (\n <option value={strayEffort}>{`${EFFORT_LABELS[strayEffort]} (${t.effortUnsupported})`}</option>\n ) : null}\n {effortChoices.map((choice) => (\n <option key={choice.value} value={choice.value}>\n {choice.models.length === allModels.length\n ? EFFORT_LABELS[choice.value]\n : `${EFFORT_LABELS[choice.value]} (${choice.models.length}/${allModels.length})`}\n </option>\n ))}\n </select>\n </div>\n {effortChoices.length === 0 ? (\n <p className=\"dsha-muted\">{t.noReasoningModels}</p>\n ) : null}\n </section>\n\n <section className=\"dsha-group\">\n <div className=\"dsha-grouphead\">\n <h3>{t.contextWindowSection}</h3>\n </div>\n <p className=\"dsha-muted\">{t.contextWindowHint}</p>\n <ContextWindowEditor\n rows={contextModels.map((model: WorkBuddyModelOption) => ({\n id: model.id,\n name: model.name,\n draft: contextDrafts[model.id] ?? '',\n inputLabel: `${model.name} context window`,\n hasOverride: status?.contextWindowOverrides[model.id] !== undefined,\n saving: savingModel === model.id,\n }))}\n labels={{\n tokens: 'tokens',\n save: t.save,\n saving: t.saving,\n reset: t.contextWindowReset,\n resetAll: t.contextWindowResetAll,\n empty: t.contextWindowNoneEnabled,\n }}\n busy={busy !== null}\n overrideCount={overrideCount}\n onDraftChange={(id, draft) => updateContextDraft(id, draft)}\n onCommit={(id) => void saveContextWindow(id)}\n onReset={(id) => void resetContextWindow(id)}\n onResetAll={() => void resetAllContextWindows()}\n />\n </section>\n\n <section className=\"dsha-group\">\n <div className=\"dsha-grouphead\">\n <h3>{t.quotaSection}</h3>\n <button\n className=\"dsha-btn\"\n disabled={busy !== null || !authenticated}\n onClick={() => void refreshQuota()}\n >\n {busy === 'quota' ? t.refreshingQuota : t.refreshQuota}\n </button>\n </div>\n <p className=\"dsha-muted\">{t.quotaDesc}</p>\n {/* The progress bars moved into each account card: quota follows the\n account, so a bar here could only ever describe whichever account\n happened to be active when the snapshot was read. What stays is what\n has no per-account bar to live in — the package and its credits, the\n cycle counters, the meters that state no share, and the freshness of\n this reading. */}\n <p className=\"dsha-muted\">{poolLabels.quotaFactsScope}</p>\n\n {!authenticated ? (\n <div className=\"dsha-empty\">{t.signedOut}</div>\n ) : quota === null || quota === undefined ? (\n <div className=\"dsha-empty\">{busy === 'quota' ? t.refreshingQuota : t.quotaEmpty}</div>\n ) : (\n <div className=\"dsha-quota-card\">\n <div className=\"dsha-quota-title\">\n <strong>{quota.packageName || t.quotaPackage}</strong>\n <span>\n {quota.remainingCredits !== null\n ? `${quota.remainingCredits} ${t.credits}`\n : '—'}\n </span>\n </div>\n\n {quota.cycleUsedCredits !== null && (\n <div className=\"dsha-row\">\n <span className=\"dsha-label\">{t.quotaCycle}</span>\n <span className=\"dsha-value\">\n {quota.cycleUsedCredits}\n {quota.cycleCredits !== null ? ` / ${quota.cycleCredits}` : ''}\n {` ${t.credits}`}\n </span>\n </div>\n )}\n {quota.cycleEndsAt !== null && (\n <div className=\"dsha-row\">\n <span className=\"dsha-label\">{t.quotaReset}</span>\n <span className=\"dsha-value\">\n {formatDate(quota.cycleEndsAt)}\n {formatReset(quota.cycleEndsAt) ? ` · ${formatReset(quota.cycleEndsAt)}` : ''}\n </span>\n </div>\n )}\n\n {quota.meters.filter((meter) => meter.remainingFraction === null).map((meter) => (\n <div key={meter.id} className=\"dsha-meter-wrap\">\n <div className=\"dsha-meter-label\">\n <span>{meter.label}</span>\n <strong>{meter.limit ?? '—'}</strong>\n </div>\n <div className=\"dsha-meter-meta\">\n {meter.used !== null && <span>{meter.used} / {meter.limit ?? '—'}</span>}\n {meter.resetsAt !== null && <span>{t.quotaReset}: {formatReset(meter.resetsAt)}</span>}\n </div>\n {meter.description !== null && (\n <div className=\"dsha-meter-meta\"><span>{meter.description}</span></div>\n )}\n </div>\n ))}\n\n {quota.meters.length === 0 && <div className=\"dsha-empty\">{t.quotaEmpty}</div>}\n\n <div className=\"dsha-timestamp\">\n {t.updatedAt.replace('{time}', new Date(quota.fetchedAt).toLocaleString())}\n </div>\n </div>\n )}\n </section>\n\n {error && (\n <div className=\"dsha-error\">\n <div>{error}</div>\n </div>\n )}\n </div>\n )\n}\n","/**\n * The MiniMax Code routes the settings card consumes.\n *\n * This module used to carry its own reader — the last one left after\n * `common/line-api.ts` took the other nine — and it still carried the predicate\n * the shared reader dropped: a 2xx answer of `{ ok: false, error }` with no\n * `value` was handed back as a payload instead of raising. Delegating is\n * therefore not only de-duplication: it is what makes this line answer a\n * failure exactly like its siblings.\n *\n * The names stay as they were so the hook that consumes them does not have to\n * change with the reader.\n */\nimport { MINIMAX_CODE_ROUTE_PREFIX } from '../../shared/minimax-code-contracts.ts'\nimport { createLineApi } from '../common/line-api.ts'\n\nconst api = createLineApi(MINIMAX_CODE_ROUTE_PREFIX, 'MiniMax Code')\n\nexport const request = api.request\nexport const get = api.get\nexport const post = api.post\n\nexport function messageOf(cause: unknown): string {\n return cause instanceof Error ? cause.message : String(cause)\n}\n","import { accountPoolEn, accountPoolZh } from '../common/account-pool-labels.ts'\n\nexport const NS_MINIMAX_CODE = 'dsh-minimax-code'\n\nexport const zh = {\n // The account-management card is shared with every other provider tab.\n ...accountPoolZh,\n title: 'MiniMax Code',\n pageDesc: '登录 MiniMax Code 编程订阅(设备码 OAuth),复用本机 MiniMax Code 的登录态,管理账号、连接与模型。',\n account: '账号',\n signedIn: '已登录',\n signedOut: '未登录',\n accountLabel: '账号标签',\n accountId: '账号 ID',\n email: '邮箱',\n region: '区域',\n regionCn: '中国大陆 (minimax.cn)',\n regionGlobal: '国际 (minimax.io)',\n expiresAt: '令牌到期',\n expiresRemaining: '剩余 {hours} 小时',\n expiresExpired: '已过期',\n expiresHint: '访问令牌约 24 小时有效;Host 会在令牌过期或上游返回 401 时自动刷新。刷新被拒绝时请回到 MiniMax Code 重新登录。',\n signIn: '登录 MiniMax Code',\n signingIn: '正在申请设备码...',\n signOut: '登出',\n cancelSignIn: '取消登录',\n deviceCodeSection: '设备码授权',\n deviceCodeHint: '在浏览器中打开下方链接(用户码已单独列出,可复制),用你的 MiniMax 账号确认授权。',\n userCode: '用户码',\n copyCode: '复制用户码',\n copied: '已复制',\n openSignInPage: '打开授权页面',\n codeExpires: '设备码有效期',\n codeMinutes: '剩余 {minutes} 分钟',\n waitingAuthorization: '等待浏览器授权...',\n loginFailed: '登录失败',\n loginExpired: '设备码已过期,请重新发起登录。',\n loginDenied: '授权被拒绝。',\n logoutOwnedByApp: '当前登录态属于 MiniMax Code 桌面端:本插件复用它并会在需要时续期写回,但不会撤销或删除它(那会把你从正在运行的 MiniMax Code 里踢下线)。请在 MiniMax Code 应用中退出登录。',\n connection: '连接',\n routeOwned: '本插件正在服务该模型路由。',\n routeConflict: '模型路由已被其他 Provider 占用:{detail}。请在 DSH 设置中移除重复的 Provider 配置后重新加载。',\n testConnection: '测试连接',\n testingConnection: '测试中...',\n testSuccess: '连接正常',\n testSuccessModel: '连接正常({model})',\n testFailed: '连接失败',\n modelsSection: '模型',\n modelsHint: '模型目录由本线路硬编码(MiniMax Code 未开放 /v1/models 接口),当前共 {count} 个可用模型。勾选后模型才会出现在对话页的模型选择列表中;未勾选或关闭下方「启用此供应商」可在列表中隐藏该线路。',\n modelsUnavailable: '暂无可显示的模型。',\n quotaSection: '用量与配额',\n dailyCheckin: '每日签到',\n checkinHint: '用本线路自己的登录态签到(与官方 MiniMax Code 客户端同一条接口)。DSH 启动时自动签到一次,运行期间每 10 分钟补检,进程关闭的当天不会签到。',\n checkinAuto: '自动签到',\n checkinToday: '今日已签 {done}/{total}',\n checkinSkipped: '{count} 个暂不可签',\n checkinFailed: '{count} 个失败',\n checkinStreak: '连续 {days} 天',\n checkinClaimed: '本轮 +{points} 积分',\n checkinLastRun: '上次运行:{time}',\n checkinNever: '尚未运行',\n checkinNow: '立即签到',\n checkinRunning: '签到中…',\n quotaUnavailable: '暂时没有用量数据。',\n quotaNeedsApiKey: '上游拒绝了这个登录态读取用量(官方客户端的用量端点要求带官方客户端标识头,本插件默认不伪造)。请在 MiniMax 控制台的用量条里查看 Token Plan 用量;如果你接受该取舍,可设 DSH_MINIMAX_CODE_QUOTA_ATTRIBUTION=1 后重试。',\n quotaUnreachable: '暂时读不到用量(用量端点未应答),稍后会自动重试。',\n quotaTokenExpired: '读取用量时令牌刚好过期,正在自动续期——账号仍然是登录状态,无需重新登录。',\n quotaStale: '下面是上一次成功读取到的用量(本次刷新未成功),稍后会自动重试。',\n quotaUsedShare: '已用 {percent}%',\n quotaRefresh: '刷新用量',\n quotaRefreshing: '刷新中...',\n composerLabel: '额度',\n // --- 与兄弟线路对齐的设置面(模型勾选 / 上下文窗口 / 默认思考深度)---\n selectAll: '全选',\n unselectAll: '全不选',\n enhanced: '增强功能',\n defaultReasoningEffort: '默认思考深度',\n defaultReasoningEffortHint: '控制支持推理的模型在未单独指定时的思考强度。',\n defaultEffortAuto: '自动(各模型默认)',\n contextWindowSection: '模型上下文窗口',\n contextWindowHint: '默认值来自订阅网关的模型目录(每个模型的真实上下文上限);可覆盖为自定义容量,该值用于 DSH 的压缩与溢出判断,可输入 1M、512K、200K 等容量。',\n contextWindowNoneEnabled: '尚未勾选任何模型,先在上方「模型」中勾选。',\n contextWindowReset: '恢复默认',\n contextWindowResetAll: '全部恢复默认',\n tokens: 'tokens',\n save: '保存',\n saving: '保存中...',\n invalidCapacity: '容量格式无效:{value}',\n // --- 思考形态(与 model-catalog.ts 的三种模式同名同义)---\n thinkingAlwaysOn: '恒定开启(无档位)',\n thinkingToggle: '可关闭',\n thinkingForced: '强制开启(可选档位)',\n capText: '文本',\n capImage: '图片',\n loading: '加载中...',\n unknown: '—',\n} as const\n\nexport const en: Record<keyof typeof zh, string> = {\n ...accountPoolEn,\n title: 'MiniMax Code',\n pageDesc: 'Sign in to the MiniMax Code coding subscription (device-code OAuth) and reuse the local MiniMax Code sign-in to manage the account, connection, and models.',\n account: 'Account',\n signedIn: 'Signed in',\n signedOut: 'Not signed in',\n accountLabel: 'Account label',\n accountId: 'Account ID',\n email: 'Email',\n region: 'Region',\n regionCn: 'Mainland China (minimax.cn)',\n regionGlobal: 'Global (minimax.io)',\n expiresAt: 'Token expires',\n expiresRemaining: '{hours} h left',\n expiresExpired: 'Expired',\n expiresHint: 'The access token lives about 24 hours; the Host refreshes it once it expires or the upstream answers 401. When a refresh is rejected, sign in again from MiniMax Code.',\n signIn: 'Sign in to MiniMax Code',\n signingIn: 'Requesting a device code...',\n signOut: 'Sign out',\n cancelSignIn: 'Cancel',\n deviceCodeSection: 'Device authorization',\n deviceCodeHint: 'Open the link below in a browser (the user code is listed separately so it can be copied) and approve it with your MiniMax account.',\n userCode: 'User code',\n copyCode: 'Copy user code',\n copied: 'Copied',\n openSignInPage: 'Open the sign-in page',\n codeExpires: 'Device code expires',\n codeMinutes: '{minutes} min left',\n waitingAuthorization: 'Waiting for browser authorization...',\n loginFailed: 'Sign-in failed',\n loginExpired: 'The device code expired — start the sign-in again.',\n loginDenied: 'Authorization was denied.',\n logoutOwnedByApp: 'This sign-in belongs to the MiniMax Code desktop app. This plugin reuses it and renews it in place when needed, but it will not revoke or delete it (doing so would sign you out of the running MiniMax Code app). Sign out in the MiniMax Code app instead.',\n connection: 'Connection',\n routeOwned: 'This plugin serves the model route.',\n routeConflict: 'Another provider already owns the model route: {detail}. Remove the duplicate provider configuration in DSH settings and reload.',\n testConnection: 'Test connection',\n testingConnection: 'Testing...',\n testSuccess: 'Connection OK',\n testSuccessModel: 'Connection OK ({model})',\n testFailed: 'Connection failed',\n modelsSection: 'Models',\n modelsHint: 'The catalog is hardcoded on this line (MiniMax Code exposes no /v1/models endpoint): {count} models available. Only checked models appear in the conversation model picker; unchecking or switching off \"Enable this provider\" hides the line from the list.',\n modelsUnavailable: 'No model to show yet.',\n quotaSection: 'Usage & quota',\n dailyCheckin: 'Daily check-in',\n checkinHint: 'Signs in with this line’s own credential (the same interface the official MiniMax Code client uses). The host signs in once at startup and re-checks every 10 minutes while running; a day the process never runs is not signed.',\n checkinAuto: 'Auto check-in',\n checkinToday: 'Checked in today {done}/{total}',\n checkinSkipped: '{count} not claimable yet',\n checkinFailed: '{count} failed',\n checkinStreak: '{days}-day streak',\n checkinClaimed: '+{points} credits this run',\n checkinLastRun: 'Last run: {time}',\n checkinNever: 'Never run',\n checkinNow: 'Check in now',\n checkinRunning: 'Checking in…',\n quotaUnavailable: 'No usage data yet.',\n quotaNeedsApiKey: 'The service refused this sign-in for the usage read (the official client\\'s endpoint expects first-party attribution headers, which this plugin does not forge by default). Check the usage bar in the MiniMax console; if you accept that trade, set DSH_MINIMAX_CODE_QUOTA_ATTRIBUTION=1 and retry.',\n quotaUnreachable: 'Usage is temporarily unreadable (the usage endpoint did not answer); this retries on its own.',\n quotaTokenExpired: 'The token expired just as usage was being read, and is being renewed automatically. The account is still signed in; no action needed.',\n quotaStale: 'Below is the last usage read that succeeded (this refresh failed); it retries on its own.',\n quotaUsedShare: '{percent}% used',\n quotaRefresh: 'Refresh usage',\n quotaRefreshing: 'Refreshing...',\n composerLabel: 'Quota',\n selectAll: 'Select all',\n unselectAll: 'Unselect all',\n enhanced: 'Enhanced',\n defaultReasoningEffort: 'Default reasoning effort',\n defaultReasoningEffortHint: 'Thinking strength for reasoning models when the conversation does not pick one.',\n defaultEffortAuto: 'Auto (each model default)',\n contextWindowSection: 'Model context windows',\n contextWindowHint: 'Defaults come from the subscription gateway model directory (each model\\'s real upper bound). Override one to a custom capacity; the value feeds the compression and overflow decisions. Accepts 1M, 512K, 200K and similar.',\n contextWindowNoneEnabled: 'No model is checked yet — pick one in \"Models\" above.',\n contextWindowReset: 'Restore default',\n contextWindowResetAll: 'Restore all defaults',\n tokens: 'tokens',\n save: 'Save',\n saving: 'Saving...',\n invalidCapacity: 'Invalid capacity: {value}',\n thinkingAlwaysOn: 'Always on (no level)',\n thinkingToggle: 'Can be disabled',\n thinkingForced: 'Forced on (level selectable)',\n capText: 'Text',\n capImage: 'Image',\n loading: 'Loading...',\n unknown: '—',\n}\n\nexport const dictionaries = {\n zh,\n 'zh-CN': zh,\n en,\n 'en-US': en,\n}\n\nexport type MinimaxCodeLocaleKey = keyof typeof zh\n","/**\n * The MiniMax Code card's state, effects and actions.\n *\n * Split out of 'MinimaxCodeSection.tsx' so that file is markup and this one is\n * behaviour: what the card tracks, what it derives from a status answer, and\n * every request a control can make. The view reads one named shape — see\n * `MinimaxCodeSectionView` — so the contract between the two is visible here\n * rather than inferred from the JSX.\n */\nimport { useCallback, useEffect, useRef, useState } from 'react'\nimport type {\n AccountPoolStatusDto,\n AccountRotationStrategy,\n} from '../../shared/account-pool-contracts.ts'\nimport type {\n MinimaxCodeAccount,\n MinimaxCodeModelOption,\n MinimaxCodeQuota,\n MinimaxCodeReasoningEffort,\n MinimaxCodeWebLogin,\n MinimaxCodeWebStatus,\n} from '../../shared/minimax-code-contracts.ts'\nimport type { AccountPoolLabels } from '../common/AccountPoolSection.tsx'\nimport { contextDraftsFor } from '../common/ContextWindowEditor.tsx'\nimport { formatCapacity, parsePositiveCapacity } from '../common/format.ts'\nimport { createQuotaFollowUp, type QuotaFollowUp } from '../common/quota-follow-up.ts'\nimport { get, messageOf, post } from './api.ts'\nimport { zh } from './locales.ts'\n\n/** The pool slice the status card renders, absent when the line has no pool. */\nexport type MinimaxCodePoolStatus = Pick<AccountPoolStatusDto, 'accounts' | 'rotationStrategy'> & {\n activeAccountId?: string\n}\n\n/**\n * The keys this card renders.\n *\n * The provider hub hosts every provider tab inside one settings section whose\n * injected `t` seat is bound to the hub's own namespace, and every sibling tab\n * therefore renders its own dictionary instead of that seat (see KimiCodeSection,\n * WorkBuddySection and CommandCodeSection, none of which declare a locale prop).\n * This card must do the same: its keys are not a subset of the hub's, so using the\n * hub's seat resolves the overlap to ChatGPT wording (\"使用 ChatGPT 登录\" on the\n * MiniMax tab) and every other key to the literal key text.\n */\nexport type Translate = (key: keyof typeof zh) => string\n\n/** The card's own dictionary; stable identity keeps effect dependencies intact. */\nexport const fallbackTranslate: Translate = (key) => zh[key]\n\n/**\n * The shared pool card's labels, resolved through this card's dictionary.\n *\n * The sibling tabs hand the shared card their raw `zh` object, which works because\n * they render `zh` directly. This card renders through a translate function\n * instead, so the same label set is assembled here by looking each key up. It is\n * derived from the shared ZH label object's own keys, so a label added to the\n * shared card cannot be silently missed — the `satisfies` below turns that into a\n * compile error.\n */\nfunction accountPoolLabelsFor(t: Translate): AccountPoolLabels {\n return {\n accountPool: t('accountPool'),\n addAccount: t('addAccount'),\n accountCount: t('accountCount'),\n primaryAccount: t('primaryAccount'),\n activeAccount: t('activeAccount'),\n setPrimary: t('setPrimary'),\n deleteAccount: t('deleteAccount'),\n cooling: t('cooling'),\n cooldownLeft: t('cooldownLeft'),\n clearCooldown: t('clearCooldown'),\n needsRelogin: t('needsRelogin'),\n relogin: t('relogin'),\n rotationStrategy: t('rotationStrategy'),\n strategySequential: t('strategySequential'),\n strategyRoundRobin: t('strategyRoundRobin'),\n strategySticky: t('strategySticky'),\n noAccounts: t('noAccounts'),\n email: t('email'),\n expires: t('expiresAt'),\n lastUsed: t('lastUsed'),\n accountId: t('accountId'),\n accountQuota: t('accountQuota'),\n quotaNone: t('quotaNone'),\n quotaSnapshot: t('quotaSnapshot'),\n quotaResets: t('quotaResets'),\n quotaExhausted: t('quotaExhausted'),\n quotaWindow: t('quotaWindow'),\n quotaUsed: t('quotaUsed'),\n quotaFactsScope: t('quotaFactsScope'),\n composerLabel: t('composerLabel'),\n }\n}\n\n/** Device-code poll cadence. The host owns the real expiry. */\nconst LOGIN_POLL_INTERVAL_MS = 2_000\n\n/** `/login/poll` answer, exactly as the frozen route table defines it. */\ninterface LoginPollResult {\n status: 'pending' | 'authenticated' | 'expired' | 'denied'\n account?: MinimaxCodeAccount\n}\n\n/** `/login/start` answer: `{ ok: true, login }` per the frozen route table. */\ninterface LoginStartResult {\n ok?: boolean\n login?: MinimaxCodeWebLogin\n}\n\n/** `/test` answer: `{ ok, model?, error? }` per the frozen route table. */\ninterface ConnectionTestResult {\n ok?: boolean\n model?: string\n error?: string\n}\n\n/**\n * Props this card accepts.\n *\n * Deliberately the same shape every sibling tab declares: the hub hands each tab\n * only the refresh callback. The card does not take the hub's `settings.section`\n * runtime seat or its locale seat, because it renders its own dictionary (see\n * below) and needs none of that scope's other props.\n */\nexport interface MinimaxCodeSectionProps {\n onModelChange?: () => void\n}\n\n/**\n * Everything the card's view consumes, grouped by kind.\n *\n * Returned as one named shape instead of one status blob: a reader can see at a\n * glance what the hook tracks, what it computes from a status answer, and what\n * the view is allowed to ask it to do.\n */\nexport interface MinimaxCodeSectionView {\n /** Values that change as the card runs. */\n state: {\n /** Last status answer; null until the first read lands. */\n status: MinimaxCodeWebStatus | null\n /** True until the first status read settles, whatever its outcome. */\n loading: boolean\n /** Id of the action in flight, or null; every disabled control reads it. */\n busy: string | null\n /** The failure the card's error strip shows. */\n error: string | null\n /** The device-code flow being polled, when one is running. */\n flow: MinimaxCodeWebLogin | null\n /** Whether the user code was just copied, so the button can say so. */\n copied: boolean\n /** Result of the last explicit connection test, as one sentence. */\n connectionNotice: string | null\n /** One free-text capacity draft per model, keyed by model id. */\n contextDrafts: Record<string, string>\n /** Model id whose context-window save or restore is in flight. */\n savingModel: string | null\n /** The pool slice read beside the status; undefined when the line has no pool. */\n pool: MinimaxCodePoolStatus | undefined\n }\n /** Facts read straight off the current status answer. */\n derived: {\n /** Whether the line holds a usable credential. */\n authenticated: boolean\n /** The signed-in account, when the host reports one. */\n account: MinimaxCodeAccount | undefined\n /** The displayed account's usage snapshot, when the host has one. */\n quota: MinimaxCodeQuota | undefined\n /** Every catalog row, in catalog order. */\n models: MinimaxCodeModelOption[]\n /** Models the context-window editor offers: the enabled ones only. */\n contextModels: MinimaxCodeModelOption[]\n /** How many stored overrides exist, whether or not a row still shows them. */\n overrideCount: number\n /**\n * The line's label set, handed to the shared pool card as one object.\n *\n * The hook resolves it for its own sentences too, so the view takes the\n * assembled labels from here rather than reaching for a second binding.\n */\n poolLabels: AccountPoolLabels\n }\n /** Everything the view can trigger. */\n actions: {\n /** Start a device-code sign-in. */\n login(): Promise<void>\n cancelLogin(): Promise<void>\n /** Copy the flow's user code; the button says so for two seconds. */\n copyCode(): Promise<void>\n logout(): Promise<void>\n /** One account-level action on the shared pool card. */\n poolAction(\n action: 'set-primary' | 'delete' | 'clear-cooldown' | 'relogin',\n accountId: string,\n ): Promise<void>\n setStrategy(strategy: AccountRotationStrategy): Promise<void>\n toggleModel(modelId: string, checked: boolean): void\n setAllModels(selectAll: boolean): void\n /** Flip the check-in scheduler's own switch. */\n setCheckinEnabled(enabled: boolean): Promise<void>\n /** Run one check-in pass now. */\n runCheckinNow(): Promise<void>\n updateEffort(effort: MinimaxCodeReasoningEffort | null): Promise<void>\n saveContextWindow(modelId: string): Promise<void>\n resetContextWindow(modelId: string): Promise<void>\n resetAllContextWindows(): Promise<void>\n refreshQuota(): Promise<void>\n testConnection(): Promise<void>\n /** Edit one capacity draft mid-typing; the editor never parses it. */\n updateContextDraft(modelId: string, draft: string): void\n }\n}\n\nexport function useMinimaxCodeSection({ onModelChange }: MinimaxCodeSectionProps): MinimaxCodeSectionView {\n const t: Translate = fallbackTranslate\n const [status, setStatus] = useState<MinimaxCodeWebStatus | null>(null)\n const [loading, setLoading] = useState(true)\n const [busy, setBusy] = useState<string | null>(null)\n const [error, setError] = useState<string | null>(null)\n const [flow, setFlow] = useState<MinimaxCodeWebLogin | null>(null)\n const [copied, setCopied] = useState(false)\n // Result of an explicit connection test. The button used to end silently on\n // success, which is indistinguishable from a click that never registered.\n const [connectionNotice, setConnectionNotice] = useState<string | null>(null)\n // Free-text context-window drafts, keyed by model id, so a half-typed value\n // does not round-trip to the host on every keystroke.\n const [contextDrafts, setContextDrafts] = useState<Record<string, string>>({})\n const [savingModel, setSavingModel] = useState<string | null>(null)\n // The pool slice, read beside the status. Absent until the first read answers,\n // and absent for a host that has no pool installed at all.\n const [pool, setPool] = useState<MinimaxCodePoolStatus | undefined>(undefined)\n\n // The follow-up poll for a usage read the host is running behind its answer.\n // Every sibling card has this and this one did not, which is why a page\n // opened right after a restart sat on \"no usage data\" until the 60 s tick:\n // the host was already fetching, the answer simply could not say so.\n const quotaFollowUp = useRef<QuotaFollowUp | undefined>(undefined)\n\n const loadStatus = useCallback(async (quiet = false) => {\n if (!quiet) setError(null)\n try {\n const next = await get<MinimaxCodeWebStatus>('/status')\n setStatus(next)\n setContextDrafts(contextDraftsFor(next))\n quotaFollowUp.current ??= createQuotaFollowUp()\n quotaFollowUp.current.observe(next.quotaRefreshing === true, () => { void loadStatus(true) })\n } catch (cause) {\n if (!quiet) setError(messageOf(cause))\n } finally {\n setLoading(false)\n }\n }, [])\n\n useEffect(() => {\n void loadStatus()\n void loadPool()\n const refreshWhenVisible = (): void => {\n if (document.visibilityState === 'visible') {\n void loadStatus(true)\n void loadPool()\n }\n }\n document.addEventListener('visibilitychange', refreshWhenVisible)\n const timer = window.setInterval(refreshWhenVisible, 60_000)\n return () => {\n window.clearInterval(timer)\n document.removeEventListener('visibilitychange', refreshWhenVisible)\n quotaFollowUp.current?.cancel()\n }\n }, [loadStatus])\n\n const loginId = flow?.loginId\n\n // Authorization happens in a browser this card does not control, so the host\n // owns the device-code exchange and the card polls the host for its verdict.\n useEffect(() => {\n if (loginId === undefined) return\n let stopped = false\n const timer = window.setInterval(() => {\n void (async () => {\n try {\n const poll = await post<LoginPollResult>('/login/poll', { loginId })\n if (stopped || poll.status === 'pending') return\n stopped = true\n window.clearInterval(timer)\n setFlow(null)\n if (poll.status === 'authenticated') {\n await loadStatus()\n onModelChange?.()\n return\n }\n setError(poll.status === 'expired' ? t('loginExpired') : t('loginDenied'))\n } catch {\n // A failed poll is transient; the next tick retries.\n }\n })()\n }, LOGIN_POLL_INTERVAL_MS)\n return () => {\n stopped = true\n window.clearInterval(timer)\n }\n }, [loginId, loadStatus, onModelChange, t])\n\n /**\n * Fetch the usage snapshot once, the first time the card sees a signed-in\n * account without one.\n *\n * The status route refreshes usage BEHIND its answer, so it never blocks on a\n * network read; that means the very first paint has no snapshot. Asking here\n * fills the section immediately instead of leaving it empty for a whole poll\n * interval. A failure is silent on purpose: the section already explains that no\n * usage is available, and a usage read must never surface as an error banner.\n */\n // Declared here rather than beside the render values because the effect below\n // needs it and hooks must all run before the loading early-return.\n const authenticated = status?.authenticated === true\n const quotaRequested = useRef(false)\n useEffect(() => {\n if (quotaRequested.current || !authenticated || status?.quota !== undefined) return\n quotaRequested.current = true\n void (async () => {\n try {\n setStatus(await post<MinimaxCodeWebStatus>('/quota'))\n } catch {\n // Silent by design - see above.\n }\n })()\n }, [authenticated, status?.quota])\n\n const login = async (): Promise<void> => {\n try {\n setBusy('login')\n setError(null)\n setConnectionNotice(null)\n setCopied(false)\n const started = await post<LoginStartResult>('/login/start')\n // `login` is the frozen shape; a host that answers with the login object\n // itself is still read, because the card loses nothing by accepting it.\n const next = started.login ?? (typeof (started as { loginId?: unknown }).loginId === 'string'\n ? started as unknown as MinimaxCodeWebLogin\n : undefined)\n if (next === undefined) {\n setError(t('loginFailed'))\n return\n }\n setFlow(next)\n } catch (cause) {\n setError(messageOf(cause))\n } finally {\n setBusy(null)\n }\n }\n\n const cancelLogin = async (): Promise<void> => {\n const pending = flow\n setFlow(null)\n if (pending === null) return\n try {\n await post('/login/cancel', { loginId: pending.loginId })\n } catch (cause) {\n setError(messageOf(cause))\n }\n }\n\n const copyCode = async (): Promise<void> => {\n const code = flow?.userCode\n if (code === undefined || code === '') return\n try {\n await navigator.clipboard.writeText(code)\n setCopied(true)\n window.setTimeout(() => setCopied(false), 2_000)\n } catch {\n // Clipboard access can be denied; the code stays on screen to copy by hand.\n }\n }\n\n const logout = async (): Promise<void> => {\n try {\n setBusy('logout')\n setError(null)\n setConnectionNotice(null)\n setFlow(null)\n // The host refuses to sign out a credential the desktop app owns; that\n // refusal is a successful, expected answer rather than an error, so it is\n // surfaced as a notice and the status is re-read either way.\n const result = await post<{ ok?: boolean; native?: boolean; error?: string }>('/logout')\n if (result.native === true) {\n setConnectionNotice(result.error ?? t('logoutOwnedByApp'))\n }\n await loadStatus(true)\n onModelChange?.()\n } catch (cause) {\n setError(messageOf(cause))\n await loadStatus(true)\n } finally {\n setBusy(null)\n }\n }\n\n /**\n * Apply one model-selection patch through `/models`.\n *\n * The host owns the selection and answers with the whole fresh status, so the\n * card never guesses which ids ended up enabled.\n */\n /** Re-read the pool slice, which lives beside the status on its own route. */\n const loadPool = useCallback(async (): Promise<void> => {\n try {\n const next = await get<MinimaxCodePoolStatus>('/accounts')\n setPool(next)\n } catch {\n // A host without a pool answers with an error here; the section simply does\n // not render rather than reporting a failure the user cannot act on.\n setPool(undefined)\n }\n }, [])\n\n /** Run one account action, then re-read both the pool and the status. */\n const poolAction = async (\n action: 'set-primary' | 'delete' | 'clear-cooldown' | 'relogin',\n accountId: string,\n ): Promise<void> => {\n try {\n setBusy(action)\n setError(null)\n await post('/accounts', { action, accountId })\n await loadPool()\n await loadStatus(true)\n onModelChange?.()\n } catch (cause) {\n setError(messageOf(cause))\n } finally {\n setBusy(null)\n }\n }\n\n const setStrategy = async (strategy: AccountRotationStrategy): Promise<void> => {\n try {\n setBusy('strategy')\n setError(null)\n await post('/accounts', { action: 'strategy', strategy })\n await loadPool()\n } catch (cause) {\n setError(messageOf(cause))\n } finally {\n setBusy(null)\n }\n }\n\n const applyEnabled = async (enabledModelIds: string[]): Promise<void> => {\n try {\n setError(null)\n const updated = await post<MinimaxCodeWebStatus>('/models', { enabledModelIds })\n setStatus(updated)\n // A model that was just checked has no draft yet; the context-window\n // section only renders enabled models.\n setContextDrafts(contextDraftsFor(updated))\n onModelChange?.()\n } catch (cause) {\n setError(messageOf(cause))\n }\n }\n\n /** Flip the check-in scheduler's own switch, through the same settings route. */\n const setCheckinEnabled = async (enabled: boolean): Promise<void> => {\n try {\n setBusy('checkin')\n setError(null)\n const updated = await post<MinimaxCodeWebStatus>('/settings', { checkin: { enabled } })\n setStatus(updated)\n } catch (cause) {\n setError(messageOf(cause))\n } finally {\n setBusy(null)\n }\n }\n\n /** Run one check-in pass now: the toggle and the retry cap are bypassed. */\n const runCheckinNow = async (): Promise<void> => {\n try {\n setBusy('checkin')\n setError(null)\n const updated = await post<MinimaxCodeWebStatus>('/checkin/now')\n setStatus(updated)\n } catch (cause) {\n setError(messageOf(cause))\n } finally {\n setBusy(null)\n }\n }\n\n const toggleModel = (modelId: string, checked: boolean): void => {\n if (status === null) return\n const current = status.models.filter((model) => model.enabled).map((model) => model.id)\n const next = checked ? [...new Set([...current, modelId])] : current.filter((id) => id !== modelId)\n void applyEnabled(next)\n }\n\n const setAllModels = (selectAll: boolean): void => {\n if (status === null || status.models.length === 0) return\n void applyEnabled(selectAll ? status.models.map((model) => model.id) : [])\n }\n\n const updateEffort = async (effort: MinimaxCodeReasoningEffort | null): Promise<void> => {\n try {\n setError(null)\n const updated = await post<MinimaxCodeWebStatus>('/settings', { defaultReasoningEffort: effort })\n setStatus(updated)\n onModelChange?.()\n } catch (cause) {\n setError(messageOf(cause))\n }\n }\n\n const saveContextWindow = async (modelId: string): Promise<void> => {\n const raw = contextDrafts[modelId] ?? ''\n const parsed = parsePositiveCapacity(raw)\n if (parsed === null) {\n setError(t('invalidCapacity').replace('{value}', raw))\n return\n }\n try {\n setSavingModel(modelId)\n setError(null)\n const updated = await post<MinimaxCodeWebStatus>('/settings', { contextWindowOverrides: { [modelId]: parsed } })\n setStatus(updated)\n setContextDrafts((prev) => ({ ...prev, [modelId]: formatCapacity(parsed) }))\n onModelChange?.()\n } catch (cause) {\n setError(messageOf(cause))\n } finally {\n setSavingModel(null)\n }\n }\n\n const resetContextWindow = async (modelId: string): Promise<void> => {\n try {\n setSavingModel(modelId)\n setError(null)\n // `null` is the wire spelling of \"drop this override\": the host deletes the\n // key so the catalog default applies again.\n const updated = await post<MinimaxCodeWebStatus>('/settings', { contextWindowOverrides: { [modelId]: null } })\n setStatus(updated)\n const model = updated.models.find((entry) => entry.id === modelId)\n if (model !== undefined) {\n setContextDrafts((prev) => ({ ...prev, [modelId]: formatCapacity(model.defaultContextWindow) }))\n }\n onModelChange?.()\n } catch (cause) {\n setError(messageOf(cause))\n } finally {\n setSavingModel(null)\n }\n }\n\n const resetAllContextWindows = async (): Promise<void> => {\n const ids = Object.keys(status?.contextWindowOverrides ?? {})\n if (ids.length === 0) return\n try {\n setError(null)\n const updated = await post<MinimaxCodeWebStatus>('/settings', {\n contextWindowOverrides: Object.fromEntries(ids.map((id) => [id, null])),\n })\n setStatus(updated)\n setContextDrafts(contextDraftsFor(updated))\n onModelChange?.()\n } catch (cause) {\n setError(messageOf(cause))\n }\n }\n\n /** Force one usage read through `/quota` and render the fresh status. */\n const refreshQuota = async (): Promise<void> => {\n try {\n setBusy('quota')\n setError(null)\n setStatus(await post<MinimaxCodeWebStatus>('/quota'))\n } catch (cause) {\n setError(messageOf(cause))\n } finally {\n setBusy(null)\n }\n }\n\n const testConnection = async (): Promise<void> => {\n try {\n setBusy('test')\n setError(null)\n setConnectionNotice(null)\n const result = await post<ConnectionTestResult>('/test')\n if (result.ok === true) {\n setConnectionNotice(result.model === undefined || result.model === ''\n ? t('testSuccess')\n : t('testSuccessModel').replace('{model}', result.model))\n return\n }\n setConnectionNotice(result.error === undefined || result.error === ''\n ? t('testFailed')\n : `${t('testFailed')}:${result.error}`)\n } catch (cause) {\n setConnectionNotice(`${t('testFailed')}:${messageOf(cause)}`)\n } finally {\n setBusy(null)\n }\n }\n\n const updateContextDraft = (modelId: string, draft: string): void => {\n setContextDrafts((prev) => ({ ...prev, [modelId]: draft }))\n }\n\n const account = status?.account\n const quota = status?.quota\n const models = status?.models ?? []\n // Only enabled models have a context window to override: an unchecked model is\n // not offered to a conversation, so a capacity for it would be dead settings.\n const contextModels = status?.models.filter((model) => model.enabled) ?? []\n const overrideCount = Object.keys(status?.contextWindowOverrides ?? {}).length\n\n return {\n state: {\n status,\n loading,\n busy,\n error,\n flow,\n copied,\n connectionNotice,\n contextDrafts,\n savingModel,\n pool,\n },\n derived: {\n authenticated,\n account,\n quota,\n models,\n contextModels,\n overrideCount,\n poolLabels: accountPoolLabelsFor(t),\n },\n actions: {\n login,\n cancelLogin,\n copyCode,\n logout,\n poolAction,\n setStrategy,\n toggleModel,\n setAllModels,\n setCheckinEnabled,\n runCheckinNow,\n updateEffort,\n saveContextWindow,\n resetContextWindow,\n resetAllContextWindows,\n refreshQuota,\n testConnection,\n updateContextDraft,\n },\n }\n}\n","/**\n * The MiniMax Code settings card.\n *\n * Markup only: every piece of state, every effect and every request this card\n * makes lives in 'useMinimaxCodeSection.ts', which returns one named shape the\n * JSX below reads. The two files are the split of a single 915-line component —\n * the behaviour is unchanged, and this one should stay render-shaped.\n */\nimport React from 'react'\nimport {\n MINIMAX_CODE_REASONING_EFFORTS,\n type MinimaxCodeModelOption,\n type MinimaxCodeReasoningEffort,\n} from '../../shared/minimax-code-contracts.ts'\nimport { AccountPoolSection } from '../common/AccountPoolSection.tsx'\nimport { ContextWindowEditor } from '../common/ContextWindowEditor.tsx'\nimport { ModelChecklist } from '../common/ModelChecklist.tsx'\nimport { formatCapacity, formatDate } from '../common/format.ts'\nimport {\n fallbackTranslate,\n useMinimaxCodeSection,\n type MinimaxCodeSectionProps,\n type Translate,\n} from './useMinimaxCodeSection.ts'\n\n/** Human label per thinking mode, so the card states what the model does. */\nfunction thinkingLabel(mode: MinimaxCodeModelOption['thinking'], t: Translate): string {\n if (mode === 'always-on') return t('thinkingAlwaysOn')\n if (mode === 'forced-effort') return t('thinkingForced')\n return t('thinkingToggle')\n}\n\n/**\n * Hours still left on the access token, or null once it has run out.\n *\n * MiniMax Code's token lives about 24 hours, so hours are the unit the card\n * reports; a value worth a fraction of an hour keeps one decimal instead of\n * rounding down to 0.\n */\nexport function remainingHours(expiresAtMs: number | undefined): string | null {\n if (expiresAtMs === undefined || !Number.isFinite(expiresAtMs) || expiresAtMs <= 0) return null\n const hours = (expiresAtMs - Date.now()) / 3_600_000\n if (hours <= 0) return null\n return hours >= 10 ? hours.toFixed(0) : hours.toFixed(1)\n}\n\nexport function MinimaxCodeSection({ onModelChange }: MinimaxCodeSectionProps): React.JSX.Element {\n const { state, derived, actions } = useMinimaxCodeSection({ onModelChange })\n const { status, loading, busy, error, flow, copied, connectionNotice, contextDrafts, savingModel, pool } = state\n const { authenticated, account, quota, models, contextModels, overrideCount, poolLabels } = derived\n const {\n login, cancelLogin, copyCode, logout, poolAction, setStrategy, toggleModel, setAllModels,\n setCheckinEnabled, runCheckinNow, updateEffort, saveContextWindow, resetContextWindow,\n resetAllContextWindows, refreshQuota, testConnection, updateContextDraft,\n } = actions\n\n const t: Translate = fallbackTranslate\n\n if (loading) {\n return (\n <div className=\"dsha-page\">\n <div className=\"dsha-empty\">{t('loading')}</div>\n </div>\n )\n }\n\n const hours = remainingHours(account?.expiresAtMs)\n\n return (\n <div className=\"dsha-page\">\n <p className=\"dsha-muted\">{t('pageDesc')}</p>\n\n {pool !== undefined && (\n <AccountPoolSection\n labels={poolLabels}\n accounts={pool.accounts}\n rotationStrategy={pool.rotationStrategy}\n {...(pool.activeAccountId === undefined ? {} : { activeAccountId: pool.activeAccountId })}\n busy={busy}\n onLogin={() => void login()}\n onSetPrimary={(accountId) => void poolAction('set-primary', accountId)}\n onDelete={(accountId) => void poolAction('delete', accountId)}\n onClearCooldown={(accountId) => void poolAction('clear-cooldown', accountId)}\n // The account card renders its 重新登录 button only when this handler is\n // supplied, and every sibling line supplies one. Without it a MiniMax Code\n // account could be reported as needing a new sign-in with no way to act on\n // it — the badge appeared and no button ever did.\n onRelogin={(accountId) => void poolAction('relogin', accountId)}\n onSetStrategy={(strategy) => void setStrategy(strategy)}\n // Quota follows the account, so the host reports each account's own\n // newest snapshot and the card draws it inside that account's row.\n showQuota\n />\n )}\n\n {status?.checkin != null ? (\n <section className=\"dsha-group\">\n <div className=\"dsha-grouphead\">\n <h3>{t('dailyCheckin')}</h3>\n </div>\n <p className=\"dsha-muted\">{t('checkinHint')}</p>\n <div className=\"dsha-row\" style={{ marginBottom: 8 }}>\n <span className=\"dsha-label\" style={{ fontWeight: 600 }}>{t('checkinAuto')}</span>\n <input\n type=\"checkbox\"\n checked={status.checkin.enabled}\n disabled={busy !== null}\n onChange={(event) => void setCheckinEnabled(event.currentTarget.checked)}\n />\n </div>\n <div className=\"dsha-row\">\n <span className=\"dsha-label\">{t('dailyCheckin')}</span>\n <span className=\"dsha-value\">\n {t('checkinToday').replace('{done}', String(status.checkin.doneToday)).replace('{total}', String(status.checkin.totalAccounts))}\n {status.checkin.skippedToday > 0\n ? ` · ${t('checkinSkipped').replace('{count}', String(status.checkin.skippedToday))}`\n : ''}\n {status.checkin.failedToday > 0\n ? ` · ${t('checkinFailed').replace('{count}', String(status.checkin.failedToday))}`\n : ''}\n {status.checkin.streakDays !== undefined\n ? ` · ${t('checkinStreak').replace('{days}', String(status.checkin.streakDays))}`\n : ''}\n {status.checkin.claimedPoints !== undefined\n ? ` · ${t('checkinClaimed').replace('{points}', String(status.checkin.claimedPoints))}`\n : ''}\n {` · ${status.checkin.lastRunAt === null ? t('checkinNever') : t('checkinLastRun').replace('{time}', formatDate(status.checkin.lastRunAt))}`}\n </span>\n </div>\n <div className=\"dsha-actions\">\n <button className=\"dsha-btn\" disabled={busy !== null} onClick={() => void runCheckinNow()}>\n {busy === 'checkin' ? t('checkinRunning') : t('checkinNow')}\n </button>\n </div>\n </section>\n ) : null}\n\n <section className=\"dsha-group\">\n <div className=\"dsha-grouphead\">\n <h3>{t('account')}</h3>\n <span className=\"dsha-value\">{authenticated ? t('signedIn') : t('signedOut')}</span>\n </div>\n\n {authenticated && (\n <>\n <div className=\"dsha-row\">\n <span className=\"dsha-label\">{t('accountLabel')}</span>\n <span className=\"dsha-value\">{account?.label !== undefined && account.label !== '' ? account.label : t('unknown')}</span>\n </div>\n {account?.id !== undefined && account.id !== '' && (\n <div className=\"dsha-row\">\n <span className=\"dsha-label\">{t('accountId')}</span>\n <span className=\"dsha-value dshm-mono\">{account.id}</span>\n </div>\n )}\n {account?.email !== undefined && account.email !== '' && (\n <div className=\"dsha-row\">\n <span className=\"dsha-label\">{t('email')}</span>\n <span className=\"dsha-value\">{account.email}</span>\n </div>\n )}\n <div className=\"dsha-row\">\n <span className=\"dsha-label\">{t('expiresAt')}</span>\n <span className=\"dsha-value\">\n {formatDate(account?.expiresAtMs)}\n {hours === null\n ? ` · ${t('expiresExpired')}`\n : ` · ${t('expiresRemaining').replace('{hours}', hours)}`}\n </span>\n </div>\n </>\n )}\n\n {status !== null && (\n <>\n <div className=\"dsha-row\">\n <span className=\"dsha-label\">{t('region')}</span>\n <span className=\"dsha-value\">{status.region === 'global' ? t('regionGlobal') : t('regionCn')}</span>\n </div>\n <p className=\"dsha-notice\">{t('expiresHint')}</p>\n </>\n )}\n\n {flow !== null && (\n <div className=\"dsha-device-box\">\n <strong>{t('deviceCodeSection')}</strong>\n <p className=\"dsha-muted\">{t('deviceCodeHint')}</p>\n <div className=\"dsha-code-row\">\n <span className=\"dsha-code\" aria-label={t('userCode')}>{flow.userCode}</span>\n <button className=\"dsha-btn\" onClick={() => void copyCode()}>\n {copied ? t('copied') : t('copyCode')}\n </button>\n </div>\n {flow.verificationUri !== '' && (\n <a className=\"dsha-link\" href={flow.verificationUri} target=\"_blank\" rel=\"noreferrer noopener\">\n {flow.verificationUri}\n </a>\n )}\n <div className=\"dsha-row\">\n <span className=\"dsha-label\">{t('codeExpires')}</span>\n <span className=\"dsha-value\">\n {t('codeMinutes').replace('{minutes}', String(Math.max(1, Math.round(flow.expiresInSec / 60))))}\n </span>\n </div>\n <p className=\"dsha-muted\">{t('waitingAuthorization')}</p>\n <div className=\"dsha-actions\">\n {flow.verificationUri !== '' && (\n <a className=\"dsha-btn\" href={flow.verificationUri} target=\"_blank\" rel=\"noreferrer noopener\">\n {t('openSignInPage')}\n </a>\n )}\n <button className=\"dsha-btn\" onClick={() => void cancelLogin()}>\n {t('cancelSignIn')}\n </button>\n </div>\n </div>\n )}\n\n <div className=\"dsha-actions\">\n {flow === null && !authenticated && (\n <button className=\"dsha-btn dsha-btn-primary\" disabled={busy !== null} onClick={() => void login()}>\n {busy === 'login' ? t('signingIn') : t('signIn')}\n </button>\n )}\n {flow === null && authenticated && (\n // A native sign-in is the desktop app's, so this plugin cannot end it.\n // The button stays (hiding it would leave the user guessing where\n // sign-out went) but is disabled, and the reason is rendered as text\n // below rather than only as a tooltip: a disabled button does not fire\n // the hover events a tooltip needs, so a title alone would leave the\n // control unexplained.\n <button\n className=\"dsha-btn\"\n disabled={busy !== null || status?.ownedByPlugin === false}\n title={status?.ownedByPlugin === false ? t('logoutOwnedByApp') : undefined}\n onClick={() => void logout()}\n >\n {t('signOut')}\n </button>\n )}\n </div>\n {flow === null && authenticated && status?.ownedByPlugin === false && (\n <p className=\"dsha-muted\">{t('logoutOwnedByApp')}</p>\n )}\n </section>\n\n <section className=\"dsha-group\">\n <div className=\"dsha-grouphead\">\n <h3>{t('connection')}</h3>\n </div>\n {/* The provider id is contended like every sibling line's, so the same\n notice they render is rendered here: a user whose models are served by\n another adapter must be told that, not shown \"connected\" for a route\n this plugin does not own. */}\n <p className=\"dsha-notice\">\n {status?.serving === false && status.conflict\n ? t('routeConflict').replace('{detail}', status.conflict)\n : t('routeOwned')}\n </p>\n {connectionNotice !== null && <p className=\"dsha-muted\">{connectionNotice}</p>}\n <div className=\"dsha-actions\">\n <button\n className=\"dsha-btn\"\n disabled={busy !== null || !authenticated}\n onClick={() => void testConnection()}\n >\n {busy === 'test' ? t('testingConnection') : t('testConnection')}\n </button>\n </div>\n </section>\n\n <section className=\"dsha-group\">\n <div className=\"dsha-grouphead\">\n <h3>{t('modelsSection')}</h3>\n </div>\n <p className=\"dsha-muted\">{t('modelsHint').replace('{count}', String(models.length))}</p>\n {models.length === 0\n ? <div className=\"dsha-empty\">{t('modelsUnavailable')}</div>\n : (\n <ModelChecklist\n items={models.map((model: MinimaxCodeModelOption) => ({\n id: model.id,\n name: model.name,\n hint: [\n thinkingLabel(model.thinking, t),\n ...(model.description === null || model.description === '' ? [] : [model.description]),\n ].join(' · ') || undefined,\n enabled: model.enabled,\n }))}\n busy={busy !== null}\n onToggle={toggleModel}\n onToggleAll={setAllModels}\n labels={{ selectAll: t('selectAll'), clearAll: t('unselectAll'), list: t('modelsSection') }}\n />\n )}\n </section>\n\n <section className=\"dsha-group\">\n <div className=\"dsha-grouphead\">\n <h3>{t('enhanced')}</h3>\n </div>\n <div className=\"dsha-pref-row\">\n <div>\n <strong>{t('defaultReasoningEffort')}</strong>\n <p className=\"dsha-muted\">{t('defaultReasoningEffortHint')}</p>\n </div>\n <select\n className=\"dsha-select\"\n aria-label={t('defaultReasoningEffort')}\n value={status?.defaultReasoningEffort ?? ''}\n disabled={busy !== null}\n onChange={(event) => {\n const value = event.currentTarget.value\n void updateEffort(value === '' ? null : (value as MinimaxCodeReasoningEffort))\n }}\n >\n <option value=\"\">{t('defaultEffortAuto')}</option>\n {MINIMAX_CODE_REASONING_EFFORTS.map((effort) => (\n <option key={effort} value={effort}>{effort}</option>\n ))}\n </select>\n </div>\n </section>\n\n <section className=\"dsha-group\">\n <div className=\"dsha-grouphead\">\n <h3>{t('contextWindowSection')}</h3>\n </div>\n <p className=\"dsha-muted\">{t('contextWindowHint')}</p>\n <ContextWindowEditor\n rows={contextModels.map((model: MinimaxCodeModelOption) => ({\n id: model.id,\n name: model.name,\n draft: contextDrafts[model.id] ?? '',\n meta: model.defaultContextWindow < model.contextWindow\n ? formatCapacity(model.contextWindow)\n : undefined,\n inputLabel: `${model.name} ${t('contextWindowSection')}`,\n hasOverride: status?.contextWindowOverrides[model.id] !== undefined,\n saving: savingModel === model.id,\n }))}\n labels={{\n tokens: t('tokens'),\n save: t('save'),\n saving: t('saving'),\n reset: t('contextWindowReset'),\n resetAll: t('contextWindowResetAll'),\n empty: t('contextWindowNoneEnabled'),\n }}\n busy={busy !== null}\n overrideCount={overrideCount}\n metaClassName=\"dsha-model-meta\"\n onDraftChange={(id, draft) => updateContextDraft(id, draft)}\n onCommit={(id) => void saveContextWindow(id)}\n onReset={(id) => void resetContextWindow(id)}\n onResetAll={() => void resetAllContextWindows()}\n />\n </section>\n\n <section className=\"dsha-group\">\n <div className=\"dsha-grouphead\">\n <h3>{t('quotaSection')}</h3>\n <button\n className=\"dsha-btn\"\n disabled={busy !== null || !authenticated}\n onClick={() => void refreshQuota()}\n >\n {busy === 'quota' ? t('quotaRefreshing') : t('quotaRefresh')}\n </button>\n </div>\n {/*\n The progress bars moved into each account card: quota follows the\n account, so a bar here could only ever describe whichever account\n happened to be active when the snapshot was read. What stays is what has\n no per-account bar to live in — the plan, each window's name with its\n counts and reset moment, the freshness of this reading, and the stale\n flag — and the note below says which account those facts describe.\n */}\n <p className=\"dsha-muted\">{t('quotaFactsScope')}</p>\n {quota === undefined\n ? (\n // The contract makes quota optional and the usage read is allowed to\n // fail, so the section explains itself rather than rendering an empty\n // meter. The host separates the refusal worth acting on (this\n // sign-in's credential type cannot read usage at all) from an endpoint\n // that merely did not answer, and each gets its own sentence.\n <p className=\"dsha-notice dshm-quota-note\">\n {status?.quotaUnavailable === 'credential-not-accepted'\n ? t('quotaNeedsApiKey')\n : status?.quotaUnavailable === 'unreachable'\n ? t('quotaUnreachable')\n : status?.quotaUnavailable === 'token-expired'\n ? t('quotaTokenExpired')\n : t('quotaUnavailable')}\n </p>\n )\n : (\n <div className=\"dsha-quota-card\">\n <div className=\"dsha-quota-title\">\n <strong>{quota.label}</strong>\n {quota.usedPercent !== undefined && (\n <span>{t('quotaUsedShare').replace('{percent}', String(Math.round(quota.usedPercent)))}</span>\n )}\n </div>\n {/* The per-window rows are gone: each window's remaining share, its\n counts and its reset moment are drawn on the account card that\n owns the snapshot. The card title above stays because the\n aggregate share has no per-account home. */}\n {/*\n The last read failed but the host is still serving the numbers that\n last parsed. Showing them WITH that qualification beats the old\n behaviour of replacing a working quota box with a sentence that\n read like a sign-in prompt.\n */}\n {status?.quotaUnavailable === 'stale' && (\n <p className=\"dsha-notice dshm-quota-note\">{t('quotaStale')}</p>\n )}\n </div>\n )}\n </section>\n\n {error !== null && (\n <div className=\"dsha-error\">\n <div>{error}</div>\n </div>\n )}\n </div>\n )\n}\n","/**\n * Wire contracts between the Claude subscription host routes and the browser\n * settings card. Everything here is public: NO CREDENTIAL EVER CROSSES THIS\n * BOUNDARY, and no shape below has a field a token could live in.\n *\n * ---------------------------------------------------------------------------\n * THE ONE RULE THIS FILE OBEYS, AND WHY IT IS NOT NEGOTIABLE\n * ---------------------------------------------------------------------------\n *\n * **Nothing in this file may resolve a module under 'src/host/'.** Not a value\n * import, not an `import type`, not an `export type … from`.\n *\n * This file is compiled by TWO projects with different worlds:\n *\n * - the host project ('tsconfig.host.json'): Node types, and 'src/host/**' in\n * its include list;\n * - the client project ('tsconfig.client.json'): NO 'types' at all, and\n * 'src/host/**' deliberately absent from its include list.\n *\n * The second one is the constraint. A type-only import is ERASED for emit but\n * still RESOLVED for checking, so a single `import type` of\n * '../host/claude/account-pool.ts' from here pulls that whole subtree —\n * node:path, node:fs, node:http, node:crypto — into the client program. It does\n * not degrade quietly; it fails the build:\n *\n * src/host/claude/account-pool.ts(104,18): error TS2307:\n * Cannot find module 'node:path' or its corresponding type declarations.\n * src/host/claude/account-pool.ts(105,28): error TS6307:\n * File '…/src/host/common/home.ts' is not listed within the file list of\n * project '…/tsconfig.client.json'.\n *\n * That was measured, not assumed: `npx tsc -p tsconfig.client.json` exits 0\n * with this file absent and exits 2 with a single type-only host re-export in\n * it. So the boundary is a property of the build, and this file is on the public\n * side of it.\n *\n * ---------------------------------------------------------------------------\n * THE TWO CONSEQUENCES, STATED PLAINLY RATHER THAN HIDDEN\n * ---------------------------------------------------------------------------\n *\n * 1. {@link ClaudeAccountSummaryDto} is DECLARED here rather than re-exported\n * from 'src/host/claude/account-pool.ts', which is where the pool chunk put\n * it. A re-export is what this file would prefer — and it is what the task\n * asked for — but it cannot compile, for the reason above.\n *\n * The drift that risks is closed from the OTHER side instead:\n * 'src/host/claude/routes.ts' imports BOTH declarations and carries a\n * compile-time assertion that each is assignable to the other. Adding a field\n * to the pool's copy without adding it here is therefore a build failure in\n * `npx tsc -p tsconfig.host.json` — the same protection a re-export would\n * have given, minus the impossible direction.\n *\n * 2. {@link CLAUDE_REASONING_EFFORTS} cannot be DERIVED from the catalog's\n * ladders by an indexed access, for the same reason. It is a literal, and the\n * equivalence between it and the catalog is asserted at the bottom of\n * 'src/host/claude/routes.ts' — against the real `CLAUDE_MODELS` table, in\n * the project that can read it. Adding a level to a catalog ladder without\n * adding it here stops the host typecheck, so the card cannot silently omit a\n * level the wire would accept.\n *\n * Both assertions live in the host project because that is the only project that\n * can see both sides. Neither is documentation: each is a line of TypeScript\n * whose deletion is the only way to make it stop working.\n */\n\nimport type { AccountPoolStatusDto, AccountRotationStrategy, PoolAccountSummaryDto } from './account-pool-contracts.ts'\n\n/**\n * How a model wants its thinking block shaped on the wire.\n *\n * Restated here rather than indexed off `ClaudeModelEntry` — see the module\n * comment. These four are not a quality ordering: 'mid-convo' and 'adaptive' are\n * different wire SHAPES, and the first is checked before every other branch\n * because a managed-effort model needs `block_binding` and `output_config`\n * or it answers with persistent 400s.\n *\n * The equivalence with the catalog's own `thinkingMode` field is asserted in\n * 'src/host/claude/routes.ts'.\n */\nexport type ClaudeThinkingMode = 'mid-convo' | 'adaptive' | 'budget' | 'none'\n\n/**\n * Every thinking level this route can name, in escalating order.\n *\n * The union of the whole shipped catalog rather than one model's ladder: these\n * are WIRE effort values, already collapsed by the upstream reference mapping\n * the frozen catalog transcribes ('minimal' and 'low' both send 'low', so\n * offering both would advertise a distinction the wire cannot make). The card\n * offers them as default-effort choices and narrows the dropdown per model with\n * {@link ClaudeModelOption.reasoningEfforts}.\n *\n * 'off' is deliberately absent, exactly as it is from every ladder in the\n * catalog: turning thinking off is the ABSENCE of a thinking block rather than\n * an effort level, and whether a model permits it is stated separately in\n * {@link ClaudeModelOption.canDisableThinking}.\n *\n * NOT derived from the catalog by an indexed access — the client project cannot\n * read that module. The equivalence is asserted against the real table in\n * 'src/host/claude/routes.ts'; see the module comment.\n */\nexport const CLAUDE_REASONING_EFFORTS = ['low', 'medium', 'high', 'xhigh', 'max'] as const\n\n/** One selectable thinking level. */\nexport type ClaudeReasoningEffort = (typeof CLAUDE_REASONING_EFFORTS)[number]\n\n/**\n * Whether a posted value is one of the levels this route can name.\n *\n * The membership test every settings route in this plugin performs against its\n * own constant, so a level no ladder carries is refused at the wire boundary\n * instead of being persisted and converged later.\n */\nexport function isClaudeReasoningEffort(value: unknown): value is ClaudeReasoningEffort {\n return typeof value === 'string' && (CLAUDE_REASONING_EFFORTS as readonly string[]).includes(value)\n}\n\n/**\n * Prompt-cache TTL the subscription route can request.\n *\n * `null` in the settings means \"follow the official subscription client\", which\n * asks for the one-hour tier while a plan is drawing on included usage.\n */\nexport type ClaudeCacheTtl = '5m' | '1h'\n\n/**\n * Whether a posted value names a tier this route can send.\n *\n * Membership is checked at the wire boundary for the same reason effort levels\n * are: the one-hour tier is a LICENSED capability, so a value that reached the\n * body without the matching beta would be refused by the service.\n */\nexport function isClaudeCacheTtl(value: unknown): value is ClaudeCacheTtl {\n return value === '5m' || value === '1h'\n}\n\n/** One model offered by the Claude subscription route. */\nexport interface ClaudeModelOption {\n id: string\n name: string\n /** Enabled models are the ones DSH offers in the conversation model picker. */\n enabled: boolean\n /** Context window this route assumes when the card saves no override. */\n defaultContextWindow: number\n /** Effective context window: the override when one is saved, else the default. */\n contextWindow: number\n /** Maximum output tokens this route requests when a caller omits one. */\n defaultMaxTokens: number\n /** Thinking levels this model exposes; empty for a model that takes none. */\n reasoningEfforts: string[]\n /**\n * Whether thinking can be turned off for this model.\n *\n * Reported because it is NOT derivable from {@link reasoningEfforts}: a model\n * the catalog maps `off: null` has a full ladder and still refuses to stop\n * thinking, and a card that offered the switch anyway would send a request the\n * wire rejects.\n */\n canDisableThinking: boolean\n /** Which thinking form this model needs; see {@link ClaudeThinkingMode}. */\n thinkingMode: ClaudeThinkingMode\n /** Whether the model accepts image input on this route. */\n supportsImage: boolean\n /** Whether the model accepts a `temperature` at all. */\n supportsTemperature: boolean\n}\n\n/**\n * One quota window, as the usage endpoint or the response headers stated it.\n *\n * The three numeric fields are null TOGETHER: null means \"the source did not\n * say\", which is a different statement from 0. A card that rendered null as 0\n * would show \"nothing used\" for a window nobody measured.\n */\nexport interface ClaudeQuotaWindow {\n /** Wire key: `five_hour`, `seven_day`, `seven_day_sonnet`. */\n id: string\n label: string\n /** Nominal length of the window in minutes, or null when unknown. */\n windowMinutes: number | null\n /** Fraction of the window consumed, 0-1. */\n usedFraction: number | null\n /** The same number as a percent, 0-100. */\n usedPercent: number | null\n /** Percent still available, 0-100. */\n remainingPercent: number | null\n /** ISO 8601 instant the window resets, or null. */\n resetsAt: string | null\n /** Which source these numbers came from, for the card's footnote. */\n source: 'usage' | 'headers'\n}\n\n/** One credit / usage meter the account carries beside its windows. */\nexport interface ClaudeMeter {\n id: string\n label: string\n /** Percent of the allowance consumed, 0-100. Null when the source said nothing. */\n usedPercent: number | null\n /** Percent still available, 0-100. Null when the source said nothing. */\n remainingPercent: number | null\n /** Monthly limit, in the account's own unit, when stated. */\n limit: number | null\n /** Amount consumed, in the same unit, when stated. */\n used: number | null\n /** Whether this meter is switched on for the account. */\n enabled: boolean\n}\n\n/** One point-in-time quota snapshot for the account the card displays. */\nexport interface ClaudeAccountQuota {\n /** Every window the account currently has, shortest first. */\n windows: ClaudeQuotaWindow[]\n /** Pay-as-you-go overage pool, when the account has one. */\n extraUsage: ClaudeMeter | null\n /** Unix milliseconds of the last successful FULL usage read; null if none. */\n fetchedAt: number | null\n /** Unix milliseconds of the most recent update from any source. */\n observedAt: number\n /** Unified rate-limit verdict the headers last reported, when they did. */\n status: string | null\n /** Window the headers last named as representative, when they did. */\n representativeClaim: string | null\n}\n\n/**\n * Account identity as the settings card renders it.\n *\n * There is no bearer field and no token: the identity this line can state from a\n * credential alone is exactly what the exchange reported — an address and a tier\n * — and everything else the card shows about WHO is signed in comes from the\n * account list.\n */\nexport interface ClaudeAccount {\n /** Address the sign-in reported, when it reported one. */\n email: string | null\n /** Subscription tier the exchange reported, verbatim ('max', 'pro', …). */\n subscriptionType: string | null\n}\n\n/**\n * One Claude account as the shared pool card renders it. Never carries a token.\n *\n * DECLARED here rather than re-exported from 'src/host/claude/account-pool.ts';\n * see the module comment for the measured reason. The two are kept identical by\n * the compile-time assertion in 'src/host/claude/routes.ts'.\n */\nexport interface ClaudeAccountSummaryDto extends PoolAccountSummaryDto {\n /** Where the credential came from; a card offers different actions per source. */\n source?: 'managed' | 'claude-code'\n /** Whether this row is a snapshot borrowed from a local Claude Code sign-in. */\n adopted?: boolean\n /** The Claude Code file an adopted snapshot was read from. */\n sourcePath?: string\n /** Subscription tier, from the credential itself. */\n subscriptionType?: string\n}\n\n/** Everything the settings card and the composer badge render. */\nexport interface ClaudeWebStatus extends Partial<AccountPoolStatusDto> {\n enabled?: boolean\n authenticated: boolean\n hasCredentials: boolean\n /** Storage description for this line's encrypted credential store. */\n storagePath: string\n /** Whether this plugin currently owns the provider route. */\n serving: boolean\n /** Diagnostic when another adapter family owns the provider route. */\n conflict: string | null\n /**\n * Whether a local Claude Code sign-in exists to offer for adoption.\n *\n * Answered by a stat and NOT by a read (see 'src/host/claude/adopt.ts'), so\n * the card can offer the import before anything has been read from the file.\n */\n claudeCodeSignInAvailable: boolean\n /** Paths the adoption reader consulted, whether or not each existed. */\n claudeCodePaths: string[]\n /** Account the displayed credential belongs to. */\n account: ClaudeAccount | null\n quota: ClaudeAccountQuota | null\n lastFetchedAt: number | null\n /**\n * Whether a quota refresh is running behind this answer.\n *\n * The card renders the snapshot it already had instead of waiting on the\n * upstream request; when this is true the client asks again shortly so the\n * refreshed snapshot reaches the UI.\n */\n quotaRefreshing?: boolean\n /** Why the last quota read failed, when it did. Reported BESIDE the snapshot. */\n quotaError?: string | null\n models: ClaudeModelOption[]\n contextWindowOverrides: Record<string, number>\n defaultReasoningEffort: ClaudeReasoningEffort | null\n /** Prompt-cache tier; `null` means \"follow the official subscription default\". */\n cacheTtl: ClaudeCacheTtl | null\n /** Account selected for catalog, quota and all requests; null means automatic. */\n selectedAccountId: string | null\n /** Signed-in accounts; empty or absent when no pool is installed. */\n accounts?: ClaudeAccountSummaryDto[]\n /** Account the next request would use. */\n activeAccountId?: string\n rotationStrategy?: AccountRotationStrategy\n}\n\n/** Patch accepted by the models/settings route. */\nexport interface ClaudeSettingsUpdateDto {\n enabled?: boolean\n enabledModelIds?: string[]\n /** A number sets an override for that model; `null` restores the default. */\n contextWindowOverrides?: Record<string, number | null>\n defaultReasoningEffort?: ClaudeReasoningEffort | null\n /** `null` restores the subscription default. */\n cacheTtl?: ClaudeCacheTtl | null\n selectedAccountId?: string | null\n}\n\n/** One account-pool action the card can post. */\nexport type ClaudeAccountAction =\n | 'set-primary'\n | 'set-alias'\n | 'delete'\n | 'clear-cooldown'\n | 'clear-auth-failed'\n | 'relogin'\n | 'strategy'\n\n/** Body accepted by the accounts route. */\nexport interface ClaudeAccountActionDto {\n action: ClaudeAccountAction\n accountId?: string\n alias?: string\n strategy?: AccountRotationStrategy\n}\n\n/**\n * Result of an explicit connection test.\n *\n * A failure is a VALUE rather than a thrown error, because the card's whole job\n * here is to render the reason: a probe that was refused is a fact about the\n * credential, not a failed request.\n */\nexport interface ClaudeConnectionDto {\n connected: boolean\n /** Model the probe asked for. */\n model: string\n /** Round-trip time of the probe request, in milliseconds. */\n latencyMs: number\n /** HTTP status the probe received; 0 when no response arrived at all. */\n status: number\n /** Why the probe did not connect, when it did not. */\n error: string | null\n /** Whether repeating the same probe could succeed. */\n retryable: boolean\n /** `stop_reason` of the one-token answer, when one arrived. */\n stopReason: string | null\n checkedAt: number\n}\n\n/**\n * Live state of the sign-in flow the card polls.\n *\n * This restates 'src/host/claude/oauth.ts''s `LoginFlowStatus` field for field,\n * and the restatement is deliberate rather than lazy: that object is serialized\n * straight into the HTTP response, and its own comment records that no secret\n * has a field to live in. Renaming a field here cannot leak anything — the host\n * serializes its own object — but it CAN make the card read a field the host\n * never sends, so the two are kept in step by eye and by the tests that drive\n * the real flow.\n */\nexport interface ClaudeLoginFlowDto {\n status: 'idle' | 'pending' | 'exchanging' | 'complete' | 'error'\n /** Correlates a status reading with the flow the user started. */\n flowId?: string\n /** Not a secret: it is the value that goes INTO the browser. */\n authUrl?: string\n mode?: 'manual' | 'loopback'\n /** Which redirect URI is armed, for the card to display. */\n redirectUri?: string\n hint?: string\n error?: string\n /** Why a loopback attempt degraded to manual. */\n fallbackReason?: string\n createdAt?: number\n completedAt?: number\n}\n","import { accountPoolEn, accountPoolZh } from '../common/account-pool-labels.ts'\n\n/**\n * Locale namespace of the Claude subscription tab.\n *\n * Its own namespace rather than the hub's, so a missing string surfaces as this\n * dictionary's key rather than as a wrong sentence borrowed from another\n * provider — the same reason every sibling line has one.\n */\nexport const NS_CLAUDE = 'dsh-claude'\n\nexport const zh = {\n // The account-management card is shared with every other provider tab.\n ...accountPoolZh,\n title: 'Claude(订阅)',\n pageDesc: '登录 Claude Pro/Max 订阅,管理模型、思考档位、上下文窗口与额度。',\n\n // --- Account card ---\n account: '账号',\n signedIn: '已登录',\n signedOut: '未登录',\n email: '邮箱',\n plan: '套餐',\n planUnknown: '—',\n subscriptionType: '订阅类型',\n source: '来源',\n sourceManaged: '本插件登录',\n sourceClaudeCode: '本机 Claude Code',\n adoptedBadge: '导入的快照',\n\n // --- Sign-in flow ---\n signIn: '登录 Claude 账号',\n signInSection: '登录授权',\n signInAgain: '重新登录',\n signingIn: '正在发起登录...',\n cancelSignIn: '取消登录',\n openAuthorizeUrl: '打开授权页面',\n authorizeUrl: '授权链接',\n redirectUri: '回调地址',\n loginModeManual: '当前是手动模式:浏览器回调不可用,授权完成后把页面上的 code 粘贴到下方输入框。',\n loginModeLoopback: '当前是本地回环模式:浏览器授权完成后会自动回到本机回调地址。',\n loginFallbackReason: '本地回环模式不可用,已降级为手动模式:{detail}',\n loginWaiting: '等待浏览器中的授权完成...',\n loginExchanging: '正在交换令牌...',\n loginComplete: '登录完成',\n loginFailed: '登录失败',\n manualPasteSection: '手动粘贴授权码',\n manualPasteHint: '把浏览器地址栏里的 code(或整段回调 URL)粘贴到这里完成登录。手动模式下没有浏览器回调,这里是唯一的入口。',\n manualPastePlaceholder: 'code#state 或完整的回调 URL',\n manualPasteSubmit: '提交授权码',\n manualPasteSubmitting: '提交中...',\n\n // --- Adoption of the local Claude Code sign-in ---\n importClaudeCode: '导入本机 Claude Code 登录态',\n importing: '导入中...',\n stopImporting: '停止导入',\n // Only the button's own labels live here now. The prose that used to sit under\n // the pool — what the import does, whether one was found, where it looked — was\n // removed: the button already names the action, and a click with no sign-in\n // present returns the host's own sentence in the card's error strip, so the\n // three paragraphs described a state the control itself already reports.\n\n // --- Connection ---\n connection: '连接',\n testConnection: '测试连接',\n testingConnection: '测试中...',\n testSuccess: '连接正常',\n testLatency: '往返 {ms} ms',\n testFailed: '连接失败:{detail}',\n testRetryable: '可重试',\n testNotRetryable: '不可重试',\n routeOwned: '模型路由由本插件提供',\n routeConflict: '模型路由已被其他 Provider 占用:{detail}。请在 DSH 设置中移除重复的 Provider 配置后重试。',\n\n // --- Models ---\n modelsSection: '模型',\n modelsHint: '勾选后模型才会出现在对话页的模型选择列表中。',\n refreshCatalog: '刷新模型目录',\n refreshingCatalog: '刷新中...',\n selectAll: '全选',\n unselectAll: '全不选',\n capImage: '图片',\n capNoImage: '仅文本',\n capThinkingOff: '可关闭思考',\n thinkingModeMidConvo: '多轮思考',\n thinkingModeAdaptive: '自适应思考',\n thinkingModeBudget: '预算思考',\n thinkingModeNone: '无思考',\n\n // --- Thinking ---\n enhanced: '思考设置',\n defaultReasoningEffort: '默认思考档位',\n defaultReasoningEffortHint: '下拉列出的是目录中出现过的全部档位(含 xhigh);每个模型真正支持的档位见下方列表,Host 按模型自身的阶梯发送。',\n defaultEffortAuto: '使用模型默认值',\n cacheTtl: '提示缓存时长',\n cacheTtlHint: 'Anthropic 提供 5 分钟与 1 小时两档。订阅用户在套餐额度内,官方 Claude Code 对主对话默认使用 1 小时;超出额度改按用量计费后官方会降回 5 分钟。1 小时写入更贵,短会话不划算。',\n cacheTtlSubscription: '跟随官方(订阅默认 1 小时)',\n cacheTtl1h: '1 小时',\n cacheTtl5m: '5 分钟',\n effortLow: '低 (low)',\n effortMedium: '中 (medium)',\n effortHigh: '高 (high)',\n effortXHigh: '极高 (xhigh)',\n effortMax: '最高 (max)',\n modelLadders: '各模型支持的档位',\n modelLadderNone: '该模型不接受思考档位',\n\n // --- Context windows ---\n contextWindowSection: '模型上下文窗口',\n contextWindowHint: '默认取模型目录的上下文长度,保存过的覆盖值优先。恢复默认会让 Host 删掉这条覆盖值,重新回到目录值。',\n contextWindowReset: '恢复默认',\n contextWindowResetAll: '全部恢复默认',\n contextWindowResetAllConfirm: '确定把已改过的模型上下文窗口全部恢复为默认值吗?',\n contextWindowNoneEnabled: '还没有勾选任何模型。在上方勾选后,这里会出现该模型的上下文窗口设置。',\n contextWindowInvalid: '上下文长度无效:{value}',\n save: '保存',\n saving: '保存中...',\n tokens: 'tokens',\n\n // --- Quota ---\n quotaSection: '用量与额度',\n quotaDesc: '数据来自 Claude 用量接口与响应头;页面可见时最多每 60 秒刷新一次。utilization 是「已用百分比」,所以 0% 已用是正常的空用量状态。',\n refreshQuota: '刷新用量',\n refreshingQuota: '刷新中...',\n quotaRefreshing: 'Host 正在后台刷新额度,稍后会自动更新。',\n quotaEmpty: '暂无配额数据,点击「刷新用量」重试。',\n quotaSignedOut: '未登录,无法读取用量。',\n quotaUnknown: '—',\n quotaUnknownHint: 'Host 没有给出这个窗口的数值,这里不显示为 0。',\n usedLabel: '已用',\n remainingLabel: '剩余',\n left: '可用',\n resetAt: '重置:{time}',\n resetUnknown: '重置时间未知',\n updatedAt: '更新时间:{time}',\n observedAt: '最近观察:{time}',\n quotaError: '额度读取失败',\n extraUsage: '额外用量',\n extraUsageEnabled: '已开启',\n extraUsageDisabled: '未开启',\n extraUsageLimit: '月度上限',\n sourceUsage: '来源:用量接口',\n sourceHeaders: '来源:响应头',\n quotaStatus: '限流状态',\n quotaRepresentative: '代表性窗口',\n\n loading: '加载中...',\n now: '即将重置',\n copy: '复制',\n copied: '已复制',\n} as const\n\nexport const en: Record<keyof typeof zh, string> = {\n ...accountPoolEn,\n title: 'Claude (subscription)',\n pageDesc: 'Sign in to a Claude Pro/Max subscription and manage models, thinking levels, context windows and quota.',\n\n account: 'Account',\n signedIn: 'Signed in',\n signedOut: 'Not signed in',\n email: 'Email',\n plan: 'Plan',\n planUnknown: '—',\n subscriptionType: 'Subscription',\n source: 'Source',\n sourceManaged: 'Signed in here',\n sourceClaudeCode: 'Local Claude Code',\n adoptedBadge: 'Imported snapshot',\n signIn: 'Sign in to Claude',\n signInSection: 'Sign-in',\n signInAgain: 'Sign in again',\n signingIn: 'Starting the sign-in...',\n cancelSignIn: 'Cancel',\n openAuthorizeUrl: 'Open the authorization page',\n authorizeUrl: 'Authorization URL',\n redirectUri: 'Redirect URI',\n loginModeManual: 'Manual mode: there is no browser callback, so paste the code shown after authorizing into the box below.',\n loginModeLoopback: 'Loopback mode: the browser returns to the local callback automatically after you authorize.',\n loginFallbackReason: 'Loopback was unavailable and the flow degraded to manual: {detail}',\n loginWaiting: 'Waiting for the browser to finish authorizing...',\n loginExchanging: 'Exchanging the token...',\n loginComplete: 'Signed in',\n loginFailed: 'Sign-in failed',\n manualPasteSection: 'Paste the authorization code',\n manualPasteHint: 'Paste the code from the browser address bar (or the whole callback URL) here to finish signing in. In manual mode there is no browser callback, so this box is the only way through.',\n manualPastePlaceholder: 'code#state or the full callback URL',\n manualPasteSubmit: 'Submit code',\n manualPasteSubmitting: 'Submitting...',\n\n importClaudeCode: 'Import the local Claude Code sign-in',\n importing: 'Importing...',\n stopImporting: 'Stop importing',\n // Only the button's own labels live here now. The prose that used to sit under\n // the pool — what the import does, whether one was found, where it looked — was\n // removed: the button already names the action, and a click with no sign-in\n // present returns the host's own sentence in the card's error strip, so the\n // three paragraphs described a state the control itself already reports.\n\n connection: 'Connection',\n testConnection: 'Test connection',\n testingConnection: 'Testing...',\n testSuccess: 'Connection OK',\n testLatency: 'round trip {ms} ms',\n testFailed: 'Connection failed: {detail}',\n testRetryable: 'retryable',\n testNotRetryable: 'not retryable',\n routeOwned: 'This plugin serves the model route',\n routeConflict: 'Another provider already owns the model route: {detail}. Remove the duplicate provider configuration in DSH settings and retry.',\n\n modelsSection: 'Models',\n modelsHint: 'Checked models appear in the DSH conversation model list.',\n refreshCatalog: 'Refresh catalog',\n refreshingCatalog: 'Refreshing...',\n selectAll: 'Select all',\n unselectAll: 'Deselect all',\n capImage: 'Images',\n capNoImage: 'Text only',\n capThinkingOff: 'Thinking can be turned off',\n thinkingModeMidConvo: 'Mid-conversation thinking',\n thinkingModeAdaptive: 'Adaptive thinking',\n thinkingModeBudget: 'Budgeted thinking',\n thinkingModeNone: 'No thinking',\n\n enhanced: 'Thinking',\n defaultReasoningEffort: 'Default thinking level',\n defaultReasoningEffortHint: 'The list is every level the catalog names (xhigh included); the per-model ladder is listed below, and the Host sends what that model itself accepts.',\n cacheTtl: 'Prompt cache duration',\n cacheTtlHint: 'Anthropic offers 5-minute and 1-hour tiers. While a subscription is drawing on included plan usage, the official Claude Code uses the hour for the main conversation; once the plan is exhausted and requests bill against usage credits, it drops back to five minutes. A 1-hour write costs more, so it does not pay off for short sessions.',\n cacheTtlSubscription: 'Follow the official (subscription default 1h)',\n cacheTtl1h: '1 hour',\n cacheTtl5m: '5 minutes',\n defaultEffortAuto: 'Use the model default',\n effortLow: 'Low',\n effortMedium: 'Medium',\n effortHigh: 'High',\n effortXHigh: 'X-High',\n effortMax: 'Max',\n modelLadders: 'Per-model levels',\n modelLadderNone: 'This model accepts no thinking level',\n\n contextWindowSection: 'Model context window',\n contextWindowHint: 'Defaults to the catalog context length; a saved override wins. Restoring the default makes the Host delete that override and fall back to the catalog value.',\n contextWindowReset: 'Restore default',\n contextWindowResetAll: 'Restore all defaults',\n contextWindowResetAllConfirm: 'Restore every changed model context window to its default?',\n contextWindowNoneEnabled: 'No model is checked yet. Check one above and its context window setting appears here.',\n contextWindowInvalid: 'Invalid context capacity: {value}',\n save: 'Save',\n saving: 'Saving...',\n tokens: 'tokens',\n\n quotaSection: 'Usage & quota',\n quotaDesc: 'Read from the Claude usage endpoint and response headers; refreshes at most once every 60 seconds while visible. utilization is PERCENT USED, so 0% used is the normal empty state.',\n refreshQuota: 'Refresh quota',\n refreshingQuota: 'Refreshing...',\n quotaRefreshing: 'The Host is refreshing the quota in the background; the numbers update shortly.',\n quotaEmpty: 'No quota data yet — use \"Refresh quota\" to retry.',\n quotaSignedOut: 'Not signed in, so usage cannot be read.',\n quotaUnknown: '—',\n quotaUnknownHint: 'The Host did not state a number for this window, so none is shown instead of a zero.',\n usedLabel: 'Used',\n remainingLabel: 'Remaining',\n left: 'left',\n resetAt: 'Reset: {time}',\n resetUnknown: 'reset time unknown',\n updatedAt: 'Updated at: {time}',\n observedAt: 'Last observed: {time}',\n quotaError: 'Quota read failed',\n extraUsage: 'Extra usage',\n extraUsageEnabled: 'enabled',\n extraUsageDisabled: 'disabled',\n extraUsageLimit: 'Monthly limit',\n sourceUsage: 'Source: usage endpoint',\n sourceHeaders: 'Source: response headers',\n quotaStatus: 'Rate-limit status',\n quotaRepresentative: 'Representative window',\n\n loading: 'Loading...',\n now: 'now',\n copy: 'Copy',\n copied: 'Copied',\n} as const\n\nexport const dictionaries = {\n zh,\n 'zh-CN': zh,\n en,\n 'en-US': en,\n}\n\nexport type ClaudeLocaleKey = keyof typeof zh\n","/**\n * The Claude card's state, effects and actions.\n *\n * Split out of 'ClaudeSection.tsx' so that file is markup and this one is\n * behaviour: what the card tracks, what it derives from a status answer, and\n * every request a control can make. The view reads one named shape — see\n * `ClaudeSectionView` — so the contract between the two is visible here rather\n * than inferred from a thousand lines of JSX.\n */\nimport { useCallback, useEffect, useRef, useState } from 'react'\nimport type { AccountRotationStrategy } from '../../shared/account-pool-contracts.ts'\nimport type {\n ClaudeAccountQuota,\n ClaudeAccountSummaryDto,\n ClaudeCacheTtl,\n ClaudeConnectionDto,\n ClaudeLoginFlowDto,\n ClaudeModelOption,\n ClaudeQuotaWindow,\n ClaudeReasoningEffort,\n ClaudeWebStatus,\n} from '../../shared/claude-contracts.ts'\nimport { contextDraftsFor } from '../common/ContextWindowEditor.tsx'\nimport { formatCapacity, parsePositiveCapacity } from '../common/format.ts'\nimport { createLineApi } from '../common/line-api.ts'\nimport { createQuotaFollowUp, type QuotaFollowUp } from '../common/quota-follow-up.ts'\nimport { zh } from './locales.ts'\n\nconst API = '/claude/api'\nconst api = createLineApi(API, 'Claude')\n\n/**\n * The poll cadence of a pending sign-in.\n *\n * There is NO SSE channel in this plugin — every sibling line polls\n * 'login/status' on a timer while the user is in the browser, and this one does\n * the same so a stalled flow is visible rather than silent.\n */\nconst LOGIN_POLL_MS = 2000\n\n/** The seats the settings hub hands the card; both optional, so a bare render works. */\nexport interface ClaudeSectionProps {\n onModelChange?: () => void\n loadModelDirectory?: () => void\n}\n\n/**\n * Everything the card's view consumes, grouped by kind.\n *\n * Returned as one named shape instead of one status blob: a reader can see at a\n * glance what the hook tracks, what it computes from a status answer, and what\n * the view is allowed to ask it to do.\n */\nexport interface ClaudeSectionView {\n /** Values that change as the card runs. */\n state: {\n /** Last status answer; null until the first read lands. */\n status: ClaudeWebStatus | null\n /** True until the first status read settles, whatever its outcome. */\n loading: boolean\n /** Id of the action in flight, or null; every disabled control reads it. */\n busy: string | null\n /** The failure the card's error strip shows. */\n error: string | null\n /** The sign-in flow being polled, when one is running. */\n flow: ClaudeLoginFlowDto | null\n /** Result of the last explicit connection test. */\n connection: ClaudeConnectionDto | null\n /** What the user has typed into the manual-paste box. */\n pasteValue: string\n /** One free-text capacity draft per model, keyed by model id. */\n contextDrafts: Record<string, string>\n /** Model id whose context-window save or restore is in flight. */\n savingModel: string | null\n }\n /** Facts read straight off the current status answer. */\n derived: {\n /** Every account row the shared pool card lists. */\n accounts: ClaudeAccountSummaryDto[]\n /** Whether any row is a snapshot of a sign-in this plugin does not own. */\n hasAdopted: boolean\n /** Models the context-window editor offers: the enabled ones only. */\n contextModels: ClaudeModelOption[]\n /** How many stored overrides exist, whether or not a row still shows them. */\n overrideCount: number\n /** The displayed account's quota snapshot, when the host has one. */\n quota: ClaudeAccountQuota | null | undefined\n /** Windows of that snapshot, shortest first. */\n windows: ClaudeQuotaWindow[]\n /**\n * The line's dictionary, handed to the shared pool card as one object.\n *\n * The hook already owns it for its own sentences, so the view takes the same\n * object from here rather than reaching for a second import.\n */\n poolLabels: typeof zh\n }\n /** Everything the view can trigger. */\n actions: {\n /** Start a sign-in; opens the authorize page when the flow carries one. */\n login(): Promise<void>\n cancelLogin(): Promise<void>\n /** Finish a manual-mode sign-in with the pasted code. */\n submitPaste(): Promise<void>\n /** Add the local Claude Code sign-in as a snapshot. */\n adopt(): Promise<void>\n /** Forget every imported snapshot, or one of them. */\n stopImporting(accountId?: string): Promise<void>\n /** One account-level action on the shared pool card. */\n accountAction(\n action: 'set-primary' | 'delete' | 'clear-cooldown',\n accountId: string,\n ): Promise<void>\n setStrategy(strategy: AccountRotationStrategy): Promise<void>\n /** Re-authorize ONE account; the returned flow starts the polling above. */\n relogin(accountId: string): void\n refreshQuota(): Promise<void>\n refreshCatalog(): Promise<void>\n testConnection(): Promise<void>\n toggleModel(modelId: string, checked: boolean): void\n setAllModels(selectAll: boolean): void\n updateEffort(effort: ClaudeReasoningEffort | null): Promise<void>\n updateCacheTtl(ttl: ClaudeCacheTtl | null): Promise<void>\n saveContextWindow(modelId: string): Promise<void>\n resetContextWindow(modelId: string): Promise<void>\n resetAllContextWindows(): Promise<void>\n /** Edit one capacity draft mid-typing; the editor never parses it. */\n updateContextDraft(modelId: string, draft: string): void\n /** Edit the manual-paste box. */\n setPasteValue(value: string): void\n }\n}\n\nexport function useClaudeSection({ onModelChange, loadModelDirectory }: ClaudeSectionProps): ClaudeSectionView {\n const [status, setStatus] = useState<ClaudeWebStatus | null>(null)\n const [loading, setLoading] = useState(true)\n const [busy, setBusy] = useState<string | null>(null)\n const [error, setError] = useState<string | null>(null)\n const [flow, setFlow] = useState<ClaudeLoginFlowDto | null>(null)\n const [pasteValue, setPasteValue] = useState('')\n const [contextDrafts, setContextDrafts] = useState<Record<string, string>>({})\n const [savingModel, setSavingModel] = useState<string | null>(null)\n const [connection, setConnection] = useState<ClaudeConnectionDto | null>(null)\n\n /** Follow-up poll owed while the host refreshes the quota behind an answer. */\n const quotaFollowUp = useRef<QuotaFollowUp | null>(null)\n\n const t = zh\n\n const notifyChange = useCallback(() => {\n onModelChange?.()\n loadModelDirectory?.()\n }, [onModelChange, loadModelDirectory])\n\n /** Report one failure in the card's error strip. */\n const reportError = useCallback((err: unknown): void => {\n setError(err instanceof Error ? err.message : String(err))\n }, [])\n\n const loadStatus = useCallback(async (quiet = false) => {\n if (!quiet) setError(null)\n try {\n const data = await api.request<ClaudeWebStatus>('/status')\n setStatus(data)\n setContextDrafts(contextDraftsFor(data))\n // An answer that refreshed the quota behind itself is followed up shortly,\n // so the fresh numbers land without waiting for the next 60 s poll.\n quotaFollowUp.current ??= createQuotaFollowUp()\n quotaFollowUp.current.observe(data.quotaRefreshing === true, () => { void loadStatus(true) })\n } catch (err) {\n if (!quiet) reportError(err)\n } finally {\n setLoading(false)\n }\n }, [reportError])\n\n useEffect(() => {\n void loadStatus()\n const refreshWhenVisible = () => {\n if (document.visibilityState === 'visible') void loadStatus(true)\n }\n document.addEventListener('visibilitychange', refreshWhenVisible)\n const timer = window.setInterval(refreshWhenVisible, 60_000)\n return () => {\n window.clearInterval(timer)\n document.removeEventListener('visibilitychange', refreshWhenVisible)\n quotaFollowUp.current?.cancel()\n }\n }, [loadStatus])\n\n // The sign-in flow runs on the host and is polled here, because authorization\n // happens in a browser this card does not control. Every entry point into the\n // flow — the account card's sign-in button, the two-option login action, and a\n // per-account re-login — ends in the same 'pending' state, so one effect\n // drives all of them.\n useEffect(() => {\n // 'exchanging' too: the host reports it while the code is redeemed, and a\n // poll that lands in that window used to stop polling for good - the card\n // then sat on \"exchanging\" while the host had long finished signing in.\n if (flow?.status !== 'pending' && flow?.status !== 'exchanging') return\n const timer = window.setInterval(() => {\n void (async () => {\n try {\n const poll = await api.request<ClaudeLoginFlowDto>('/login/status')\n setFlow(poll)\n if (poll.status === 'complete') {\n setPasteValue('')\n await loadStatus()\n notifyChange()\n } else if (poll.status === 'error') {\n setError(poll.error || t.loginFailed)\n }\n } catch {\n // A failed poll is transient; the next tick retries.\n }\n })()\n }, LOGIN_POLL_MS)\n return () => window.clearInterval(timer)\n }, [flow?.status, loadStatus, notifyChange, t.loginFailed])\n\n const login = async () => {\n try {\n setBusy('login')\n setError(null)\n setPasteValue('')\n const next = await api.request<ClaudeLoginFlowDto>('/login', {\n method: 'POST',\n body: JSON.stringify({}),\n })\n setFlow(next)\n // The card is the ONLY place the page is opened; the host no longer opens\n // it too (that showed two identical login pages). The desktop shell hands\n // window.open to the system browser, and a blocked popup changes nothing:\n // the card renders the link below.\n if (next.authUrl) window.open(next.authUrl, '_blank', 'noopener,noreferrer')\n } catch (err) {\n reportError(err)\n } finally {\n setBusy(null)\n }\n }\n\n const cancelLogin = async () => {\n try {\n const next = await api.request<ClaudeLoginFlowDto>('/login/cancel', { method: 'POST' })\n setFlow(next)\n } catch (err) {\n reportError(err)\n }\n }\n\n /** Finish a manual-mode sign-in with the code the user pasted. */\n const submitPaste = async () => {\n if (pasteValue.trim() === '') return\n try {\n setBusy('login-input')\n setError(null)\n // The route answers with the refreshed STATUS, not with the flow: a\n // successful exchange stores the credential, so the account card, the\n // models and the quota are all stale by the time it returns.\n const updated = await api.request<ClaudeWebStatus>('/login/input', {\n method: 'POST',\n body: JSON.stringify({ input: pasteValue }),\n })\n setStatus(updated)\n setContextDrafts(contextDraftsFor(updated))\n setFlow({ status: 'idle' })\n setPasteValue('')\n notifyChange()\n } catch (err) {\n reportError(err)\n } finally {\n setBusy(null)\n }\n }\n\n /**\n * Add the local Claude Code sign-in as a snapshot.\n *\n * The host reads the file; the card only asks for the import.\n */\n const adopt = async () => {\n try {\n setBusy('adopt')\n setError(null)\n const updated = await api.request<ClaudeWebStatus>('/adopt', { method: 'POST' })\n setStatus(updated)\n setContextDrafts(contextDraftsFor(updated))\n notifyChange()\n } catch (err) {\n reportError(err)\n } finally {\n setBusy(null)\n }\n }\n\n /** Forget every imported snapshot, or one of them. Claude Code's file is untouched. */\n const stopImporting = async (accountId?: string) => {\n try {\n setBusy(accountId === undefined ? 'adopt-disable' : `adopt-disable-${accountId}`)\n setError(null)\n const updated = await api.request<ClaudeWebStatus>('/adopt/disable', {\n method: 'POST',\n body: JSON.stringify(accountId === undefined ? {} : { accountId }),\n })\n setStatus(updated)\n notifyChange()\n } catch (err) {\n reportError(err)\n } finally {\n setBusy(null)\n }\n }\n\n /** One account-level action on the shared pool card. */\n const accountAction = async (\n action: 'set-primary' | 'delete' | 'clear-cooldown',\n accountId: string,\n ) => {\n try {\n setBusy(`${action}-${accountId}`)\n setError(null)\n const updated = await api.request<ClaudeWebStatus>('/accounts', {\n method: 'POST',\n body: JSON.stringify({ action, accountId }),\n })\n setStatus(updated)\n notifyChange()\n } catch (err) {\n reportError(err)\n } finally {\n setBusy(null)\n }\n }\n\n const setStrategy = async (strategy: AccountRotationStrategy) => {\n try {\n setBusy('strategy')\n setError(null)\n const updated = await api.request<ClaudeWebStatus>('/accounts', {\n method: 'POST',\n body: JSON.stringify({ action: 'strategy', strategy }),\n })\n setStatus(updated)\n } catch (err) {\n reportError(err)\n } finally {\n setBusy(null)\n }\n }\n\n /**\n * Re-authorize ONE account.\n *\n * Nothing is deleted: the sign-in route is addressed at this account id, so\n * the new credential lands in that row and keeps its alias and place in the\n * rotation. The flow DTO it returns is what starts the polling above.\n */\n const relogin = (accountId: string): void => {\n void (async () => {\n try {\n setBusy(`relogin-${accountId}`)\n setError(null)\n setPasteValue('')\n const next = await api.request<ClaudeLoginFlowDto>('/login', {\n method: 'POST',\n body: JSON.stringify({ accountId }),\n })\n setFlow(next)\n if (next.authUrl) window.open(next.authUrl, '_blank', 'noopener,noreferrer')\n } catch (err) {\n reportError(err)\n } finally {\n setBusy(null)\n }\n })()\n }\n\n const refreshQuota = async () => {\n try {\n setBusy('quota')\n setError(null)\n // A quota FAILURE is not a failed request: it arrives as `quotaError` on a\n // 200, so the card keeps rendering the account beside the reason.\n const updated = await api.request<ClaudeWebStatus>('/quota', { method: 'POST' })\n setStatus(updated)\n } catch (err) {\n reportError(err)\n // Re-read so the card still shows the account and any recorded reason.\n await loadStatus(true)\n } finally {\n setBusy(null)\n }\n }\n\n const refreshCatalog = async () => {\n try {\n setBusy('catalog')\n setError(null)\n const updated = await api.request<ClaudeWebStatus>('/catalog/refresh', { method: 'POST' })\n setStatus(updated)\n setContextDrafts(contextDraftsFor(updated))\n notifyChange()\n } catch (err) {\n reportError(err)\n } finally {\n setBusy(null)\n }\n }\n\n const testConnection = async () => {\n try {\n setBusy('connection')\n setError(null)\n setConnection(null)\n // A refusal is a VALUE here: the route answers 200 with `connected: false`\n // and a reason, because explaining the refusal is the whole job.\n const result = await api.request<ClaudeConnectionDto>('/connection/test', { method: 'POST' })\n setConnection(result)\n // The probe is a real request against the account, so the quota shown is\n // now current.\n await loadStatus(true)\n } catch (err) {\n reportError(err)\n } finally {\n setBusy(null)\n }\n }\n\n const applyEnabled = async (enabledModelIds: string[]) => {\n try {\n const updated = await api.request<ClaudeWebStatus>('/models', {\n method: 'POST',\n body: JSON.stringify({ enabledModelIds }),\n })\n setStatus(updated)\n // A model that was just checked has no draft yet; the context window\n // section only renders enabled models.\n setContextDrafts(contextDraftsFor(updated))\n notifyChange()\n } catch (err) {\n reportError(err)\n }\n }\n\n const toggleModel = (modelId: string, checked: boolean) => {\n if (!status) return\n const current = status.models.filter((model) => model.enabled).map((model) => model.id)\n const next = checked ? [...new Set([...current, modelId])] : current.filter((id) => id !== modelId)\n void applyEnabled(next)\n }\n\n const setAllModels = (selectAll: boolean) => {\n if (!status || status.models.length === 0) return\n void applyEnabled(selectAll ? status.models.map((model) => model.id) : [])\n }\n\n const updateEffort = async (effort: ClaudeReasoningEffort | null) => {\n try {\n const updated = await api.request<ClaudeWebStatus>('/settings', {\n method: 'POST',\n body: JSON.stringify({ defaultReasoningEffort: effort }),\n })\n setStatus(updated)\n notifyChange()\n } catch (err) {\n reportError(err)\n }\n }\n\n const updateCacheTtl = async (ttl: ClaudeCacheTtl | null) => {\n try {\n const updated = await api.request<ClaudeWebStatus>('/settings', {\n method: 'POST',\n body: JSON.stringify({ cacheTtl: ttl }),\n })\n setStatus(updated)\n notifyChange()\n } catch (err) {\n reportError(err)\n }\n }\n\n const saveContextWindow = async (modelId: string) => {\n const raw = contextDrafts[modelId] || ''\n const parsed = parsePositiveCapacity(raw)\n if (parsed === null) {\n setError(t.contextWindowInvalid.replace('{value}', raw))\n return\n }\n try {\n setSavingModel(modelId)\n setError(null)\n const updated = await api.request<ClaudeWebStatus>('/settings', {\n method: 'POST',\n body: JSON.stringify({ contextWindowOverrides: { [modelId]: parsed } }),\n })\n setStatus(updated)\n setContextDrafts((prev) => ({ ...prev, [modelId]: formatCapacity(parsed) }))\n notifyChange()\n } catch (err) {\n reportError(err)\n } finally {\n setSavingModel(null)\n }\n }\n\n /**\n * Clear one override.\n *\n * `null` is the card's \"restore the catalog default\" and the host preserves\n * it through its own normalization, which is what makes this a delete rather\n * than a save of the default value.\n */\n const resetContextWindow = async (modelId: string) => {\n try {\n setSavingModel(modelId)\n setError(null)\n const updated = await api.request<ClaudeWebStatus>('/settings', {\n method: 'POST',\n body: JSON.stringify({ contextWindowOverrides: { [modelId]: null } }),\n })\n setStatus(updated)\n setContextDrafts((prev) => {\n const model = updated.models.find((candidate) => candidate.id === modelId)\n return model === undefined ? prev : { ...prev, [modelId]: formatCapacity(model.defaultContextWindow) }\n })\n notifyChange()\n } catch (err) {\n reportError(err)\n } finally {\n setSavingModel(null)\n }\n }\n\n /** Clear every stored override, including models the picker no longer shows. */\n const resetAllContextWindows = async () => {\n const models = Object.keys(status?.contextWindowOverrides ?? {})\n if (models.length === 0) return\n if (typeof window !== 'undefined' && !window.confirm(t.contextWindowResetAllConfirm)) return\n try {\n setBusy('context')\n setError(null)\n const updated = await api.request<ClaudeWebStatus>('/settings', {\n method: 'POST',\n body: JSON.stringify({ contextWindowOverrides: Object.fromEntries(models.map((model) => [model, null])) }),\n })\n setStatus(updated)\n setContextDrafts(contextDraftsFor(updated))\n notifyChange()\n } catch (err) {\n reportError(err)\n } finally {\n setBusy(null)\n }\n }\n\n const updateContextDraft = (modelId: string, draft: string): void => {\n setContextDrafts((prev) => ({ ...prev, [modelId]: draft }))\n }\n\n const accounts = (status?.accounts ?? []) as ClaudeAccountSummaryDto[]\n const hasAdopted = accounts.some((account) => account.adopted === true || account.removable === false)\n const contextModels = status?.models.filter((model) => model.enabled) ?? []\n const overrideCount = Object.keys(status?.contextWindowOverrides ?? {}).length\n const quota = status?.quota\n const windows: ClaudeQuotaWindow[] = quota?.windows ?? []\n\n return {\n state: {\n status,\n loading,\n busy,\n error,\n flow,\n connection,\n pasteValue,\n contextDrafts,\n savingModel,\n },\n derived: {\n accounts,\n hasAdopted,\n contextModels,\n overrideCount,\n quota,\n windows,\n poolLabels: t,\n },\n actions: {\n login,\n cancelLogin,\n submitPaste,\n adopt,\n stopImporting,\n accountAction,\n setStrategy,\n relogin,\n refreshQuota,\n refreshCatalog,\n testConnection,\n toggleModel,\n setAllModels,\n updateEffort,\n updateCacheTtl,\n saveContextWindow,\n resetContextWindow,\n resetAllContextWindows,\n updateContextDraft,\n setPasteValue,\n },\n }\n}\n","/**\n * The Claude subscription settings card.\n *\n * Markup only: every piece of state, every effect and every request this card\n * makes lives in 'useClaudeSection.ts', which returns one named shape the JSX\n * below reads. The two files are the split of a single 900-line component — the\n * behaviour is unchanged, and this one should stay render-shaped.\n */\nimport React from 'react'\nimport type {\n ClaudeAccountSummaryDto,\n ClaudeCacheTtl,\n ClaudeModelOption,\n ClaudeReasoningEffort,\n} from '../../shared/claude-contracts.ts'\nimport { CLAUDE_REASONING_EFFORTS } from '../../shared/claude-contracts.ts'\nimport { AccountPoolSection } from '../common/AccountPoolSection.tsx'\nimport { ContextWindowEditor } from '../common/ContextWindowEditor.tsx'\nimport { ModelChecklist } from '../common/ModelChecklist.tsx'\nimport { formatCapacity, formatDate } from '../common/format.ts'\nimport { useClaudeSection, type ClaudeSectionProps } from './useClaudeSection.ts'\nimport { zh } from './locales.ts'\n\n/**\n * Display label per thinking level.\n *\n * The locale dictionary only accepts flat string values, so this table lives\n * with the control that renders it — the same arrangement every sibling uses.\n * Every level the wire can name is listed, 'xhigh' included: filtering a level\n * out here would hide a choice the host would accept and a catalog may expose.\n */\nconst EFFORT_LABELS: Record<ClaudeReasoningEffort, string> = {\n low: zh.effortLow,\n medium: zh.effortMedium,\n high: zh.effortHigh,\n xhigh: zh.effortXHigh,\n max: zh.effortMax,\n}\n\n/** One-line capability summary shown as a model pill's hover title. */\nfunction modelFacts(model: ClaudeModelOption, t: typeof zh): string[] {\n const thinking = model.thinkingMode === 'mid-convo'\n ? t.thinkingModeMidConvo\n : model.thinkingMode === 'adaptive'\n ? t.thinkingModeAdaptive\n : model.thinkingMode === 'budget' ? t.thinkingModeBudget : t.thinkingModeNone\n return [\n model.id,\n model.supportsImage ? t.capImage : t.capNoImage,\n thinking,\n ...(model.canDisableThinking ? [t.capThinkingOff] : []),\n ...(model.reasoningEfforts.length > 0 ? [model.reasoningEfforts.join('/')] : []),\n ]\n}\n\nexport function ClaudeSection({ onModelChange, loadModelDirectory }: ClaudeSectionProps): React.ReactElement {\n const { state, derived, actions } = useClaudeSection({ onModelChange, loadModelDirectory })\n const { status, loading, busy, error, flow, connection, pasteValue, contextDrafts, savingModel } = state\n const { accounts, hasAdopted, contextModels, overrideCount, quota, windows, poolLabels } = derived\n const {\n login, cancelLogin, submitPaste, adopt, stopImporting, accountAction, setStrategy, relogin,\n refreshQuota, refreshCatalog, testConnection, toggleModel, setAllModels, updateEffort,\n updateCacheTtl, saveContextWindow, resetContextWindow, resetAllContextWindows,\n updateContextDraft, setPasteValue,\n } = actions\n\n const t = zh\n\n if (loading) {\n return (\n <div className=\"dsha-page\">\n <div className=\"dsha-empty\">{t.loading}</div>\n </div>\n )\n }\n\n return (\n <div className=\"dsha-page\">\n <AccountPoolSection<ClaudeAccountSummaryDto>\n accounts={accounts}\n activeAccountId={status?.activeAccountId}\n rotationStrategy={status?.rotationStrategy ?? 'sequential'}\n busy={busy}\n labels={poolLabels}\n onLogin={() => void login()}\n onSetPrimary={(accountId) => void accountAction('set-primary', accountId)}\n onDelete={(accountId) => void accountAction('delete', accountId)}\n onClearCooldown={(accountId) => void accountAction('clear-cooldown', accountId)}\n onRelogin={(accountId) => relogin(accountId)}\n onSetStrategy={(strategy) => void setStrategy(strategy)}\n showQuota\n renderLoginActions={() => (\n <div className=\"dsha-account-add-actions\">\n <button\n className=\"dsha-btn dsha-btn-primary\"\n disabled={busy !== null}\n aria-label={t.signIn}\n onClick={() => void login()}\n >\n {busy === 'login' ? t.signingIn : t.signIn}\n </button>\n {/* The second entry: an existing local Claude Code sign-in can be\n borrowed instead of running a fresh OAuth flow. */}\n <button\n className=\"dsha-btn\"\n disabled={busy !== null}\n aria-label={t.importClaudeCode}\n onClick={() => void adopt()}\n >\n {busy === 'adopt' ? t.importing : t.importClaudeCode}\n </button>\n </div>\n )}\n renderAccountActions={(entry) => (\n // An imported row is a snapshot of a sign-in this plugin does NOT own,\n // so the shared card suppresses Delete for it ('removable: false') and\n // this is the action that replaces it. Un-importing forgets the\n // snapshot; Claude Code's own file is never touched.\n entry.adopted === true || entry.removable === false ? (\n <button\n className=\"dsha-btn\"\n disabled={busy !== null}\n aria-label={`${t.stopImporting}: ${entry.id}`}\n onClick={() => void stopImporting(entry.id)}\n >\n {busy === `adopt-disable-${entry.id}` ? t.importing : t.stopImporting}\n </button>\n ) : null\n )}\n // Only facts the shared card cannot know. E-mail is the shared card's\n // row (and is usually the card's title already); the snapshot path is\n // credential bookkeeping, which the card does not show anywhere.\n renderDetails={(entry) => (\n <>\n {entry.planLabel && <span>{t.plan}: {entry.planLabel}</span>}\n {entry.subscriptionType && <span>{t.subscriptionType}: {entry.subscriptionType}</span>}\n <span>\n {t.source}: {entry.source === 'claude-code' ? t.sourceClaudeCode : t.sourceManaged}\n </span>\n </>\n )}\n >\n {hasAdopted && (\n <div className=\"dsha-actions\">\n <button\n className=\"dsha-btn\"\n disabled={busy !== null}\n aria-label={t.stopImporting}\n onClick={() => void stopImporting()}\n >\n {busy === 'adopt-disable' ? t.importing : t.stopImporting}\n </button>\n </div>\n )}\n\n {flow !== null && flow.status !== 'idle' && flow.status !== 'complete' && (\n <div className=\"dshcl-flow\">\n <strong>{t.signInSection}</strong>\n <p className=\"dsha-muted\">\n {flow?.status === 'error'\n ? `${t.loginFailed}: ${flow.error ?? ''}`\n : flow?.status === 'exchanging'\n ? t.loginExchanging\n : flow?.mode === 'manual' ? t.loginModeManual : t.loginModeLoopback}\n </p>\n {flow?.hint !== undefined && <p className=\"dsha-muted\">{flow.hint}</p>}\n {flow?.fallbackReason !== undefined && (\n <p className=\"dsha-notice\">{t.loginFallbackReason.replace('{detail}', flow.fallbackReason)}</p>\n )}\n {flow?.authUrl !== undefined && (\n <>\n <span className=\"dsha-label\">{t.authorizeUrl}</span>\n <code className=\"dshcl-flow-url\">{flow.authUrl}</code>\n <div className=\"dsha-actions\">\n <a className=\"dsha-btn\" href={flow.authUrl} target=\"_blank\" rel=\"noreferrer noopener\">\n {t.openAuthorizeUrl}\n </a>\n </div>\n </>\n )}\n {flow?.redirectUri !== undefined && (\n <div className=\"dsha-row\">\n <span className=\"dsha-label\">{t.redirectUri}</span>\n <span className=\"dsha-value dshcl-mono\">{flow.redirectUri}</span>\n </div>\n )}\n {/* Always rendered while a flow is pending, and never hidden behind a\n mode test: manual mode has no browser callback at all, so for those\n users this box is the only way to finish signing in. */}\n <div className=\"dshcl-paste\">\n <strong>{t.manualPasteSection}</strong>\n <p className=\"dsha-muted\">{t.manualPasteHint}</p>\n <div className=\"dshcl-paste-row\">\n <input\n type=\"text\"\n className=\"dsha-select\"\n aria-label={t.manualPasteSection}\n placeholder={t.manualPastePlaceholder}\n value={pasteValue}\n disabled={busy !== null}\n onChange={(event) => setPasteValue(event.currentTarget.value)}\n onKeyDown={(event) => {\n if (event.key === 'Enter') void submitPaste()\n }}\n />\n <button\n className=\"dsha-btn dsha-btn-primary\"\n disabled={busy !== null || pasteValue.trim() === ''}\n onClick={() => void submitPaste()}\n >\n {busy === 'login-input' ? t.manualPasteSubmitting : t.manualPasteSubmit}\n </button>\n <button className=\"dsha-btn\" disabled={busy !== null} onClick={() => void cancelLogin()}>\n {t.cancelSignIn}\n </button>\n </div>\n </div>\n </div>\n )}\n </AccountPoolSection>\n\n <section className=\"dsha-group\">\n <div className=\"dsha-grouphead\">\n <h3>{t.connection}</h3>\n </div>\n {status?.account !== null && status?.account !== undefined && (\n <div className=\"dsha-row\">\n <span className=\"dsha-label\">{t.account}</span>\n <span className=\"dsha-value\">\n {status.account.email ?? t.planUnknown}\n {status.account.subscriptionType !== null ? ` · ${status.account.subscriptionType}` : ''}\n </span>\n </div>\n )}\n <p className=\"dsha-notice\">\n {status?.serving === false && status.conflict\n ? t.routeConflict.replace('{detail}', status.conflict)\n : t.routeOwned}\n </p>\n {connection !== null && (\n <p className={connection.connected ? 'dsha-muted' : 'dsha-notice'}>\n {connection.connected\n ? `${t.testSuccess} · ${t.testLatency.replace('{ms}', String(connection.latencyMs))}`\n : t.testFailed.replace('{detail}', connection.error ?? `HTTP ${connection.status}`)\n + ` (${connection.retryable ? t.testRetryable : t.testNotRetryable})`}\n </p>\n )}\n <div className=\"dsha-actions\">\n <button\n className=\"dsha-btn\"\n disabled={busy !== null || !status?.authenticated}\n onClick={() => void testConnection()}\n >\n {busy === 'connection' ? t.testingConnection : t.testConnection}\n </button>\n </div>\n </section>\n\n <section className=\"dsha-group\">\n <div className=\"dsha-grouphead\">\n <h3>{t.modelsSection}</h3>\n <button\n className=\"dsha-btn\"\n disabled={busy !== null}\n onClick={() => void refreshCatalog()}\n >\n {busy === 'catalog' ? t.refreshingCatalog : t.refreshCatalog}\n </button>\n </div>\n <p className=\"dsha-muted dsha-models-hint\">{t.modelsHint}</p>\n <ModelChecklist\n items={(status?.models ?? []).map((model: ClaudeModelOption) => ({\n id: model.id,\n name: model.name,\n hint: modelFacts(model, t).slice(1).join(' · ') || undefined,\n enabled: model.enabled,\n }))}\n busy={busy !== null}\n onToggle={toggleModel}\n onToggleAll={setAllModels}\n labels={{ selectAll: t.selectAll, clearAll: t.unselectAll, list: t.modelsSection }}\n />\n </section>\n\n <section className=\"dsha-group\">\n <div className=\"dsha-grouphead\">\n <h3>{t.enhanced}</h3>\n </div>\n <div className=\"dsha-pref-row\">\n <div>\n <strong>{t.defaultReasoningEffort}</strong>\n <p className=\"dsha-muted\">{t.defaultReasoningEffortHint}</p>\n </div>\n <select\n className=\"dsha-select\"\n aria-label={t.defaultReasoningEffort}\n value={status?.defaultReasoningEffort ?? ''}\n disabled={busy !== null}\n onChange={(event) => {\n const value = event.currentTarget.value\n void updateEffort(value === '' ? null : (value as ClaudeReasoningEffort))\n }}\n >\n <option value=\"\">{t.defaultEffortAuto}</option>\n {/* Exactly what the catalog exposes, 'xhigh' included. */}\n {CLAUDE_REASONING_EFFORTS.map((effort) => (\n <option key={effort} value={effort}>{EFFORT_LABELS[effort]}</option>\n ))}\n </select>\n </div>\n <div className=\"dsha-pref-row\">\n <div>\n <strong>{t.cacheTtl}</strong>\n <p className=\"dsha-muted\">{t.cacheTtlHint}</p>\n </div>\n <select\n className=\"dsha-select\"\n aria-label={t.cacheTtl}\n value={status?.cacheTtl ?? ''}\n disabled={busy !== null}\n onChange={(event) => {\n const value = event.currentTarget.value\n void updateCacheTtl(value === '' ? null : (value as ClaudeCacheTtl))\n }}\n >\n <option value=\"\">{t.cacheTtlSubscription}</option>\n <option value=\"1h\">{t.cacheTtl1h}</option>\n <option value=\"5m\">{t.cacheTtl5m}</option>\n </select>\n </div>\n <p className=\"dsha-muted\" style={{ paddingTop: 10 }}>{t.modelLadders}</p>\n {status?.models.map((model) => (\n <div key={model.id} className=\"dsha-row\">\n <span className=\"dsha-label\">{model.name}</span>\n <span className=\"dsha-value\">\n {model.reasoningEfforts.length === 0 ? t.modelLadderNone : model.reasoningEfforts.join(' · ')}\n </span>\n </div>\n ))}\n </section>\n\n <section className=\"dsha-group\">\n <div className=\"dsha-grouphead\">\n <h3>{t.contextWindowSection}</h3>\n </div>\n <p className=\"dsha-muted\">{t.contextWindowHint}</p>\n <ContextWindowEditor\n rows={contextModels.map((model: ClaudeModelOption) => ({\n id: model.id,\n name: model.name,\n draft: contextDrafts[model.id] ?? '',\n meta: model.defaultContextWindow < model.contextWindow\n ? formatCapacity(model.contextWindow)\n : undefined,\n inputLabel: `${model.name} context window`,\n hasOverride: status?.contextWindowOverrides[model.id] !== undefined,\n saving: savingModel === model.id,\n }))}\n labels={{\n tokens: t.tokens,\n save: t.save,\n saving: t.saving,\n reset: t.contextWindowReset,\n resetAll: t.contextWindowResetAll,\n empty: t.contextWindowNoneEnabled,\n }}\n busy={busy !== null}\n overrideCount={overrideCount}\n metaClassName=\"dshcl-model-meta\"\n onDraftChange={(id, draft) => updateContextDraft(id, draft)}\n onCommit={(id) => void saveContextWindow(id)}\n onReset={(id) => void resetContextWindow(id)}\n onResetAll={() => void resetAllContextWindows()}\n />\n </section>\n\n <section className=\"dsha-group\">\n <div className=\"dsha-grouphead\">\n <h3>{t.quotaSection}</h3>\n <button\n className=\"dsha-btn\"\n disabled={busy !== null || !status?.authenticated}\n onClick={() => void refreshQuota()}\n >\n {busy === 'quota' ? t.refreshingQuota : t.refreshQuota}\n </button>\n </div>\n <p className=\"dsha-muted\">{t.quotaDesc}</p>\n {/* The progress bars moved into each account card: quota follows the\n account, so a bar here could only ever describe whichever account\n happened to be active when the snapshot was read. What stays is what\n has no per-account bar to live in — the extra-usage meter's own\n facts, the rate-limit status, the representative window and the\n freshness of this reading. */}\n <p className=\"dsha-muted\">{t.quotaFactsScope}</p>\n\n {/* A refresh running behind the answer is rendered beside the snapshot\n rather than instead of it: the numbers on screen are real, just not\n the newest, and the follow-up poll brings the newer ones. */}\n {status?.quotaRefreshing === true && <p className=\"dsha-notice\">{t.quotaRefreshing}</p>}\n {status?.quotaError !== undefined && status.quotaError !== null && (\n <p className=\"dsha-notice\">{t.quotaError}: {status.quotaError}</p>\n )}\n\n {!status?.authenticated ? (\n <div className=\"dsha-empty\">{t.quotaSignedOut}</div>\n ) : quota === null || quota === undefined ? (\n <div className=\"dsha-empty\">{busy === 'quota' ? t.refreshingQuota : t.quotaEmpty}</div>\n ) : (\n <div className=\"dsha-quota-card\">\n <div className=\"dsha-quota-title\">\n <strong>{status.account?.subscriptionType ?? t.quotaSection}</strong>\n <span>{status.account?.email ?? t.planUnknown}</span>\n </div>\n\n {quota.extraUsage !== null && (\n <div className=\"dsha-meter-wrap\">\n <div className=\"dsha-meter-label\">\n <span>{quota.extraUsage.label || t.extraUsage}</span>\n <strong>\n {quota.extraUsage.remainingPercent === null\n ? t.quotaUnknown\n : `${Math.round(quota.extraUsage.remainingPercent)}% ${t.left}`}\n </strong>\n </div>\n <div className=\"dsha-meter-meta\">\n <span>{t.extraUsage}: {quota.extraUsage.enabled ? t.extraUsageEnabled : t.extraUsageDisabled}</span>\n {quota.extraUsage.used !== null && <span>{t.usedLabel}: {quota.extraUsage.used}</span>}\n {quota.extraUsage.limit !== null && (\n <span>{t.extraUsageLimit}: {quota.extraUsage.limit}</span>\n )}\n </div>\n </div>\n )}\n\n {quota.status !== null && (\n <div className=\"dsha-row\">\n <span className=\"dsha-label\">{t.quotaStatus}</span>\n <span className=\"dsha-value\">{quota.status}</span>\n </div>\n )}\n {quota.representativeClaim !== null && (\n <div className=\"dsha-row\">\n <span className=\"dsha-label\">{t.quotaRepresentative}</span>\n <span className=\"dsha-value\">{quota.representativeClaim}</span>\n </div>\n )}\n\n {windows.length === 0 && quota.extraUsage === null && (\n <div className=\"dsha-empty\">{t.quotaEmpty}</div>\n )}\n\n <div className=\"dsha-timestamp\">\n {quota.fetchedAt === null\n ? t.observedAt.replace('{time}', formatDate(quota.observedAt))\n : t.updatedAt.replace('{time}', formatDate(quota.fetchedAt))}\n </div>\n </div>\n )}\n </section>\n\n {error && (\n <div className=\"dsha-error\">\n <div>{error}</div>\n </div>\n )}\n </div>\n )\n}\n","import type { OllamaWebStatus } from '../../shared/ollama-contracts.ts'\n\nconst API = '/ollama/api'\n\n/**\n * The Ollama settings API, as the card uses it.\n *\n * Deliberately the same envelope and the same fetch shape every other provider\n * section uses, so the shared account-pool card and this helper read alike.\n */\nexport class OllamaApi {\n status(): Promise<OllamaWebStatus> {\n return request<OllamaWebStatus>(`${API}/status`)\n }\n\n /**\n * One pool action, returning the refreshed status.\n *\n * The host answers with the same envelope the status route uses, so the card\n * never has to guess what the pool looks like after a change.\n */\n accountAction(\n action: 'add' | 'set-primary' | 'set-alias' | 'delete' | 'clear-cooldown' | 'strategy',\n body: { accountId?: string; alias?: string; strategy?: string; apiKey?: string } = {},\n ): Promise<OllamaWebStatus> {\n return post<OllamaWebStatus>(`${API}/accounts`, { action, ...body })\n }\n\n refreshCatalog(): Promise<{ models: unknown[] }> {\n return post(`${API}/catalog/refresh`, {})\n }\n\n /**\n * Replace the enabled-model selection.\n *\n * The whole list is sent rather than a single id's new state, because the card\n * offers bulk select and unselect and would otherwise have to read the current\n * selection before it could answer 'turn this one off'.\n */\n setEnabledModels(enabledModelIds: string[]): Promise<{ enabledModelIds: string[] }> {\n return post(`${API}/models`, { enabledModelIds })\n }\n}\n\nasync function post<T>(url: string, body: object): Promise<T> {\n return request<T>(url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body),\n })\n}\n\nasync function request<T>(url: string, init?: RequestInit): Promise<T> {\n const response = await fetch(url, { ...init, credentials: 'same-origin' })\n const envelope = await readEnvelope<T>(response)\n if (!response.ok || !envelope.ok) {\n throw new Error(envelope.error || `HTTP ${response.status}`)\n }\n return envelope.value as T\n}\n\n/**\n * Read the {ok,value,error} envelope, or say why there was not one.\n *\n * `response.json()` is not a way to report an error. A body that is empty —\n * which is what DSH's web server sends for a route handler that rejected, and\n * what a proxy sends for a blocked request — throws the browser's own\n * \"Failed to execute 'json' on 'Response': Unexpected end of JSON input\" (issue\n * #36), a sentence that names neither the status nor the request. Reading the\n * text first costs one string and turns every unreadable answer into a message\n * that says what the Host actually replied.\n *\n * The body is never echoed back: it can be an HTML page of arbitrary size, and\n * its content-type alone is what identifies the failure.\n */\nasync function readEnvelope<T>(\n response: Response,\n): Promise<{ ok: boolean; value?: T; error?: string }> {\n let text: string\n try {\n text = await response.text()\n } catch (cause) {\n throw new Error(unreadable(response, cause))\n }\n if (text.trim() === '') throw new Error(unreadable(response))\n let parsed: unknown\n try {\n parsed = JSON.parse(text)\n } catch {\n throw new Error(unreadable(response))\n }\n if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {\n throw new Error(unreadable(response))\n }\n const envelope = parsed as { ok: boolean; value?: T; error?: string }\n if (typeof envelope.error !== 'string') delete envelope.error\n return envelope\n}\n\n/** The one sentence every unreadable answer turns into. */\nfunction unreadable(response: Response, cause?: unknown): string {\n const kind = response.headers.get('content-type') ?? 'no content-type'\n return `The Ollama settings API answered with ${response.status} and no JSON body (${kind})`\n + (cause instanceof Error ? `: ${cause.message}` : '')\n + '. The Host log holds the underlying error.'\n}","import { accountPoolEn, accountPoolZh } from '../common/account-pool-labels.ts'\n\nexport const NS_OLLAMA = 'dsh-ollama'\n\nexport const zh = {\n // The account-management card is shared with every other provider tab, so its\n // labels come from one place instead of drifting per provider. Only the two\n // entries that are wrong for a pasted key are overridden below.\n ...accountPoolZh,\n // Two overrides, and both are factual rather than cosmetic: an Ollama key\n // never expires and is replaced rather than re-signed-in, so the shared\n // wording would state something untrue about this line.\n relogin: '更换 Key',\n needsRelogin: 'Key 已失效',\n addAccount: '添加 API Key',\n noAccounts: '暂无 API Key。点击「添加 API Key」粘贴 ollama.com 创建的 Key。',\n\n title: 'Ollama',\n pageDesc: '接入 Ollama Cloud,用多个 API Key 组成号池,自动轮换与故障转移。',\n routeOwned: '模型路由由本插件提供',\n routeConflict: '模型路由已被其他 Provider 占用:{detail}。请在 DSH 设置中移除重复的 Provider 配置后重试。',\n\n // Sign-in is a paste, not a flow: the service issues a static key and there\n // is nothing to authorize.\n keySection: '添加 API Key',\n keyHint: '在 https://ollama.com/settings/keys 创建 API Key 后粘贴到此处。Key 不会过期,可随时在设置页吊销。',\n keyPlaceholder: '粘贴 Ollama API Key',\n keyAliasLabel: '备注名(可选)',\n keyAliasPlaceholder: '例如:主号、备用号',\n keyAliasHint: 'Ollama 不返回账号信息,多个 Key 靠备注名区分。',\n keySave: '添加',\n keySaving: '添加中...',\n\n modelsSection: '模型',\n modelsHint: '模型列表来自 Ollama 的 /api/tags,随服务更新,无需手动维护。',\n catalogSync: '同步模型列表',\n catalogSyncing: '同步中...',\n catalogNeverSynced: '尚未同步模型列表。点右上角「同步模型列表」获取你账号可用的模型 —— 在此之前这里不会有任何条目,本线路也不会出现在模型选择器中。',\n catalogEmpty: 'Ollama 未返回任何模型。',\n catalogNeedKey: '请先添加一个 API Key,再同步模型列表。',\n catalogFailed: '无法从 Ollama 读取模型列表。',\n modelCount: '{count} 个模型',\n noModels: '暂无可用模型。',\n selectAll: '全选',\n unselectAll: '全不选',\n noneSelected: '未选择任何模型,该线路不会出现在模型选择器中。',\n\n // Stated plainly, because these are documented service limits and a user who\n // hits them deserves to know they are not a bug here.\n limitsSection: '能力边界',\n limitsHint: '以下为 Ollama Cloud 官方文档列出的限制,本线路不会绕过:',\n limitNoStateful: '不支持 Responses 的有状态会话(仅无状态形式)。',\n limitNoWebSearch: '不支持通过 /v1/responses 使用内置联网搜索。',\n limitNoToolReplay: '不支持自定义工具调用的重放(replay)。',\n limitUsage: 'Ollama 没有配额/剩余额度 API(上游 issue #15132、#15663 均已关闭),所以只能显示「已消耗」,无法显示「剩余多少」。',\n wireNote: '请求默认走 OpenAI 兼容面(/v1),必要时回落到原生面(/api/chat)。',\n\n lastModel: '最近模型',\n keyCreated: '添加于',\n error: '操作失败:{detail}',\n usageTitle: '累计消耗',\n usageInput: '输入 {tokens}',\n usageOutput: '输出 {tokens}',\n usageRequests: '{count} 次请求',\n usageNone: '尚无请求',\n usageHint: '按 Ollama 每次响应自带的 token 计数本地累加。',\n} as const\n\nexport const en = {\n ...accountPoolEn,\n relogin: 'Replace Key',\n needsRelogin: 'Key rejected',\n addAccount: 'Add API Key',\n noAccounts: 'No API keys yet. Click \"Add API Key\" to paste one from ollama.com.',\n\n title: 'Ollama',\n pageDesc: 'Connect Ollama Cloud with several API keys pooled for rotation and failover.',\n routeOwned: 'Model route served by this plugin',\n routeConflict: 'The model route is already owned by another provider: {detail}',\n\n keySection: 'Add an API key',\n keyHint: 'Create a key at https://ollama.com/settings/keys and paste it here. Keys do not expire and can be revoked from that page.',\n keyPlaceholder: 'Paste an Ollama API key',\n keyAliasLabel: 'Label (optional)',\n keyAliasPlaceholder: 'e.g. primary, backup',\n keyAliasHint: 'Ollama reports no account identity, so labels are what tell several keys apart.',\n keySave: 'Add',\n keySaving: 'Adding...',\n\n modelsSection: 'Models',\n modelsHint: 'The list comes from Ollama \\'/api/tags\\' and tracks the service, so there is nothing to maintain by hand.',\n catalogSync: 'Sync model list',\n catalogSyncing: 'Syncing...',\n catalogNeverSynced: 'The model list has not been synced yet. Use \"Sync model list\" above to fetch the models your account can use - until then this list is empty and the line will not appear in the model picker.',\n catalogEmpty: 'Ollama returned no models.',\n catalogNeedKey: 'Add an API key before syncing the model list.',\n catalogFailed: 'Could not read the model list from Ollama.',\n modelCount: '{count} model(s)',\n noModels: 'No models available.',\n selectAll: 'Select all',\n unselectAll: 'Clear all',\n noneSelected: 'No models are selected, so this line will not appear in the model picker.',\n\n limitsSection: 'Documented limits',\n limitsHint: 'Ollama Cloud documents these limits; this line does not work around them:',\n limitNoStateful: 'No stateful Responses (stateless only).',\n limitNoWebSearch: 'No built-in web search through /v1/responses.',\n limitNoToolReplay: 'No replay of custom tool calls.',\n limitUsage: 'Ollama has no quota or remaining-balance API (upstream issues #15132 and #15663 were both closed), so this card can show what has been consumed but not what is left.',\n wireNote: 'Requests use the OpenAI-compatible surface (/v1) and fall back to the native surface (/api/chat) when needed.',\n\n lastModel: 'Last model',\n keyCreated: 'Added',\n error: 'Action failed: {detail}',\n usageTitle: 'Consumed so far',\n usageInput: 'in {tokens}',\n usageOutput: 'out {tokens}',\n usageRequests: '{count} request(s)',\n usageNone: 'No requests yet',\n usageHint: 'Summed locally from the token counts Ollama returns on each response.',\n} as const\n\n// Same shape every other provider locale exports: the host selects the active\n// locale and the section reads the flat dictionary through it.\nexport const dictionaries = {\n zh,\n 'zh-CN': zh,\n en,\n 'en-US': en,\n}\n\nexport type OllamaLocaleKey = keyof typeof zh\n\n","import React, { useCallback, useEffect, useState } from 'react'\nimport { AccountPoolSection } from '../common/AccountPoolSection.tsx'\nimport { ModelChecklist } from '../common/ModelChecklist.tsx'\nimport type { AccountRotationStrategy } from '../../shared/account-pool-contracts.ts'\nimport type { OllamaWebStatus } from '../../shared/ollama-contracts.ts'\nimport { OllamaApi } from './api.ts'\nimport { zh } from './locales.ts'\n\nconst API = new OllamaApi()\n\n/**\n * A token count short enough to sit in an account card.\n *\n * Exact below a thousand, then thousands, then millions. A six-figure number with\n * no grouping is unreadable at card width, and these are running totals that only\n * ever grow, so rounding is fine but commas are not optional.\n */\nexport function formatTokens(value: number): string {\n if (!Number.isFinite(value) || value < 0) return '—'\n if (value < 1_000) return String(Math.floor(value))\n if (value < 1_000_000) return `${(value / 1_000).toFixed(value < 10_000 ? 1 : 0)}K`\n return `${(value / 1_000_000).toFixed(1)}M`\n}\n\ninterface Props {\n onModelChange?: () => void\n loadModelDirectory?: () => void\n}\n\n/**\n * The Ollama tab.\n *\n * Deliberately thin. The account card, its badges and the rotation picker are\n * the shared {@link AccountPoolSection}, so this line looks\n * like every other provider tab by construction rather than by imitation; only\n * what is genuinely Ollama's - pasting a key, syncing the catalog, and the\n * documented service limits - is written here.\n */\nexport function OllamaSection(props: Props): React.ReactElement {\n const [status, setStatus] = useState<OllamaWebStatus | null>(null)\n const [busy, setBusy] = useState<string | null>(null)\n const [error, setError] = useState<string | null>(null)\n const [key, setKey] = useState('')\n const [alias, setAlias] = useState('')\n const [showKeyForm, setShowKeyForm] = useState(false)\n /** Ids the user has switched on. Empty means 'no filter', i.e. all of them. */\n const [enabled, setEnabled] = useState<Set<string>>(new Set())\n\n const reload = useCallback(async () => {\n try {\n const next = await API.status()\n setStatus(next)\n setEnabled(new Set(next.enabledModelIds))\n } catch (cause) {\n setError(cause instanceof Error ? cause.message : String(cause))\n }\n }, [])\n\n useEffect(() => {\n void reload()\n }, [reload])\n\n const run = useCallback(async (label: string, action: () => Promise<OllamaWebStatus>) => {\n setBusy(label)\n setError(null)\n try {\n setStatus(await action())\n props.onModelChange?.()\n props.loadModelDirectory?.()\n } catch (cause) {\n setError(cause instanceof Error ? cause.message : String(cause))\n } finally {\n setBusy(null)\n }\n }, [props])\n\n const addKey = useCallback(() => {\n const trimmed = key.trim()\n if (trimmed === '') return\n void run('add', async () => {\n const next = await API.accountAction('add', {\n apiKey: trimmed,\n ...(alias.trim() === '' ? {} : { alias: alias.trim() }),\n })\n // Cleared only after the host accepted it, so a failed add never loses the\n // key the user just pasted and would have to find again.\n setKey('')\n setAlias('')\n setShowKeyForm(false)\n return next\n })\n }, [key, alias, run])\n\n const syncCatalog = useCallback(() => {\n void run('catalog', async () => {\n await API.refreshCatalog()\n return API.status()\n })\n }, [run])\n\n // An empty selection means 'everything the catalog returned', which is what the\n // adapter reads as no filter. Modelling it that way rather than storing an\n // explicit all-ids list means a model the service adds later is not silently\n // hidden by a selection made before it existed.\n const isModelEnabled = useCallback((id: string): boolean => {\n return enabled.size === 0 || enabled.has(id)\n }, [enabled])\n\n const applyEnabled = useCallback((next: string[]) => {\n void run('models', async () => {\n const result = await API.setEnabledModels(next)\n setEnabled(new Set(result.enabledModelIds))\n return API.status()\n })\n }, [run])\n\n const toggleModel = useCallback((id: string, checked: boolean) => {\n if (status === null) return\n const current = status.models.filter(model => isModelEnabled(model.id)).map(model => model.id)\n const next = checked\n ? [...new Set([...current, id])]\n : current.filter(entry => entry !== id)\n applyEnabled(next)\n }, [status, isModelEnabled, applyEnabled])\n\n const setAllModels = useCallback((selectAll: boolean) => {\n if (status === null || status.models.length === 0) return\n applyEnabled(selectAll ? status.models.map(model => model.id) : [])\n }, [status, applyEnabled])\n\n const t = zh\n const pool = status?.pool\n\n return (\n <div>\n <div className=\"dsha-group\">\n <div className=\"dsha-grouphead\">\n <h3>{t.title}</h3>\n </div>\n <p className=\"dsha-notice\">{t.pageDesc}</p>\n {error !== null && (\n <p className=\"dsha-notice\" style={{ color: 'var(--dsha-danger, #c0392b)' }}>\n {t.error.replace('{detail}', error)}\n </p>\n )}\n </div>\n\n {pool !== undefined && (\n <AccountPoolSection\n accounts={pool.accounts}\n activeAccountId={pool.activeAccountId}\n rotationStrategy={pool.rotationStrategy}\n labels={t}\n busy={busy}\n onLogin={() => setShowKeyForm(value => !value)}\n onSetPrimary={(id) => void run('set-primary', () => API.accountAction('set-primary', { accountId: id }))}\n onDelete={(id) => void run('delete', () => API.accountAction('delete', { accountId: id }))}\n onClearCooldown={(id) => void run('clear-cooldown', () => API.accountAction('clear-cooldown', { accountId: id }))}\n onSetStrategy={(strategy: AccountRotationStrategy) =>\n void run('strategy', () => API.accountAction('strategy', { strategy }))}\n renderDetails={(account) => {\n const usage = account.usage\n return <>\n {account.lastModelId !== undefined && <span>{t.lastModel}: {account.lastModelId}</span>}\n {usage === undefined\n ? <span>{t.usageNone}</span>\n : <span>\n {t.usageInput.replace('{tokens}', formatTokens(usage.inputTokens))}\n {t.usageOutput.replace('{tokens}', formatTokens(usage.outputTokens))}\n {t.usageRequests.replace('{count}', String(usage.requestCount))}\n </span>}\n </>\n }}\n renderLoginActions={() => (\n <div style={{ display: 'flex', gap: 8 }}>\n <button\n className=\"dsha-btn dsha-btn-primary\"\n disabled={busy !== null}\n onClick={() => setShowKeyForm(value => !value)}\n >\n {t.addAccount}\n </button>\n </div>\n )}\n >\n {showKeyForm && (\n <div className=\"dsha-pref-row\" style={{ flexDirection: 'column', alignItems: 'stretch', gap: 8 }}>\n <label className=\"dsha-label\" htmlFor=\"ollama-key\">{t.keySection}</label>\n <input\n id=\"ollama-key\"\n className=\"dsha-input\"\n type=\"password\"\n value={key}\n placeholder={t.keyPlaceholder}\n autoComplete=\"off\"\n onChange={(event) => setKey(event.target.value)}\n />\n <label className=\"dsha-label\" htmlFor=\"ollama-alias\">{t.keyAliasLabel}</label>\n <input\n id=\"ollama-alias\"\n className=\"dsha-input\"\n value={alias}\n placeholder={t.keyAliasPlaceholder}\n onChange={(event) => setAlias(event.target.value)}\n />\n <p className=\"dsha-muted\" style={{ fontSize: 12 }}>{t.keyHint}</p>\n <p className=\"dsha-muted\" style={{ fontSize: 12 }}>{t.keyAliasHint}</p>\n <div style={{ display: 'flex', gap: 8 }}>\n <button\n className=\"dsha-btn dsha-btn-primary\"\n disabled={busy !== null || key.trim() === ''}\n onClick={addKey}\n >\n {busy === 'add' ? t.keySaving : t.keySave}\n </button>\n <button className=\"dsha-btn\" disabled={busy !== null} onClick={() => setShowKeyForm(false)}>\n {zh.deleteAccount}\n </button>\n </div>\n </div>\n )}\n </AccountPoolSection>\n )}\n\n <div className=\"dsha-group\">\n <div className=\"dsha-grouphead\">\n <h3>{t.modelsSection}</h3>\n <button className=\"dsha-btn\" disabled={busy !== null} onClick={syncCatalog}>\n {busy === 'catalog' ? t.catalogSyncing : t.catalogSync}\n </button>\n </div>\n <p className=\"dsha-muted\" style={{ fontSize: 12 }}>{t.modelsHint}</p>\n <p className=\"dsha-muted\" style={{ fontSize: 12 }}>{t.wireNote}</p>\n {status !== null && status.models.length === 0 && (\n <div className=\"dsha-empty\">\n {status.catalogSynced ? t.catalogEmpty : t.catalogNeverSynced}\n </div>\n )}\n {status !== null && status.models.length === 0 && !status.usable && (\n <p className=\"dsha-muted\" style={{ fontSize: 12 }}>{t.catalogNeedKey}</p>\n )}\n {status !== null && status.models.length > 0 && (\n <>\n <p className=\"dsha-muted\" style={{ fontSize: 12 }}>\n {t.modelCount.replace('{count}', String(status.models.length))}\n </p>\n <ModelChecklist\n items={status.models.map((model) => ({\n id: model.id,\n name: model.name ?? model.id,\n enabled: isModelEnabled(model.id),\n }))}\n busy={busy !== null}\n onToggle={(id, enabled) => void toggleModel(id, enabled)}\n onToggleAll={(enabled) => void setAllModels(enabled)}\n labels={{ selectAll: t.selectAll, clearAll: t.unselectAll, list: t.modelsSection }}\n />\n </>\n )}\n </div>\n\n <div className=\"dsha-group\">\n <div className=\"dsha-grouphead\">\n <h3>{t.limitsSection}</h3>\n </div>\n <p className=\"dsha-muted\" style={{ fontSize: 12 }}>{t.limitsHint}</p>\n <ul className=\"dsha-notice\" style={{ paddingLeft: 18 }}>\n <li>{t.limitNoStateful}</li>\n <li>{t.limitNoWebSearch}</li>\n <li>{t.limitNoToolReplay}</li>\n <li>{t.limitUsage}</li>\n </ul>\n </div>\n </div>\n )\n}","/**\n * The hub's provider registry: one descriptor per subscription line.\n *\n * This is the single place the overview learns what a line is called, what\n * its card looks like, how its enable switch talks to the host, and which\n * section the detail page mounts. Adding a line to the hub means adding one\n * entry here — the overview, the navigation and the card rendering all read\n * this table.\n */\nimport type { ReactElement } from 'react'\nimport type { PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\nimport { ROUTE_PREFIX } from '../../compat.ts'\nimport { MINIMAX_CODE_ROUTE_PREFIX } from '../../shared/minimax-code-contracts.ts'\nimport { CodexSubscriptionSection } from '../CodexSubscriptionSection.tsx'\nimport { AntigravitySection } from '../antigravity/AntigravitySection.tsx'\nimport { CommandCodeSection } from '../command-code/CommandCodeSection.tsx'\nimport { KimiCodeSection } from '../kimi-code/KimiCodeSection.tsx'\nimport { WorkBuddySection } from '../workbuddy/WorkBuddySection.tsx'\nimport { MinimaxCodeSection } from '../minimax-code/MinimaxCodeSection.tsx'\nimport { ClaudeSection } from '../claude/ClaudeSection.tsx'\nimport { OllamaSection } from '../ollama/OllamaSection.tsx'\nimport type { HubProviderId } from './brand-icons.tsx'\n\n/** What the detail page hands to a mounted section. */\nexport interface HubDetailRenderProps {\n t: (key: any) => string\n onModelChange?: () => void\n /** The settings.section runtime props (close, etc.) the host slot passes in. */\n runtime: PropsRuntime<'settings.section'>\n}\n\nexport interface HubProviderDescriptor {\n id: HubProviderId\n /** Display name; brand names stay literal, matching the former tabs. */\n name: string\n /**\n * Commit an enable/disable to the line's own settings endpoint.\n *\n * The overview deliberately reuses each line's existing mutation route\n * rather than adding a second mutator to the aggregated overview route —\n * the aggregated route stays read-only, and every line keeps exactly one\n * place that writes its `enabled` flag. Null when the line has no switch.\n */\n setEnabled: ((enabled: boolean) => Promise<void>) | null\n renderDetail(props: HubDetailRenderProps): ReactElement\n}\n\n/** One POST to a line's settings endpoint, answered with that line's refreshed status. */\nasync function postLineSettings(prefix: string, body: Record<string, unknown>): Promise<void> {\n const response = await fetch(`${prefix}/settings`, {\n method: 'POST',\n credentials: 'same-origin',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(body),\n })\n const envelope = await response.json() as { ok: boolean; error?: { message?: string } | string }\n if (!response.ok || !envelope.ok) {\n const error = envelope.error\n throw new Error(typeof error === 'object' && error !== null ? error.message ?? 'Request failed' : String(error ?? 'Request failed'))\n }\n}\n\nasync function setChatGptEnabled(enabled: boolean): Promise<void> {\n const response = await fetch(`${ROUTE_PREFIX}/preferences/update`, {\n method: 'POST',\n credentials: 'same-origin',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ enabled }),\n })\n const envelope = await response.json() as { ok: boolean; error?: { message?: string } }\n if (!response.ok || !envelope.ok) throw new Error(envelope.error?.message ?? 'Request failed')\n}\n\n/** Card order on the overview; also the former tab order. */\nexport const HUB_PROVIDERS: readonly HubProviderDescriptor[] = [\n {\n id: 'chatgpt',\n name: 'ChatGPT',\n setEnabled: setChatGptEnabled,\n renderDetail: ({ t, runtime }) => <CodexSubscriptionSection t={t} {...runtime} />,\n },\n {\n id: 'antigravity',\n name: 'Antigravity',\n setEnabled: (enabled) => postLineSettings('/antigravity/api', { enabled }),\n renderDetail: ({ onModelChange }) => <AntigravitySection onModelChange={onModelChange} />,\n },\n {\n id: 'command-code',\n name: 'Command Code',\n setEnabled: (enabled) => postLineSettings('/command-code/api', { enabled }),\n renderDetail: ({ onModelChange }) => <CommandCodeSection onModelChange={onModelChange} />,\n },\n {\n id: 'kimi-code',\n name: 'Kimi Code',\n setEnabled: (enabled) => postLineSettings('/kimi-code/api', { enabled }),\n renderDetail: ({ onModelChange }) => <KimiCodeSection onModelChange={onModelChange} />,\n },\n {\n id: 'workbuddy',\n name: 'WorkBuddy',\n setEnabled: (enabled) => postLineSettings('/workbuddy/api', { enabled }),\n renderDetail: ({ onModelChange }) => <WorkBuddySection onModelChange={onModelChange} />,\n },\n {\n id: 'minimax-code',\n name: 'MiniMax Code',\n setEnabled: (enabled) => postLineSettings(MINIMAX_CODE_ROUTE_PREFIX, { enabled }),\n renderDetail: ({ onModelChange }) => <MinimaxCodeSection onModelChange={onModelChange} />,\n },\n {\n id: 'claude',\n name: 'Claude',\n setEnabled: (enabled) => postLineSettings('/claude/api', { enabled }),\n renderDetail: ({ onModelChange }) => <ClaudeSection onModelChange={onModelChange} />,\n },\n {\n id: 'ollama',\n name: 'Ollama',\n setEnabled: null,\n renderDetail: ({ onModelChange }) => <OllamaSection onModelChange={onModelChange} />,\n },\n]\n\nexport function hubProviderDescriptor(id: string): HubProviderDescriptor | undefined {\n return HUB_PROVIDERS.find((provider) => provider.id === id)\n}\n","/**\n * The hub's opening screen: one card per provider line, in the QQ-mail\n * account-picker idiom — a brand tile, the line's name, a one-line annotation\n * (accounts, models, state), and exactly two interactions per card: the\n * enable switch and drilling into the line's detail page.\n *\n * Data comes from the host's aggregated read-only overview route, so opening\n * the settings page costs one request and never touches an upstream service.\n * Switch commits go to each line's own settings endpoint (see providers.tsx)\n * and update optimistically; a failed commit rolls the switch back and says\n * so in the card's annotation line, where the user is already looking.\n */\nimport { useCallback, useEffect, useState } from 'react'\nimport type { PropsLocale } from '@deepseek-ai/dsh-client-ui-slots'\nimport type { ApiEnvelope } from '../../shared/contracts.ts'\nimport { HUB_OVERVIEW_PATH } from '../../shared/hub-contracts.ts'\nimport type { HubOverviewDto, HubProviderSummaryDto } from '../../shared/hub-contracts.ts'\nimport { formatPoolLabel } from '../common/account-pool-labels.ts'\nimport type { NS } from '../locales.ts'\nimport { BrandTile } from './brand-icons.tsx'\nimport { HUB_PROVIDERS, type HubProviderDescriptor } from './providers.tsx'\n\nexport type HubTranslate = PropsLocale<typeof NS>['t']\n\ninterface Props {\n t: HubTranslate\n onOpen(id: HubProviderDescriptor['id']): void\n}\n\nasync function fetchOverview(): Promise<HubOverviewDto> {\n const response = await fetch(HUB_OVERVIEW_PATH, { credentials: 'same-origin' })\n const envelope = await response.json() as ApiEnvelope<HubOverviewDto>\n if (!response.ok || !envelope.ok) {\n throw new Error(envelope.ok ? `Request failed (${response.status})` : envelope.error.message)\n }\n return envelope.value\n}\n\n/** The card's one-line annotation: accounts, then models, then state. */\nexport function cardAnnotation(summary: HubProviderSummaryDto | undefined, descriptor: HubProviderDescriptor, t: HubTranslate): string {\n if (summary === undefined) return '…'\n if (summary.error === true) return t('hubStatusFailed')\n const parts: string[] = []\n if (summary.canToggle && !summary.enabled) parts.push(t('hubStateDisabled'))\n parts.push(summary.accountCount > 0\n ? formatPoolLabel(t('hubAccountCount'), { count: summary.accountCount })\n : t('hubNoAccounts'))\n if (summary.enabledModelCount !== null) {\n parts.push(summary.totalModelCount !== null\n ? formatPoolLabel(t('hubModelsEnabledOfTotal'), { count: summary.enabledModelCount, total: summary.totalModelCount })\n : formatPoolLabel(t('hubModelsEnabled'), { count: summary.enabledModelCount }))\n }\n return parts.join(' · ')\n}\n\nexport function HubOverview({ t, onOpen }: Props): React.JSX.Element {\n const [summaries, setSummaries] = useState<ReadonlyMap<string, HubProviderSummaryDto> | null>(null)\n const [loadError, setLoadError] = useState<string | null>(null)\n const [busyId, setBusyId] = useState<string | null>(null)\n const [toggleErrors, setToggleErrors] = useState<ReadonlyMap<string, string>>(new Map())\n\n const load = useCallback(async (): Promise<void> => {\n try {\n const overview = await fetchOverview()\n setSummaries(new Map(overview.providers.map((provider) => [provider.id, provider])))\n setLoadError(null)\n } catch (error) {\n setLoadError(error instanceof Error ? error.message : String(error))\n }\n }, [])\n\n useEffect(() => {\n void load()\n }, [load])\n\n const toggle = useCallback(async (descriptor: HubProviderDescriptor, summary: HubProviderSummaryDto, enabled: boolean): Promise<void> => {\n if (descriptor.setEnabled === null) return\n setBusyId(descriptor.id)\n setToggleErrors((current) => {\n if (!current.has(descriptor.id)) return current\n const next = new Map(current)\n next.delete(descriptor.id)\n return next\n })\n // Optimistic: the switch flips now, the commit answers later.\n setSummaries((current) => new Map(current).set(descriptor.id, { ...summary, enabled }))\n try {\n await descriptor.setEnabled(enabled)\n // The commit did not carry the other lines' counts; refresh behind the\n // settled switch so the annotation stays exact.\n void load()\n } catch (error) {\n setSummaries((current) => new Map(current).set(descriptor.id, { ...summary, enabled: summary.enabled }))\n setToggleErrors((current) => new Map(current).set(descriptor.id, error instanceof Error ? error.message : String(error)))\n } finally {\n setBusyId(null)\n }\n }, [load])\n\n return <div className=\"dsh-hub-overview\">\n <p className=\"dsh-hub-hint\">{t('hubOverviewHint')}</p>\n {loadError !== null && summaries === null ? (\n <div className=\"dsh-codex-errorbar\" role=\"alert\">\n <span>{loadError}</span>\n <button type=\"button\" className=\"dsh-codex-button\" onClick={() => void load()}>{t('retry')}</button>\n </div>\n ) : (\n <div className=\"dsh-hub-cards\">\n {summaries === null ? HUB_PROVIDERS.map((descriptor) => (\n <div key={descriptor.id} className=\"dsh-hub-skeleton\" aria-hidden=\"true\">\n <i />\n <span style={{ flex: 1, display: 'flex', flexDirection: 'column' }}>\n <span className=\"dsh-hub-skel-name\" />\n <span className=\"dsh-hub-skel-note\" />\n </span>\n </div>\n )) : HUB_PROVIDERS.map((descriptor) => {\n const summary = summaries.get(descriptor.id)\n return <HubProviderCard\n key={descriptor.id}\n descriptor={descriptor}\n summary={summary}\n busy={busyId === descriptor.id}\n toggleError={toggleErrors.get(descriptor.id) ?? null}\n t={t}\n onOpen={onOpen}\n onToggle={toggle}\n />\n })}\n </div>\n )}\n </div>\n}\n\nconst CHEVRON_SVG = '<svg viewBox=\"0 0 16 16\" width=\"14\" height=\"14\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M6 4l4 4-4 4\"/></svg>'\n\nfunction HubProviderCard(props: {\n descriptor: HubProviderDescriptor\n summary: HubProviderSummaryDto | undefined\n busy: boolean\n toggleError: string | null\n t: HubTranslate\n onOpen(id: HubProviderDescriptor['id']): void\n onToggle(descriptor: HubProviderDescriptor, summary: HubProviderSummaryDto, enabled: boolean): Promise<void>\n}): React.JSX.Element {\n const { descriptor, summary, t } = props\n const enabled = summary?.enabled ?? true\n const annotation = props.toggleError ?? cardAnnotation(summary, descriptor, t)\n const canToggle = descriptor.setEnabled !== null && (summary?.canToggle ?? true)\n\n return <div\n role=\"button\"\n tabIndex={0}\n className=\"dsh-hub-card\"\n data-enabled={enabled}\n aria-label={formatPoolLabel(t('hubCardLabel'), { name: descriptor.name, annotation })}\n onClick={() => props.onOpen(descriptor.id)}\n onKeyDown={(event) => {\n if (event.key !== 'Enter' && event.key !== ' ') return\n if (event.target !== event.currentTarget) return\n event.preventDefault()\n props.onOpen(descriptor.id)\n }}\n >\n <BrandTile id={descriptor.id} />\n <span className=\"dsh-hub-card-copy\">\n <span className=\"dsh-hub-card-name\">{descriptor.name}</span>\n <span className={`dsh-hub-card-note${props.toggleError !== null || summary?.error === true ? ' dsh-hub-note-danger' : ''}`}>\n {annotation}\n </span>\n </span>\n <span className=\"dsh-hub-card-side\">\n {canToggle ? (\n <button\n type=\"button\"\n role=\"switch\"\n aria-checked={enabled}\n aria-label={formatPoolLabel(t(enabled ? 'hubSwitchOff' : 'hubSwitchOn'), { name: descriptor.name })}\n className=\"dsh-hub-switch\"\n disabled={props.busy || summary === undefined}\n onClick={(event) => {\n event.stopPropagation()\n if (summary === undefined) return\n void props.onToggle(descriptor, summary, !enabled)\n }}\n />\n ) : null}\n <span className=\"dsh-hub-chevron\" aria-hidden=\"true\" dangerouslySetInnerHTML={{ __html: CHEVRON_SVG }} />\n </span>\n </div>\n}\n","import { useCallback, useState } from 'react'\nimport type { PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\nimport { NS } from './locales.ts'\nimport { HubOverview } from './hub/HubOverview.tsx'\nimport { hubProviderDescriptor, HUB_PROVIDERS } from './hub/providers.tsx'\nimport type { HubProviderId } from './hub/brand-icons.tsx'\n\ntype Props = PropsRuntime<'settings.section'> & PropsLocale<typeof NS> & {\n onModelChange?: () => void\n}\n\ntype HubView = { view: 'overview' } | { view: 'detail'; id: HubProviderId }\n\nconst STORAGE_KEY = 'dsh-chatgpt-subscription:hub-view'\n\n/**\n * The detail page a user was last on survives a settings-page remount, so a\n * provider toggle deep in a detail page never throws them back to the\n * overview. Session storage, not local: a new browser session starts at the\n * overview, which is the page's whole point.\n */\nfunction readStoredView(): HubView {\n try {\n const raw = sessionStorage.getItem(STORAGE_KEY)\n if (raw === null) return { view: 'overview' }\n const parsed = JSON.parse(raw) as { view?: string; id?: string }\n if (parsed.view !== 'detail' || typeof parsed.id !== 'string') return { view: 'overview' }\n // A provider the registry no longer knows (renamed, removed) falls back\n // to the overview rather than stranding the page on an empty panel.\n return hubProviderDescriptor(parsed.id) === undefined ? { view: 'overview' } : { view: 'detail', id: parsed.id as HubProviderId }\n } catch {\n return { view: 'overview' }\n }\n}\n\nfunction storeView(view: HubView): void {\n try {\n sessionStorage.setItem(STORAGE_KEY, JSON.stringify(view))\n } catch {\n // Storage can be unavailable (private mode); navigation still works.\n }\n}\n\nconst BACK_SVG = '<svg viewBox=\"0 0 16 16\" width=\"14\" height=\"14\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M10 4l-4 4 4 4\"/></svg>'\n\n/**\n * Single settings page hosting every subscription provider. The opening\n * screen is the overview — one card per line with its enable switch and\n * account count — and picking a card replaces it with that line's detail\n * page under a back bar. Only the active view is mounted, mirroring the\n * shell's behavior of mounting just the selected settings page (each\n * provider section refetches its status on mount).\n */\nexport function ProviderHubSection({ t, onModelChange, ...runtime }: Props): React.JSX.Element {\n const [view, setView] = useState<HubView>(readStoredView)\n\n const open = useCallback((id: HubProviderId): void => {\n const next: HubView = { view: 'detail', id }\n storeView(next)\n setView(next)\n }, [])\n\n const back = useCallback((): void => {\n const next: HubView = { view: 'overview' }\n storeView(next)\n setView(next)\n }, [])\n\n if (view.view === 'overview') {\n return <section className=\"dsh-codex-page\" aria-labelledby=\"dsh-hub-title\">\n <header>\n <h2 id=\"dsh-hub-title\" className=\"dsh-codex-title\">{t('hubTitle')}</h2>\n </header>\n {/* The overview's whole job is the cards. A local sign-in belongs to the\n ONE provider whose account pool it would join, so it lives on that\n provider's detail page next to its own rows: an overview that answered\n for three providers at once had to tell users to visit the page they\n were already one click away from. */}\n <HubOverview t={t} onOpen={open} />\n </section>\n }\n\n const descriptor = hubProviderDescriptor(view.id) ?? HUB_PROVIDERS[0]\n return <section className=\"dsh-codex-page\" aria-labelledby=\"dsh-hub-detail-name\">\n <nav className=\"dsh-hub-backbar\">\n <button type=\"button\" className=\"dsh-hub-back\" onClick={back} aria-label={t('hubBack')}>\n <span aria-hidden=\"true\" dangerouslySetInnerHTML={{ __html: BACK_SVG }} />\n {t('hubBack')}\n </button>\n <span className=\"dsh-hub-backbar-name\" id=\"dsh-hub-detail-name\">{descriptor.name}</span>\n </nav>\n <div className=\"dsh-hub-detail\">\n {descriptor.renderDetail({ t, onModelChange, runtime })}\n </div>\n </section>\n}\n","export const NS = 'dsh-chatgpt-subscription' as const\n\nimport { accountPoolEn, accountPoolZh } from './common/account-pool-labels.ts'\n\nexport const zh = {\n // The account-management card is shared with every other provider tab, so its\n // labels live in one place and are translated through this tab's dictionary.\n ...accountPoolZh,\n title: 'ChatGPT',\n hubTitle: '订阅服务',\n intro: '使用 ChatGPT 账号登录,在 DSH 中使用订阅可用的模型。',\n account: '账号',\n signedOut: '尚未登录',\n signedIn: '已登录',\n plan: '套餐',\n accountId: '账号 ID',\n expires: '令牌到期',\n signIn: '使用 ChatGPT 登录',\n signInAgain: '重新登录',\n cancel: '取消登录',\n signOut: '注销',\n refreshToken: '刷新凭据',\n pending: '请在浏览器中完成登录。',\n popupBlocked: '浏览器拦截了登录窗口,请使用下面的链接继续。',\n continueLogin: '打开 ChatGPT 登录页',\n loading: '正在读取状态…',\n connection: '连接',\n testConnection: '测试连接',\n testing: '测试中…',\n latency: '最近延迟',\n selectAll: '全选',\n unselectAll: '全不选',\n models: '可用模型',\n modelsHint: '勾选后模型才会显示在对话页的模型选择列表中;全部取消勾选或关闭上方开关可在列表中隐藏该供应商。',\n proxySettings: '网络代理',\n proxyMode: '代理模式',\n proxyModeHint: 'GPT 与 Antigravity(Gemini)共用此代理设置;支持自动读取系统代理,修改后对后续请求生效。',\n proxyModeAuto: '系统代理(自动检测)',\n proxyModeCustom: '自定义代理',\n proxyModeDirect: '直连(禁用代理)',\n customProxyUrl: '自定义代理地址',\n customProxyUrlHint: '支持 HTTP/HTTPS/SOCKS5 代理地址,例如 http://127.0.0.1:7890',\n customProxyUrlPlaceholder: '例如: http://127.0.0.1:7890',\n saveProxyUrl: '保存代理地址',\n proxyDetected: '检测到系统代理',\n proxyDetectedEffective: '(已自动生效)',\n proxyNoneDetected: '未检测到系统代理,将使用直连',\n proxyDirectHint: '所有网络请求将直接连接,不经过任何代理服务器。',\n enhancements: '增强功能',\n fastMode: '快速模式(1.5x 速度)',\n fastModeHint: '提升 Token 生成速度至约 1.5 倍;将以约 2x–2.5x 速度消耗 Codex 订阅额度。',\n outputVerbosity: '输出详细程度',\n outputVerbosityHint: '控制 Codex 最终回答的详细程度;不影响思考深度。默认值与官方 Codex 客户端一致(低)。',\n verbosityLow: '低(保持回答简洁)',\n verbosityMedium: '中(兼顾细节与简洁)',\n verbosityHigh: '高(在回答中包含更多细节)',\n reasoningSummary: '推理摘要',\n reasoningSummaryHint: '选择 ChatGPT 总结其推理的方式;不影响思考深度。默认值与官方 Codex 客户端一致(不生成摘要,可省额度)。',\n summaryAuto: '自动(让模型选择摘要详细程度)',\n summaryConcise: '简洁(显示简要推理摘要)',\n summaryDetailed: '详细(显示更详细的推理摘要)',\n summaryNone: '无(不显示推理摘要)',\n searchProvider: '搜索来源',\n searchProviderHint: '选择 DSH 联网搜索使用默认来源,或改用当前 ChatGPT 订阅的 Codex 来源(自动走代理隧道)。抓取模式为 auto 时,抓取来源跟随此选择。',\n searchProviderDsh: 'DSH 默认',\n searchProviderCodex: 'ChatGPT(代理隧道)',\n fetchStatus: '抓取来源(只读)',\n fetchStatusHint: '以下内容由 Host 上报,只读展示。',\n fetchConfiguredProvider: '配置的抓取 Provider',\n fetchProviderDshDefault: 'DSH 默认(Host 未固定抓取 provider)',\n switcherState: '抓取选择器状态',\n switcherStateIdle: '空闲(尚未应用选择)',\n switcherStateApplying: '应用中(正在切换 Host 的 web provider)',\n switcherStateApplied: '已应用',\n switcherStateMissing: '未找到可切换的 web 服务',\n switcherStateFailed: '切换失败,请检查 Host 日志',\n fetchMode: '抓取模式',\n fetchModeAuto: 'auto(有可用代理或选了 ChatGPT 搜索时用插件抓取)',\n fetchModePlugin: 'plugin(始终用本插件抓取)',\n fetchModeDsh: 'dsh(保留 DSH 原有抓取来源)',\n fetchMaxBodyChars: '插件正文上限',\n fetchMaxResponseBytes: '插件响应体上限',\n characters: '字符',\n bytes: '字节',\n fetchLimitsInactive: '仅在实际使用插件抓取时生效;走 DSH 原有抓取来源时不适用这两个上限。',\n fetchConfigSource: '模式与上限在插件 Config 中修改(不是本页面偏好),修改后重载插件或重启 DSH 生效。',\n providerDefault: '使用 Provider 默认值',\n contextWindows: '模型上下文窗口',\n contextWindowsHint: '只列出已勾选「可用模型」的条目。默认取模型目录值(GPT-6 系列 384K,最高 872K;其余最高 1M),该值用于 DSH 的压缩与溢出判断,可输入 872K、512K 等容量;改过的模型可单独或一键恢复默认。',\n contextWindow: '上下文窗口',\n contextWindowInvalid: '上下文窗口必须是正整数,且不能超过模型上限(GPT-6 系列为 872K,其余为 1M);可使用 K 或 M 后缀。',\n contextWindowReset: '恢复默认',\n contextWindowResetAll: '全部恢复默认',\n contextWindowResetAllConfirm: '确定把已改过的模型上下文窗口全部恢复为默认值吗?',\n contextWindowsNoneEnabled: '还没有勾选任何模型。在上方「可用模型」里勾选后,这里会出现该模型的上下文窗口设置。',\n saveContextWindow: '保存上下文窗口',\n save: '保存',\n tokens: 'tokens',\n quickQuota: '在输入框旁显示快捷用量',\n quickQuotaHint: '仅在当前会话选中 codex-chatgpt 模型时显示。',\n quota: '用量与限额',\n quotaIntro: '数据来自 ChatGPT Codex 用量服务。页面可见时最多每 60 秒刷新一次。',\n refreshQuota: '刷新用量',\n refreshing: '刷新中…',\n noQuota: '当前套餐未返回可显示的限额窗口。',\n quotaSignedOut: '登录后可查看订阅限额。',\n stale: '显示的是上次成功获取的数据。',\n updated: '更新时间',\n primary: '主要窗口',\n secondary: '次要窗口',\n limitWindow: '额度',\n used: '已使用',\n remaining: '剩余',\n available: '可用',\n unavailable: '不可用',\n unlimited: '无限',\n credits: 'Credits',\n monthlySpend: '月度消费控制',\n resetCredits: '重置次数',\n resetCreditExpires: '到期时间',\n useResetCredit: '使用重置卡',\n usingResetCredit: '使用中…',\n useResetCreditConfirm: '使用后会立即消耗 1 次重置机会,并重置符合条件的 Codex 额度窗口。确定继续吗?',\n resetCreditUsed: '重置卡已使用,用量数据已刷新。',\n spendControlReached: '已触发月度消费控制,新的订阅调用可能被限制。',\n limit: '上限',\n exhausted: '额度已用尽',\n resets: '重置',\n quickQuotaLabel: 'Codex 剩余',\n quickQuotaLoading: '用量…',\n imageToolRunning: '正在生成图片',\n imageToolDone: '已生成图片',\n imageToolFailed: '图片生成失败',\n image: '图片',\n openImage: '打开图片',\n openNamedImage: '打开 {name}',\n imageLoading: '加载图片…',\n imageLoadFailed: '图片加载失败,点击重试',\n imagePreviewClose: '关闭',\n imagePreviewOpenOriginal: '打开原图',\n retry: '重试',\n unknown: '未知',\n // The hub overview: the settings page's opening screen.\n hubBack: '订阅服务',\n hubOverviewHint: '选择供应商以管理账号、模型与配额;右侧开关控制该供应商是否出现在模型列表中。',\n hubAccountCount: '{count} 个账号',\n hubNoAccounts: '暂无账号,点击进入添加',\n hubStateEnabled: '已启用',\n hubStateDisabled: '已停用',\n hubModelsEnabled: '{count} 个模型可用',\n hubModelsEnabledOfTotal: '{count}/{total} 个模型可用',\n hubStatusFailed: '状态读取失败',\n hubSwitchOn: '启用 {name}',\n hubSwitchOff: '停用 {name}',\n hubCardLabel: '{name},{annotation}',\n // The import button that sits beside 登录 in the account pool's login row.\n // Two labels and nothing else: the button says what it does, the row it sits in\n // says where it goes, and the Claude section's own import button is worded the\n // same way because the two are the same decision.\n localCodexLoginImport: '导入本机 Codex CLI 登录',\n localCodexLoginImporting: '导入中…',\n // The account pool's undo for the local sign-in imported just above it. The\n // wording says \"all\" because the host's route clears every imported row at once:\n // a label reading like a per-row action would promise something the pool forbids.\n stopImporting: '停止导入全部本机登录',\n stopImportingLabel: '停止导入全部本机登录(当前 {count} 个)',\n stopImportingBusy: '停止导入中…',\n stopImportingHint: '停止导入只会让本插件忘记本机 CLI 登录的副本;Codex CLI 自己的登录文件不会被删除或修改。账号池不允许逐条删除借来的凭据,所以这里一次会停止全部导入。',\n modelChecklistCount: '已启用 {count}/{total}',\n} as const\n\nexport const en: Record<keyof typeof zh, string> = {\n ...accountPoolEn,\n title: 'ChatGPT',\n hubTitle: 'Subscriptions',\n intro: 'Sign in with ChatGPT to use models available to your subscription in DSH.',\n account: 'Account',\n signedOut: 'Not signed in',\n signedIn: 'Signed in',\n plan: 'Plan',\n accountId: 'Account ID',\n expires: 'Token expires',\n signIn: 'Sign in with ChatGPT',\n signInAgain: 'Sign in again',\n cancel: 'Cancel sign-in',\n signOut: 'Sign out',\n refreshToken: 'Refresh credentials',\n pending: 'Complete sign-in in your browser.',\n popupBlocked: 'The sign-in window was blocked. Use the link below to continue.',\n continueLogin: 'Open ChatGPT sign-in',\n loading: 'Reading status…',\n connection: 'Connection',\n testConnection: 'Test connection',\n testing: 'Testing…',\n latency: 'Last latency',\n selectAll: 'Select all',\n unselectAll: 'Unselect all',\n models: 'Available models',\n modelsHint: 'Checked models appear in the conversation model picker; unchecking all or turning off the switch hides this provider from the picker.',\n proxySettings: 'Network Proxy',\n proxyMode: 'Proxy Mode',\n proxyModeHint: 'GPT and Antigravity (Gemini) share these proxy settings. Supports system proxy detection; changes apply to subsequent requests.',\n proxyModeAuto: 'System Proxy (Auto-detect)',\n proxyModeCustom: 'Custom Proxy',\n proxyModeDirect: 'Direct (No Proxy)',\n customProxyUrl: 'Custom Proxy URL',\n customProxyUrlHint: 'Supports HTTP/HTTPS/SOCKS5 proxy URLs, e.g. http://127.0.0.1:7890',\n customProxyUrlPlaceholder: 'e.g. http://127.0.0.1:7890',\n saveProxyUrl: 'Save Proxy URL',\n proxyDetected: 'Detected system proxy',\n proxyDetectedEffective: ' (active)',\n proxyNoneDetected: 'No system proxy detected; connecting directly',\n proxyDirectHint: 'All requests connect directly without using any proxy server.',\n enhancements: 'Enhancements',\n fastMode: 'Fast mode (1.5x speed)',\n fastModeHint: 'Generates tokens ~1.5x faster; consumes Codex subscription quota at ~2x–2.5x the normal rate.',\n outputVerbosity: 'Output verbosity',\n outputVerbosityHint: 'Controls the detail level of final Codex answers without changing reasoning effort. The default matches the official Codex client (low).',\n verbosityLow: 'Low (keep answers concise)',\n verbosityMedium: 'Medium (balance detail and brevity)',\n verbosityHigh: 'High (include more detail)',\n reasoningSummary: 'Reasoning summary',\n reasoningSummaryHint: 'Controls how ChatGPT summarizes its chain of thought; does not change reasoning depth. The default matches the official Codex client (no summary, which saves quota).',\n summaryAuto: 'Auto (let model determine detail)',\n summaryConcise: 'Concise (brief summary)',\n summaryDetailed: 'Detailed (in-depth summary)',\n summaryNone: 'None (hide reasoning summary)',\n searchProvider: 'Search provider',\n searchProviderHint: 'Choose whether DSH web search uses the default provider or the Codex proxy-backed source from this ChatGPT subscription. Fetch mode \"auto\" follows this choice.',\n searchProviderDsh: 'DSH default',\n searchProviderCodex: 'ChatGPT (Proxy tunnel)',\n fetchStatus: 'Fetch source (read-only)',\n fetchStatusHint: 'Reported by the host. Read-only.',\n fetchConfiguredProvider: 'Configured fetch provider',\n fetchProviderDshDefault: 'DSH default (the host pins no fetch provider)',\n switcherState: 'Fetch switcher state',\n switcherStateIdle: 'Idle (no selection applied yet)',\n switcherStateApplying: 'Applying (host web provider switch in progress)',\n switcherStateApplied: 'Applied',\n switcherStateMissing: 'No web service found to switch',\n switcherStateFailed: 'Switch failed, check the host log',\n fetchMode: 'Fetch mode',\n fetchModeAuto: 'auto (fetches with the plugin when a proxy is available or the ChatGPT search source is selected)',\n fetchModePlugin: 'plugin (always fetch with this plugin)',\n fetchModeDsh: 'dsh (keep the DSH default fetch source)',\n fetchMaxBodyChars: 'Plugin body limit',\n fetchMaxResponseBytes: 'Plugin response limit',\n characters: 'chars',\n bytes: 'bytes',\n fetchLimitsInactive: 'Only applied when the plugin actually fetches; the DSH default fetch source does not use these two limits.',\n fetchConfigSource: 'Mode and limits are changed in the plugin Config, not in these settings; they take effect after a plugin reload or a DSH restart.',\n providerDefault: 'Use provider default',\n contextWindows: 'Model context windows',\n contextWindowsHint: 'Lists the models checked under Available models. Each starts at its catalog value (384K for the GPT-6 family, up to 872K; up to 1M otherwise); DSH uses it for compaction and overflow detection. Values such as 872K and 512K are accepted, and a changed model can be restored one by one or all at once.',\n contextWindow: 'Context window',\n contextWindowInvalid: 'The context window must be a positive integer within the model limit (872K for the GPT-6 family, 1M otherwise). K and M suffixes are accepted.',\n contextWindowReset: 'Restore default',\n contextWindowResetAll: 'Restore all defaults',\n contextWindowResetAllConfirm: 'Restore every changed model context window to its default?',\n contextWindowsNoneEnabled: 'No model is checked yet. Check one under Available models above and its context window setting appears here.',\n saveContextWindow: 'Save context window',\n save: 'Save',\n tokens: 'tokens',\n quickQuota: 'Show quick usage beside the composer',\n quickQuotaHint: 'Shown only when the current session uses a codex-chatgpt model.',\n quota: 'Usage and limits',\n quotaIntro: 'Data comes from the ChatGPT Codex usage service and refreshes at most once per minute while visible.',\n refreshQuota: 'Refresh usage',\n refreshing: 'Refreshing…',\n noQuota: 'Your plan did not return any displayable limit windows.',\n quotaSignedOut: 'Sign in to view subscription limits.',\n stale: 'Showing the last successfully fetched data.',\n updated: 'Updated',\n primary: 'Primary window',\n secondary: 'Secondary window',\n limitWindow: 'limit',\n used: 'used',\n remaining: 'remaining',\n available: 'Available',\n unavailable: 'Unavailable',\n unlimited: 'Unlimited',\n credits: 'Credits',\n monthlySpend: 'Monthly spend control',\n resetCredits: 'Reset credits',\n resetCreditExpires: 'Expires',\n useResetCredit: 'Use reset credit',\n usingResetCredit: 'Using…',\n useResetCreditConfirm: 'This immediately spends one reset credit and resets eligible Codex limit windows. Continue?',\n resetCreditUsed: 'The reset credit was used and usage data was refreshed.',\n spendControlReached: 'Monthly spend control has been reached; new subscription calls may be limited.',\n limit: 'Limit',\n exhausted: 'Quota exhausted',\n resets: 'Resets',\n quickQuotaLabel: 'Codex left',\n quickQuotaLoading: 'Usage…',\n imageToolRunning: 'Generating image',\n imageToolDone: 'Generated image',\n imageToolFailed: 'Image generation failed',\n image: 'Image',\n openImage: 'Open image',\n openNamedImage: 'Open {name}',\n imageLoading: 'Loading image…',\n imageLoadFailed: 'Image failed to load. Click to retry',\n imagePreviewClose: 'Close',\n imagePreviewOpenOriginal: 'Open original',\n retry: 'Retry',\n unknown: 'Unknown',\n // The hub overview: the settings page's opening screen.\n hubBack: 'Subscriptions',\n hubOverviewHint: 'Pick a provider to manage its accounts, models and quota. The switch controls whether it appears in the model picker.',\n hubAccountCount: '{count} accounts',\n hubNoAccounts: 'No accounts yet — open to add one',\n hubStateEnabled: 'Enabled',\n hubStateDisabled: 'Disabled',\n hubModelsEnabled: '{count} models available',\n hubModelsEnabledOfTotal: '{count}/{total} models available',\n hubStatusFailed: 'Status unavailable',\n hubSwitchOn: 'Enable {name}',\n hubSwitchOff: 'Disable {name}',\n hubCardLabel: '{name}, {annotation}',\n // The import button that sits beside 登录 in the account pool's login row.\n // Two labels and nothing else: the button says what it does, the row it sits in\n // says where it goes, and the Claude section's own import button is worded the\n // same way because the two are the same decision.\n localCodexLoginImport: 'Import the local Codex CLI sign-in',\n localCodexLoginImporting: 'Importing…',\n // The account pool's undo for the local sign-in imported just above it. The\n // wording says \"all\" because the host's route clears every imported row at once:\n // a label reading like a per-row action would promise something the pool forbids.\n stopImporting: 'Stop importing all local sign-ins',\n stopImportingLabel: 'Stop importing all local sign-ins ({count} currently imported)',\n stopImportingBusy: 'Stopping the import…',\n stopImportingHint: 'Stopping the import only makes this plugin forget its copy of the local CLI sign-in; the Codex CLI own sign-in file is never deleted or changed. The account pool does not allow deleting a borrowed credential one at a time, so this stops every import at once.',\n modelChecklistCount: '{count}/{total} enabled',\n}\n\nexport type LocaleKey = keyof typeof zh\nexport const dictionaries = { zh, en }\n","/**\n * Shared installer for every stylesheet this plugin injects.\n *\n * The DSH client module system books stylesheet ownership by attribute. When a\n * package's factory materializes it claims every untagged `<style>` in the\n * document for itself (`style:not([data-plugin])` gains that package's id); when\n * a package reloads, is replaced at a new revision, or is pruned from the graph,\n * it removes every tag carrying its id. A sheet injected as a plain\n * `<style id=…>` therefore gets claimed by whichever sibling package\n * materializes next and is then deleted as that sibling's bookkeeping — which is\n * how the whole shared provider design system (`.dsha-*`) disappeared from the\n * settings page while the already-tagged chat-only `…/main` sheet survived.\n *\n * Tagging every sheet with this package's own `data-plugin` and a unique\n * `data-plugin-css` keeps the module system from attributing it to another\n * package, and re-running the installer on every `apply()` restores it after one\n * of our own reloads. The tag is owned by the document: the installer refreshes\n * stale text but never removes the element, so a stale fiber's teardown can\n * never take the styles away.\n */\nexport const PLUGIN_ID = '@eddyskywalker/dsh-chatgpt-subscription'\n\nexport function installPluginStyle(name: string, css: string, legacyId?: string): () => void {\n if (typeof document === 'undefined') return () => undefined\n const pluginCss = `${PLUGIN_ID}/${name}`\n let element = document.querySelector<HTMLStyleElement>(`style[data-plugin-css=\"${pluginCss}\"]`)\n // A bundle predating the ownership tags injected a plain tag; adopt that\n // element instead of stacking a second copy of the same CSS on the page.\n element ??= legacyId === undefined ? null : document.getElementById(legacyId) as HTMLStyleElement | null\n if (element === null) {\n element = document.createElement('style')\n if (legacyId !== undefined) element.id = legacyId\n document.head.appendChild(element)\n }\n element.dataset.plugin = PLUGIN_ID\n element.dataset.pluginCss = pluginCss\n if (element.textContent !== css) element.textContent = css\n return () => undefined\n}\n","import { installPluginStyle } from './common/plugin-style.ts'\n\nconst CSS = `\n.dsh-codex-page{box-sizing:border-box;color:var(--dsw-alias-label-primary);display:flex;flex-direction:column;gap:20px;max-width:780px;min-width:0;padding:2px 0 30px}\n.dsh-codex-page *{box-sizing:border-box}\n.dsh-codex-title{font-size:15px;font-weight:650;line-height:1.4;margin:0 0 5px}\n.dsh-codex-intro,.dsh-codex-muted{color:var(--dsw-alias-label-secondary);font-size:13px;line-height:1.55;margin:0}\n.dsh-codex-group{border-top:0.5px solid var(--dsw-alias-border-l2);min-width:0}\n.dsh-codex-grouphead{align-items:center;display:flex;gap:12px;justify-content:space-between;min-height:48px}\n.dsh-codex-grouphead h3{font-size:14px;font-weight:650;margin:0}\n.dsh-codex-row{align-items:center;border-bottom:0.5px solid var(--dsw-alias-border-l2);display:flex;gap:20px;justify-content:space-between;min-height:44px;padding:8px 0}\n.dsh-codex-label{color:var(--dsw-alias-label-secondary);font-size:13px;flex:0 0 auto}\n.dsh-codex-value{font-size:13px;min-width:0;overflow-wrap:anywhere;text-align:right}\n.dsh-codex-actions{display:flex;flex-wrap:wrap;gap:8px;justify-content:flex-end;padding-top:12px}\n.dsh-codex-button{background:var(--dsw-alias-bg-layer-2);border:0.5px solid var(--dsw-alias-border-l2);border-radius:999px;corner-shape:round;color:var(--dsw-alias-label-primary);cursor:pointer;font:inherit;font-size:13px;line-height:1;padding:8px 13px;white-space:nowrap}\n.dsh-codex-button:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}\n.dsh-codex-button:focus-visible,.dsh-codex-link:focus-visible{outline:2px solid var(--dsw-alias-button-info-fill,#397ee8);outline-offset:2px}\n.dsh-codex-button:disabled{cursor:default;opacity:.5}\n.dsh-codex-button-primary{background:var(--dsw-alias-button-info-fill,#397ee8);border-color:transparent;color:var(--dsw-alias-button-info-label,#fff)}\n.dsh-codex-notice{background:var(--dsw-alias-bg-layer-2);border:0.5px solid var(--dsw-alias-border-l2);border-radius:7px;color:var(--dsw-alias-label-secondary);font-size:12px;line-height:1.55;margin:12px 0 0;padding:10px 12px}\n.dsh-codex-error,.dsh-codex-warning,.dsh-codex-success{font-size:12px;line-height:1.5;margin:8px 0 0}\n.dsh-codex-error{color:var(--dsw-alias-label-danger,#d94b4b)}\n.dsh-codex-warning{color:var(--dsw-alias-label-warning,#c77a18)}\n.dsh-codex-success{color:var(--dsw-alias-label-success,#2e9b62)}\n.dsh-codex-errorbar{align-items:center;background:color-mix(in srgb,var(--dsw-alias-label-danger,#d94b4b) 9%,transparent);border:0.5px solid color-mix(in srgb,var(--dsw-alias-label-danger,#d94b4b) 28%,transparent);border-radius:7px;color:var(--dsw-alias-label-danger,#d94b4b);display:flex;font-size:13px;gap:12px;justify-content:space-between;padding:10px 12px}\n.dsh-codex-link{color:var(--dsw-alias-label-link,#3278d4);display:inline-block;font-size:13px;margin-top:8px}\n.dsh-codex-pref-row{align-items:center;border-bottom:0.5px solid var(--dsw-alias-border-l2);display:flex;gap:16px;justify-content:space-between;min-height:58px;padding:10px 0}\n.dsh-codex-pref-row strong,.dsh-codex-check strong{display:block;font-size:13px;font-weight:600;line-height:1.35}\n.dsh-codex-segments{background:var(--dsw-alias-bg-layer-2);border:0.5px solid var(--dsw-alias-border-l2);border-radius:8px;display:inline-flex;flex-wrap:nowrap;gap:3px;padding:3px}\n.dsh-codex-segments label{cursor:pointer;display:block;margin:0}\n.dsh-codex-segments input{position:absolute;opacity:0;pointer-events:none}\n.dsh-codex-segments span,.dsh-codex-segments button{border:0.5px solid transparent;border-radius:6px;color:var(--dsw-alias-label-secondary);display:block;font:inherit;font-size:12px;font-weight:500;line-height:1.2;padding:6px 12px;transition:all .15s ease;user-select:none;white-space:nowrap}\n.dsh-codex-segments button{background:transparent;cursor:pointer}\n.dsh-codex-segments label:hover span,.dsh-codex-segments button:hover:not(:disabled){color:var(--dsw-alias-label-primary)}\n.dsh-codex-segments input:checked+span,.dsh-codex-segments button.active,.dsh-codex-segments button[aria-pressed=true]{background:color-mix(in srgb,var(--dsw-alias-button-info-fill,#397ee8) 22%,var(--dsw-alias-bg-layer-2));border-color:color-mix(in srgb,var(--dsw-alias-button-info-fill,#397ee8) 60%,var(--dsw-alias-border-l2));color:var(--dsw-alias-label-primary);font-weight:600;box-shadow:0 1px 3px rgba(0,0,0,.15)}\n.dsh-codex-segments input:focus-visible+span,.dsh-codex-segments button:focus-visible{outline:2px solid var(--dsw-alias-button-info-fill,#397ee8);outline-offset:2px}\n.dsh-codex-segments input:disabled+span,.dsh-codex-segments button:disabled{cursor:default;opacity:.5}\n.dsh-codex-select,.dsh-codex-capacity-control input{background:var(--dsw-alias-bg-layer-2);border:0.5px solid var(--dsw-alias-border-l2);border-radius:7px;color:var(--dsw-alias-label-primary);font:inherit;font-size:12px;padding:7px 9px}\n.dsh-codex-select{max-width:210px;min-width:150px}\n.dsh-codex-context-settings{border-bottom:0.5px solid var(--dsw-alias-border-l2);display:grid;gap:10px;padding:12px 0}\n.dsh-codex-context-settings>div>strong{font-size:13px;font-weight:600}\n.dsh-codex-context-row{align-items:center;display:flex;font-size:12px;gap:14px;justify-content:space-between}\n.dsh-codex-proxy-control{align-items:center;display:flex;gap:8px;width:100%}\n.dsh-codex-proxy-control input{background:var(--dsw-alias-bg-layer-2);border:0.5px solid var(--dsw-alias-border-l2);border-radius:7px;color:var(--dsw-alias-label-primary);flex:1;font:inherit;font-family:ui-monospace,SFMono-Regular,Consolas,monospace;font-size:12px;min-width:220px;padding:7px 10px;text-align:left}\n.dsh-codex-proxy-status{align-items:center;color:var(--dsw-alias-label-secondary);display:flex;flex-wrap:wrap;font-size:12px;gap:6px;margin:6px 0 0}\n.dsh-codex-proxy-tag{background:color-mix(in srgb,var(--dsw-alias-button-info-fill,#397ee8) 18%,transparent);border:0.5px solid color-mix(in srgb,var(--dsw-alias-button-info-fill,#397ee8) 45%,transparent);border-radius:4px;color:var(--dsw-alias-label-primary);font-family:ui-monospace,SFMono-Regular,Consolas,monospace;font-size:11px;padding:2px 6px}\n.dsh-codex-capacity-control{align-items:center;display:flex;gap:7px}\n.dsh-codex-capacity-control input{font-family:ui-monospace,SFMono-Regular,Consolas,monospace;text-align:right;width:90px}\n.dsh-codex-capacity-control input[type=number]{width:110px}\n.dsh-codex-capacity-control small{color:var(--dsw-alias-label-tertiary);font-size:11px;width:42px}\n.dsh-codex-context-save{background:var(--dsw-alias-bg-layer-2);border:0.5px solid var(--dsw-alias-border-l2);border-radius:7px;color:var(--dsw-alias-label-primary);cursor:pointer;font:inherit;font-size:12px;line-height:1;padding:8px 10px;white-space:nowrap}\n.dsh-codex-context-save:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}\n.dsh-codex-context-save:focus-visible{outline:2px solid var(--dsw-alias-button-info-fill,#397ee8);outline-offset:2px}\n.dsh-codex-context-save:disabled{cursor:default;opacity:.45}\n.dsh-codex-check{align-items:flex-start;border-bottom:0.5px solid var(--dsw-alias-border-l2);cursor:pointer;display:flex;gap:10px;padding:12px 0}\n.dsh-codex-check input{flex:none;margin-top:2px}\n.dsh-codex-check small{color:var(--dsw-alias-label-secondary);display:block;font-size:12px;line-height:1.45;margin-top:2px}\n.dsh-codex-quota-card{background:var(--dsw-alias-bg-layer-2);border:0.5px solid var(--dsw-alias-border-l2);border-radius:8px;margin-top:12px;padding:12px}\n.dsh-codex-quota-title{align-items:center;display:flex;font-size:13px;gap:8px;justify-content:space-between}\n.dsh-codex-quota-title span{color:var(--dsw-alias-label-tertiary);font-size:11px;text-transform:uppercase}\n.dsh-codex-quota-fact{align-items:flex-start;border-bottom:0.5px solid var(--dsw-alias-border-l2);display:flex;font-size:12px;gap:12px;justify-content:space-between;line-height:1.45;padding:10px 0}\n.dsh-codex-quota-fact span{color:var(--dsw-alias-label-secondary);flex:none}\n.dsh-codex-quota-fact strong{font-weight:600;min-width:0;overflow-wrap:anywhere;text-align:right}\n.dsh-codex-reset-credits{align-items:center;border-bottom:0.5px solid var(--dsw-alias-border-l2);display:flex;gap:16px;justify-content:space-between;padding:10px 0}\n.dsh-codex-reset-credits-info{display:grid;font-size:12px;gap:2px;grid-template-columns:auto auto}\n.dsh-codex-reset-credits-info>span{color:var(--dsw-alias-label-secondary)}\n.dsh-codex-reset-credits-info>strong{font-weight:650;text-align:right}\n.dsh-codex-reset-credits-info>small{color:var(--dsw-alias-label-tertiary);font-size:11px;grid-column:1/-1}\n.dsh-codex-meter-wrap{margin-top:13px}\n.dsh-codex-meter-label,.dsh-codex-meter-meta{display:flex;gap:10px;justify-content:space-between}\n.dsh-codex-meter-label{font-size:12px;margin-bottom:6px}\n.dsh-codex-meter-meta{color:var(--dsw-alias-label-tertiary);font-size:11px;line-height:1.45;margin-top:6px}\n.dsh-codex-meter{background:var(--dsw-alias-bg-layer-1,rgba(127,127,127,.15));border-radius:999px;corner-shape:round;height:7px;overflow:hidden;width:100%}\n.dsh-codex-meter>span{background:var(--dsw-alias-button-info-fill,#397ee8);border-radius:inherit;display:block;height:100%;max-width:100%;min-width:0;transition:width .25s ease}\n.dsh-codex-meter-warning>span{background:var(--dsw-alias-label-warning,#d58a24)}\n.dsh-codex-meter-danger>span{background:var(--dsw-alias-label-danger,#d94b4b)}\n.dsh-codex-empty{border:0.5px dashed var(--dsw-alias-border-l2);border-radius:7px;color:var(--dsw-alias-label-tertiary);font-size:12px;margin:12px 0 0;padding:16px;text-align:center}\n.dsh-codex-timestamp{color:var(--dsw-alias-label-tertiary);font-size:11px;margin:10px 0 0;text-align:right}\n.dsh-codex-skeleton{display:grid;gap:9px;padding-top:10px}\n.dsh-codex-skeleton span{animation:dsh-codex-pulse 1.4s ease-in-out infinite;background:var(--dsw-alias-bg-layer-2);border-radius:5px;height:42px}\n.dsh-codex-skeleton span:nth-child(2){animation-delay:.12s}.dsh-codex-skeleton span:nth-child(3){animation-delay:.24s}\n.dsh-codex-sr{height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px;clip:rect(0 0 0 0);white-space:nowrap}\n.dsh-codex-composer-quota{align-items:center;background:var(--dsw-alias-bg-layer-2);border:0.5px solid var(--dsw-alias-border-l2);border-radius:999px;corner-shape:round;color:var(--dsw-alias-label-secondary);display:inline-flex;font-size:11px;gap:6px;height:28px;line-height:1;max-width:160px;padding:0 9px;white-space:nowrap}\n.dsh-codex-composer-quota strong{color:var(--dsw-alias-label-primary);font-size:11px;font-weight:650}\n.dsh-codex-composer-quota[data-level=warning] strong{color:var(--dsw-alias-label-warning,#d58a24)}\n.dsh-codex-composer-quota[data-level=danger] strong{color:var(--dsw-alias-label-danger,#d94b4b)}\n.dsh-codex-image-tool{border:0.5px solid var(--dsw-alias-border-l2);border-radius:8px;display:flex;flex-direction:column;gap:8px;margin:4px 0 4px 4px;max-width:520px;padding:10px 12px}\n.dsh-codex-image-tool-head{align-items:center;display:flex;font-size:13px;gap:8px;min-width:0}\n.dsh-codex-image-dot{background:var(--dsw-alias-button-info-fill,#397ee8);border-radius:50%;corner-shape:round;display:inline-block;flex:none;height:8px;width:8px}\n.dsh-codex-image-tool[data-state=error] .dsh-codex-image-dot{background:var(--dsw-alias-label-danger,#d94b4b)}\n.dsh-codex-image-title{font-weight:600}\n.dsh-codex-image-summary{color:var(--dsw-alias-label-tertiary);min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n.dsh-codex-image-grid{display:flex;flex-wrap:wrap;gap:8px}\n.dsh-codex-image-preview{background:var(--dsw-alias-bg-layer-2);border:0.5px solid var(--dsw-alias-border-l2);border-radius:8px;display:block;max-height:260px;max-width:min(100%,360px);object-fit:contain}\n.dsh-codex-image-loading,.dsh-codex-image-failed{border:0.5px dashed var(--dsw-alias-border-l2);border-radius:8px;color:var(--dsw-alias-label-tertiary);display:inline-flex;font-size:12px;line-height:1.4;padding:18px 20px}\n.dsh-codex-image-failed{color:var(--dsw-alias-label-danger,#d94b4b)}\n@keyframes dsh-codex-pulse{0%,100%{opacity:.45}50%{opacity:.85}}\n@media(max-width:560px){.dsh-codex-row,.dsh-codex-pref-row,.dsh-codex-quota-fact,.dsh-codex-reset-credits{align-items:flex-start;flex-direction:column;gap:3px}.dsh-codex-value,.dsh-codex-quota-fact strong{text-align:left}.dsh-codex-actions{justify-content:flex-start}.dsh-codex-grouphead{align-items:flex-start;flex-direction:column;gap:0;padding:12px 0}.dsh-codex-meter-meta{align-items:flex-start;flex-direction:column;gap:2px}.dsh-codex-errorbar{align-items:flex-start;flex-direction:column}.dsh-codex-segments{width:100%}.dsh-codex-select{max-width:none;width:100%}.dsh-codex-context-row{align-items:flex-start;flex-direction:column;gap:5px}.dsh-codex-segments label{flex:1}.dsh-codex-segments span{text-align:center}.dsh-codex-image-tool{max-width:100%;margin-left:0}}\n@media(prefers-reduced-motion:reduce){.dsh-codex-meter>span{transition:none}.dsh-codex-skeleton span{animation:none}}\n`\n\n/**\n * Install the ChatGPT tab's stylesheet as a document-owned, never-removed\n * `<style>` element.\n *\n * The other client stylesheets this plugin installs are additive: their\n * installers no-op when the element already exists and their disposers do\n * nothing, so a restart can never take the styles away. This one used to\n * create *and remove* its element, and the dedupe handoff was racy: on a\n * plugin fiber restart (config change, dependency reload, HMR) the new fiber\n * ran `apply()` before the old fiber's async unload removed the element —\n * dedupe saw the old tag, returned a no-op disposer, and the old unload then\n * deleted the only copy. Every later restart kept returning the no-op, so the\n * stylesheet never came back and the settings page rendered unstyled.\n *\n * Fix: treat the tag as owned by the document rather than by one fiber —\n * create it when missing, refresh `textContent` when a rebuilt bundle ships\n * different CSS (HMR), and return a no-op disposer unconditionally, matching\n * the additive installers.\n *\n * Every other sheet this plugin injects now goes through the same installer\n * (`installPluginStyle`), which additionally stamps the ownership attributes\n * the client module system needs so the tag cannot be claimed by, and later\n * removed with, some other package.\n */\nexport function installStyles(): () => void {\n return installPluginStyle('main', CSS)\n}\n","/**\n * Styles for the subscription hub: the overview's provider cards, the detail\n * page's back bar, and the provider switch. Installed through the shared\n * installer so the module system never claims the sheet (see\n * common/plugin-style.ts). Colors ride DSH theme tokens, so dark mode needs\n * no branch of its own.\n */\nimport { installPluginStyle } from '../common/plugin-style.ts'\n\nconst CSS = `\n.dsh-hub-overview{display:flex;flex-direction:column;min-width:0}\n.dsh-hub-hint{color:var(--dsw-alias-label-secondary,#5d5c52);font-size:13px;line-height:1.55;margin:0 0 14px}\n.dsh-hub-cards{border-top:0.5px solid var(--dsw-alias-border-l2,#eceadf)}\n.dsh-hub-card{align-items:center;background:transparent;border:none;border-bottom:0.5px solid var(--dsw-alias-border-l2,#eceadf);color:var(--dsw-alias-label-primary,#141413);cursor:pointer;display:flex;gap:14px;font:inherit;min-height:68px;padding:12px 6px;text-align:left;width:100%}\n.dsh-hub-card:hover{background:var(--dsw-alias-interactive-bg-hover,rgba(0,0,0,.04))}\n.dsh-hub-card:focus-visible{outline:2px solid var(--dsw-alias-button-info-fill,#397ee8);outline-offset:-2px}\n.dsh-hub-card[data-enabled=false] .dsh-hub-card-name,.dsh-hub-card[data-enabled=false] .dsh-hub-card-note{opacity:.55}\n.dsh-hub-card-copy{display:flex;flex:1;flex-direction:column;gap:3px;min-width:0}\n.dsh-hub-card-name{font-size:14px;font-weight:600;line-height:1.3}\n.dsh-hub-card-note{color:var(--dsw-alias-label-tertiary,#8f8d84);font-size:12px;line-height:1.4}\n.dsh-hub-card-note.dsh-hub-note-danger{color:var(--dsw-alias-label-danger,#d94b4b)}\n.dsh-hub-card-side{align-items:center;display:flex;flex:none;gap:10px}\n.dsh-hub-chevron{color:var(--dsw-alias-label-caption,#a6a094);display:inline-flex;flex:none}\n.dsh-hub-brand-tile{align-items:center;background:color-mix(in srgb,var(--dsh-hub-brand,#888) 10%,transparent);border-radius:10px;display:inline-flex;flex:none;justify-content:center;overflow:hidden}\n.dsh-hub-brand-tile>svg{display:block}\n.dsh-hub-brand-mono{font-family:ui-monospace,SFMono-Regular,Consolas,monospace;font-size:15px;font-weight:700;line-height:1}\n.dsh-hub-switch{background:var(--dsw-alias-bg-layer-2,#f2f1ea);border:0.5px solid var(--dsw-alias-border-l2,#e3e1d5);border-radius:999px;box-sizing:border-box;cursor:pointer;flex:none;height:24px;padding:2px;position:relative;transition:background .15s ease,border-color .15s ease;width:44px}\n.dsh-hub-switch::after{background:var(--dsw-alias-bg-layer-1,#fff);border-radius:50%;box-shadow:0 1px 3px rgba(0,0,0,.28);content:\"\";display:block;height:19px;transition:transform .15s ease;width:19px}\n.dsh-hub-switch[aria-checked=true]{background:var(--dsw-alias-button-info-fill,#397ee8);border-color:transparent}\n.dsh-hub-switch[aria-checked=true]::after{transform:translateX(20px)}\n.dsh-hub-switch:disabled{cursor:default;opacity:.5}\n.dsh-hub-switch:focus-visible{outline:2px solid var(--dsw-alias-button-info-fill,#397ee8);outline-offset:2px}\n.dsh-hub-skeleton{border-bottom:0.5px solid var(--dsw-alias-border-l2,#eceadf);display:flex;gap:14px;min-height:68px;padding:12px 6px;align-items:center}\n.dsh-hub-skeleton i{background:var(--dsw-alias-bg-layer-2,#f2f1ea);border-radius:10px;display:block;height:40px;width:40px}\n.dsh-hub-skeleton span{background:var(--dsw-alias-bg-layer-2,#f2f1ea);border-radius:5px;display:block;height:12px}\n.dsh-hub-skeleton .dsh-hub-skel-name{width:120px;margin-bottom:6px}\n.dsh-hub-skeleton .dsh-hub-skel-note{width:180px;height:10px}\n.dsh-hub-backbar{align-items:center;display:flex;gap:10px;margin-bottom:14px;min-height:32px}\n.dsh-hub-back{align-items:center;background:transparent;border:none;border-radius:6px;color:var(--dsw-alias-label-secondary,#5d5c52);cursor:pointer;display:inline-flex;font:inherit;font-size:13px;font-weight:550;gap:2px;padding:5px 8px 5px 2px}\n.dsh-hub-back:hover{background:var(--dsw-alias-interactive-bg-hover,rgba(0,0,0,.04));color:var(--dsw-alias-label-primary,#141413)}\n.dsh-hub-back:focus-visible{outline:2px solid var(--dsw-alias-button-info-fill,#397ee8);outline-offset:2px}\n.dsh-hub-back svg{display:block}\n.dsh-hub-backbar-name{color:var(--dsw-alias-label-tertiary,#8f8d84);font-size:13px;font-weight:600}\n/* In the hub's detail page the back bar already names the provider, so the\n section's own page-level title would read as a duplicate. The intro line\n under it stays — it describes the line, not the location. Only ChatGPT's\n section renders such a header; the other seven begin with their content. */\n.dsh-hub-detail .dsha-page>header .dsh-codex-title{display:none}\n.dsh-hub-detail .dsha-page>header{margin-bottom:4px}\n`\n\nexport function installHubStyles(): void {\n installPluginStyle('hub', CSS)\n}\n","/**\n * Styles for the shared ModelChecklist (see ModelChecklist.tsx). Row metrics\n * and hover follow the claude-style model picker so the settings list and the\n * conversation picker read as one surface.\n */\nimport { installPluginStyle } from './plugin-style.ts'\n\nconst CSS = `\n.dsh-mcl{display:flex;flex-direction:column;min-width:0;padding:4px 0 2px}\n.dsh-mcl-head{align-items:center;display:flex;justify-content:space-between;min-height:28px;padding:2px 2px 6px}\n.dsh-mcl-count{color:var(--dsw-alias-label-caption,#a6a094);font-size:11px;letter-spacing:.02em}\n.dsh-mcl-head-actions{display:inline-flex;gap:4px}\n.dsh-mcl-action{background:transparent;border:none;border-radius:5px;color:var(--dsw-alias-label-link,#3278d4);cursor:pointer;font:inherit;font-size:12px;padding:3px 7px}\n.dsh-mcl-action:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover,rgba(0,0,0,.05))}\n.dsh-mcl-action:disabled{cursor:default;opacity:.45}\n.dsh-mcl-action:focus-visible{outline:2px solid var(--dsw-alias-button-info-fill,#397ee8);outline-offset:2px}\n.dsh-mcl-list{display:flex;flex-direction:column;gap:1px}\n.dsh-mcl-option{align-items:center;background:transparent;border:none;border-radius:6px;color:var(--dsw-alias-label-primary,#141413);cursor:pointer;display:flex;font:inherit;gap:9px;min-height:34px;padding:3px 8px;text-align:left;width:100%}\n.dsh-mcl-option:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover,rgba(0,0,0,.06))}\n.dsh-mcl-option:disabled{cursor:default;opacity:.55}\n.dsh-mcl-option:focus-visible{outline:2px solid var(--dsw-alias-button-info-fill,#397ee8);outline-offset:-2px}\n.dsh-mcl-option>svg{flex:none}\n.dsh-mcl-copy{display:flex;flex:1;flex-direction:column;gap:1px;min-width:0}\n.dsh-mcl-name{font-size:13px;font-weight:500;line-height:16px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n.dsh-mcl-hint{color:var(--dsw-alias-label-tertiary,#8f8d84);font-size:11px;line-height:14px}\n.dsh-mcl-option[data-enabled=false] .dsh-mcl-name,.dsh-mcl-option[data-enabled=false] .dsh-mcl-hint{opacity:.6}\n.dsh-mcl-check{align-items:center;background:var(--dsw-alias-bg-layer-2,#f2f1ea);border:0.5px solid var(--dsw-alias-border-l1,#e8e6dc);border-radius:50%;color:transparent;display:inline-flex;flex:none;height:18px;justify-content:center;transition:background .12s ease,border-color .12s ease,color .12s ease;width:18px}\n.dsh-mcl-option[aria-checked=true] .dsh-mcl-check{background:var(--dsw-alias-button-info-fill,#397ee8);border-color:transparent;color:var(--dsw-alias-button-info-label,#fff)}\n.dsh-mcl-option:hover:not(:disabled) .dsh-mcl-check{border-color:var(--dsw-alias-button-info-fill,#397ee8)}\n`\n\nexport function installModelChecklistStyles(): void {\n installPluginStyle('model-checklist', CSS)\n}\n","import { installPluginStyle } from '../common/plugin-style.ts'\n\nexport const STYLE_ID = 'dsh-antigravity-settings-style'\n\nexport function installAntigravityStyles(): void {\n installPluginStyle('antigravity', `\n.dsha-page{box-sizing:border-box;color:var(--dsw-alias-label-primary);display:flex;flex-direction:column;gap:20px;max-width:780px;min-width:0;padding:2px 0 30px}\n.dsha-page *{box-sizing:border-box}\n.dsha-group{border-top:0.5px solid var(--dsw-alias-border-l2);min-width:0}\n.dsha-group:first-of-type{border-top:0}\n.dsha-grouphead{align-items:center;display:flex;gap:12px;justify-content:space-between;min-height:48px}\n.dsha-grouphead h3{font-size:14px;font-weight:650;margin:0;color:var(--dsw-alias-label-primary)}\n.dsha-row{align-items:center;border-bottom:0.5px solid var(--dsw-alias-border-l2);display:flex;gap:20px;justify-content:space-between;min-height:44px;padding:8px 0}\n.dsha-label{color:var(--dsw-alias-label-secondary);font-size:13px;flex:0 0 auto}\n.dsha-value{font-size:13px;min-width:0;overflow-wrap:anywhere;text-align:right;color:var(--dsw-alias-label-primary)}\n.dsha-actions{display:flex;flex-wrap:wrap;gap:8px;justify-content:flex-end;padding-top:12px}\n.dsha-btn{background:var(--dsw-alias-bg-layer-2);border:0.5px solid var(--dsw-alias-border-l2);border-radius:999px;corner-shape:round;color:var(--dsw-alias-label-primary);cursor:pointer;font:inherit;font-size:13px;line-height:1;padding:8px 13px;white-space:nowrap}\n.dsha-btn:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}\n.dsha-btn:disabled{cursor:default;opacity:.5}\n.dsha-btn-primary{background:var(--dsw-alias-button-info-fill,#397ee8);border-color:transparent;color:var(--dsw-alias-button-info-label,#fff)}\n.dsha-btn-primary:hover:not(:disabled){opacity:.9}\n.dsha-notice{background:var(--dsw-alias-bg-layer-2);border:0.5px solid var(--dsw-alias-border-l2);border-radius:7px;color:var(--dsw-alias-label-secondary);font-size:12px;line-height:1.55;margin:12px 0 0;padding:10px 12px}\n.dsha-muted{color:var(--dsw-alias-label-secondary);font-size:13px;line-height:1.55;margin:0}\n.dsha-models-hint{padding-top:10px}\n.dsha-pref-row{align-items:center;border-bottom:0.5px solid var(--dsw-alias-border-l2);display:flex;gap:16px;justify-content:space-between;min-height:58px;padding:10px 0}\n.dsha-pref-row strong{display:block;font-size:13px;font-weight:600;line-height:1.35;color:var(--dsw-alias-label-primary)}\n.dsha-select{background:var(--dsw-alias-bg-layer-2);border:0.5px solid var(--dsw-alias-border-l2);border-radius:7px;color:var(--dsw-alias-label-primary);font:inherit;font-size:12px;padding:7px 9px;max-width:220px;min-width:160px}\n.dsha-context-settings{border-bottom:0.5px solid var(--dsw-alias-border-l2);display:grid;gap:10px;padding:12px 0}\n.dsha-context-settings>div>strong{font-size:13px;font-weight:600;color:var(--dsw-alias-label-primary)}\n.dsha-context-row{align-items:center;display:flex;font-size:12px;gap:14px;justify-content:space-between}\n.dsha-capacity-control{align-items:center;display:flex;gap:7px}\n.dsha-capacity-control input{background:var(--dsw-alias-bg-layer-2);border:0.5px solid var(--dsw-alias-border-l2);border-radius:7px;color:var(--dsw-alias-label-primary);font:inherit;font-family:ui-monospace,SFMono-Regular,Consolas,monospace;font-size:12px;padding:7px 9px;text-align:right;width:90px}\n.dsha-capacity-control small{color:var(--dsw-alias-label-tertiary);font-size:11px;width:42px}\n.dsha-context-save{background:var(--dsw-alias-bg-layer-2);border:0.5px solid var(--dsw-alias-border-l2);border-radius:7px;color:var(--dsw-alias-label-primary);cursor:pointer;font:inherit;font-size:12px;line-height:1;padding:8px 10px;white-space:nowrap}\n.dsha-context-save:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}\n.dsha-context-save:disabled{cursor:default;opacity:.45}\n.dsha-context-reset{color:var(--dsw-alias-label-secondary)}\n.dsha-context-reset:hover:not(:disabled){color:var(--dsw-alias-label-primary)}\n.dsha-quota-card{background:var(--dsw-alias-bg-layer-2);border:0.5px solid var(--dsw-alias-border-l2);border-radius:8px;margin-top:12px;padding:12px}\n.dsha-quota-title{align-items:center;display:flex;font-size:13px;gap:8px;justify-content:space-between;color:var(--dsw-alias-label-primary);font-weight:650}\n.dsha-quota-title span{color:var(--dsw-alias-label-tertiary);font-size:11px;text-transform:uppercase}\n.dsha-meter-wrap{margin-top:13px}\n.dsha-meter-label,.dsha-meter-meta{display:flex;gap:10px;justify-content:space-between}\n.dsha-meter-label{font-size:12px;margin-bottom:6px;color:var(--dsw-alias-label-primary)}\n.dsha-meter-meta{color:var(--dsw-alias-label-tertiary);font-size:11px;line-height:1.45;margin-top:6px}\n.dsha-meter{background:var(--dsw-alias-bg-layer-1,rgba(127,127,127,.15));border-radius:999px;corner-shape:round;height:7px;overflow:hidden;width:100%}\n.dsha-meter>span{background:var(--dsw-alias-button-info-fill,#397ee8);border-radius:inherit;display:block;height:100%;max-width:100%;min-width:0;transition:width .25s ease}\n.dsha-meter-green>span{background:var(--dsw-alias-label-success,#10b981)}\n.dsha-meter-cyan>span{background:#06b6d4}\n.dsha-timestamp{color:var(--dsw-alias-label-tertiary);font-size:11px;margin:10px 0 0;text-align:right}\n.dsha-mini-btn{border:0;background:transparent;color:var(--dsw-alias-label-link,#397ee8);font-size:12px;line-height:18px;cursor:pointer;padding:0;margin-left:8px}\n.dsha-mini-btn:hover{text-decoration:underline}\n.dsha-empty{border:0.5px dashed var(--dsw-alias-border-l2);border-radius:7px;color:var(--dsw-alias-label-tertiary);font-size:12px;margin:12px 0 0;padding:16px;text-align:center}\n.dsha-error{color:var(--dsw-alias-label-danger,#d94b4b);font-size:12px;margin:8px 0 0}\n.dsha-composer-quota{align-items:center;background:var(--dsw-alias-bg-layer-2);border:0.5px solid var(--dsw-alias-border-l2);border-radius:999px;corner-shape:round;color:var(--dsw-alias-label-secondary);cursor:pointer;display:inline-flex;font-size:11px;gap:6px;height:28px;line-height:1;max-width:160px;padding:0 9px;white-space:nowrap;user-select:none;transition:all .15s ease}\n.dsha-composer-quota:hover{background:var(--dsw-alias-interactive-bg-hover);border-color:var(--dsw-alias-border-l1,var(--dsw-alias-border-l2))}\n.dsha-composer-quota strong{color:var(--dsw-alias-label-primary);font-size:11px;font-weight:650}\n.dsha-composer-quota[data-level=warning] strong{color:var(--dsw-alias-label-warning,#d58a24)}\n.dsha-composer-quota[data-level=danger] strong{color:var(--dsw-alias-label-danger,#d94b4b)}\n.dsha-accounts-list{display:flex;flex-direction:column;gap:10px;margin-top:10px}\n.dsha-account-card{background:var(--dsw-alias-bg-layer-2);border:0.5px solid var(--dsw-alias-border-l2);border-radius:8px;padding:12px 14px;display:flex;flex-direction:column;gap:8px;transition:border-color .15s ease}\n.dsha-account-card.active{border-color:color-mix(in srgb,var(--dsw-alias-button-info-fill,#397ee8) 60%,var(--dsw-alias-border-l2))}\n.dsha-account-header{display:flex;align-items:center;justify-content:space-between;gap:8px}\n.dsha-account-identity{display:flex;align-items:center;gap:8px;min-width:0}\n.dsha-account-title{font-size:13px;font-weight:600;color:var(--dsw-alias-label-primary);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n.dsha-badges{display:flex;align-items:center;gap:6px}\n.dsha-badge{font-size:11px;line-height:1;padding:3px 7px;border-radius:4px;font-weight:550;white-space:nowrap}\n.dsha-badge.primary{background:color-mix(in srgb,var(--dsw-alias-button-info-fill,#397ee8) 18%,var(--dsw-alias-bg-layer-1));color:var(--dsw-alias-button-info-fill,#397ee8);border:0.5px solid color-mix(in srgb,var(--dsw-alias-button-info-fill,#397ee8) 40%,transparent)}\n.dsha-badge.active{background:color-mix(in srgb,var(--dsw-alias-label-success,#10b981) 18%,var(--dsw-alias-bg-layer-1));color:var(--dsw-alias-label-success,#10b981);border:0.5px solid color-mix(in srgb,var(--dsw-alias-label-success,#10b981) 40%,transparent)}\n.dsha-badge.cooldown{background:color-mix(in srgb,var(--dsw-alias-label-warning,#d58a24) 18%,var(--dsw-alias-bg-layer-1));color:var(--dsw-alias-label-warning,#d58a24);border:0.5px solid color-mix(in srgb,var(--dsw-alias-label-warning,#d58a24) 40%,transparent)}\n.dsha-account-details{display:flex;flex-wrap:wrap;gap:14px;font-size:12px;color:var(--dsw-alias-label-secondary)}\n.dsha-account-actions{display:flex;flex-wrap:wrap;gap:6px;margin-top:2px}\n.dsha-account-actions .dsha-btn{padding:5px 10px;font-size:12px}\n`, STYLE_ID)\n}\n","import { installPluginStyle } from './plugin-style.ts'\n\nexport const POOL_STYLE_ID = 'dsh-provider-pool-style'\n\n/**\n * Styles the shared account-pool card adds on top of the existing provider\n * stylesheets: the badge variants no single provider tab owned before.\n *\n * Additive on purpose — the shared `.dsha-*` block and each provider's own\n * tweaks keep living in their own modules, in the order the client installs\n * them, so nothing that already rendered changes appearance.\n */\nexport function installPoolStyles(): void {\n installPluginStyle('pool', `\n.dsha-badge.danger{background:color-mix(in srgb,var(--dsw-alias-label-danger,#d94b4b) 18%,var(--dsw-alias-bg-layer-1));color:var(--dsw-alias-label-danger,#d94b4b);border:0.5px solid color-mix(in srgb,var(--dsw-alias-label-danger,#d94b4b) 40%,transparent)}\n.dsha-account-card .dsha-btn.danger{color:var(--dsw-alias-label-danger,#d94b4b)}\n/* Quota inside one account row. It follows the account, so it sits with the\n account's identity, badges and timestamps rather than in a page-level block\n that could only ever describe whichever account was active when it was read. */\n.dsha-account-quota{display:flex;flex-direction:column;gap:5px;margin-top:9px}\n.dsha-account-quota-head{align-items:baseline;color:var(--dsw-alias-label-secondary);display:flex;font-size:11px;font-weight:600;gap:8px;letter-spacing:.02em}\n.dsha-account-quota-head em{color:var(--dsw-alias-label-tertiary);font-style:normal;font-weight:400}\n.dsha-account-quota-empty{color:var(--dsw-alias-label-tertiary);font-size:12px}\n.dsha-account-quota-row{align-items:center;display:flex;font-size:12px;gap:8px}\n.dsha-account-quota-name{color:var(--dsw-alias-label-secondary);flex:none;max-width:38%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n/* The track is drawn even when nothing is used: an empty bar nobody can see\n leaves the row reading as a stray label next to a number. */\n.dsha-account-quota-track{background:color-mix(in srgb,var(--dsw-alias-label-tertiary,#8a8a8a) 16%,transparent);border-radius:999px;box-shadow:inset 0 0 0 0.5px var(--dsw-alias-border-l2);flex:1;height:6px;min-width:56px;overflow:hidden}\n.dsha-account-quota-fill{background:var(--dsw-alias-button-info-fill,#397ee8);border-radius:999px;display:block;height:100%;min-width:2px;transition:width .2s ease}\n.dsha-account-quota-row[data-level=warning] .dsha-account-quota-fill{background:var(--dsw-alias-label-warning,#d9913b)}\n.dsha-account-quota-row[data-level=danger] .dsha-account-quota-fill{background:var(--dsw-alias-label-danger,#d94b4b)}\n.dsha-account-quota-value{color:var(--dsw-alias-label-primary);flex:none;font-variant-numeric:tabular-nums;min-width:40px;text-align:right}\n.dsha-account-quota-meta{color:var(--dsw-alias-label-tertiary);flex:none;font-size:11px;font-variant-numeric:tabular-nums}\n@media(max-width:560px){.dsha-account-quota-meta{display:none}}\n`, POOL_STYLE_ID)\n}\n","/**\n * The composer badge every subscription line shows beside the input.\n *\n * Six of these were near-identical copies: the same mount guard, the same 60 s\n * poll that only ticks while the tab is visible, the same \"inert unless the\n * conversation is on this provider\" rule, the same markup. What differed was the\n * part worth reading — how each line picks its most meaningful number — and that\n * is the only thing a line still supplies.\n *\n * Two details this shared shape depends on:\n *\n * - the callbacks are held in refs. Every caller hands them over as an inline\n * arrow, and a callback in the dependency array would restart the interval —\n * and refetch — on every render. The copies this replaced were only safe\n * because each was rendered with a stable prop, which is a property of the\n * call site rather than of the badge;\n * - `authenticated` is part of the status contract rather than a predicate a\n * line could forget, so a signed-out line can never leave a stale badge up.\n */\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react'\nimport type { ModelDirectoryState } from '@deepseek-ai/dsh-client-ui-model-selection/client'\nimport type { SnapshotStore } from '../store.ts'\nimport { useStore } from './use-store.ts'\n\nexport interface ComposerQuotaFacts {\n /** The number the badge shows, already formatted. */\n text: string\n /** What the hover and the screen reader say. */\n tooltip: string\n level: 'normal' | 'warning' | 'danger'\n}\n\n/** The shared grading: 5% or less is critical, 20% or less warns. */\nexport function quotaLevel(remainingPercent: number): ComposerQuotaFacts['level'] {\n return remainingPercent <= 5 ? 'danger' : remainingPercent <= 20 ? 'warning' : 'normal'\n}\n\nexport interface ComposerQuotaBadgeProps<Status extends { authenticated: boolean }> {\n directory: SnapshotStore<ModelDirectoryState>\n loadModelDirectory(): void\n /** The provider id this badge speaks for; it renders for no other. */\n providerId: string\n /** One status read; `true` asks the host for a forced refresh. */\n readStatus(refresh: boolean): Promise<Status>\n /**\n * The line's own number picker; null means there is nothing to show.\n *\n * `modelId` is the conversation's selected model, which one line needs: its\n * allowance is reported per model group, so the number to show depends on\n * which group that model belongs to.\n */\n selectFacts(status: Status | null, modelId: string | undefined): ComposerQuotaFacts | null\n /** Label in front of the number, from the line's own dictionary. */\n label: string\n}\n\nexport function ComposerQuotaBadge<Status extends { authenticated: boolean }>(\n props: ComposerQuotaBadgeProps<Status>,\n): React.JSX.Element | null {\n const { directory, loadModelDirectory, providerId, label } = props\n const modelState = useStore(directory)\n const [status, setStatus] = useState<Status | null>(null)\n const [loading, setLoading] = useState(false)\n const mountedRef = useRef(false)\n // See the header: identity churn in these two must not restart the poll.\n const readRef = useRef(props.readStatus)\n const selectRef = useRef(props.selectFacts)\n readRef.current = props.readStatus\n selectRef.current = props.selectFacts\n\n const selected = modelState.current\n const isSelected = selected?.provider === providerId\n\n useEffect(() => {\n loadModelDirectory()\n }, [loadModelDirectory])\n\n useEffect(() => {\n mountedRef.current = true\n return () => {\n mountedRef.current = false\n }\n }, [])\n\n const fetchStatus = useCallback(async (refresh: boolean) => {\n if (!mountedRef.current) return\n setLoading(true)\n try {\n // The host refreshes a stale quota cache while serving the ordinary read;\n // only an explicit click asks for the forced one, so a poll never doubles\n // the upstream request count.\n const data = await readRef.current(refresh)\n if (mountedRef.current) setStatus(data)\n } catch {\n // best-effort: the settings card reports the actionable error\n } finally {\n if (mountedRef.current) setLoading(false)\n }\n }, [])\n\n useEffect(() => {\n if (!isSelected) return\n void fetchStatus(false)\n const timer = window.setInterval(() => {\n if (document.visibilityState === 'visible') void fetchStatus(false)\n }, 60_000)\n return () => {\n window.clearInterval(timer)\n }\n }, [fetchStatus, isSelected])\n\n const facts = useMemo(() => selectRef.current(status, selected?.model), [status, selected?.model])\n\n // Inert unless the conversation is actually on this provider: the badge is one\n // per line and six of them must never be visible at once.\n if (!isSelected || status === null || !status.authenticated || facts === null) return null\n\n return <span\n className=\"dsha-composer-quota\"\n data-level={facts.level}\n title={facts.tooltip}\n aria-label={facts.tooltip}\n onClick={() => void fetchStatus(true)}\n >\n <span className=\"dsha-composer-quota-label\">{label}</span>\n <strong className=\"dsha-composer-quota-val\">{loading ? '…' : facts.text}</strong>\n </span>\n}\n","import type { ModelDirectoryState } from '@deepseek-ai/dsh-client-ui-model-selection/client'\nimport type { PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\nimport type { AntigravityModelBucket, AntigravityQuotaGroup, AntigravityWebStatus } from '../../shared/antigravity-contracts.ts'\nimport { ComposerQuotaBadge, quotaLevel, type ComposerQuotaFacts } from '../common/ComposerQuotaBadge.tsx'\nimport { createLineApi } from '../common/line-api.ts'\nimport type { SnapshotStore } from '../store.ts'\nimport { NS_ANTIGRAVITY } from './locales.ts'\n\nconst api = createLineApi('/antigravity/api', 'Antigravity')\n\ntype Props = PropsRuntime<'conversation.input.right'> & PropsLocale<typeof NS_ANTIGRAVITY> & {\n directory: SnapshotStore<ModelDirectoryState>\n loadModelDirectory: () => void\n}\n\n/**\n * The bucket this badge should speak for, or null when it cannot speak for one.\n *\n * The service reports the same allowances under separate model groups, and a\n * bucket the service never measured must not be published as \"0% left\". So the\n * badge skips it and takes the next measured one in the group, and shows nothing\n * at all when the group has none. Falling back to another group's numbers would\n * label one allowance with another's reading.\n *\n * Exported for its own regression test; the badge is its only caller.\n */\nexport function selectQuotaBucketForModel(groups: AntigravityQuotaGroup[], modelId?: string) {\n if (!groups || groups.length === 0) return null\n const isClaudeOrGpt = modelId ? /claude|gpt/i.test(modelId) : false\n const targetGroup =\n groups.find((g) => {\n const match = /claude|gpt|3p/i.test(g.displayName)\n return isClaudeOrGpt ? match : !match\n }) || groups[0]\n\n if (!targetGroup || !targetGroup.buckets || targetGroup.buckets.length === 0) return null\n // A missing field and a null are the same statement (\"never measured\"), and a\n // non-finite number is no more publishable than either: all three are skipped\n // rather than multiplied into a \"0% left\" the service never said.\n const measured = (bucket: AntigravityModelBucket): boolean =>\n typeof bucket.remainingFraction === 'number' && Number.isFinite(bucket.remainingFraction)\n const shortBucket: AntigravityModelBucket | undefined =\n targetGroup.buckets.find((b: AntigravityModelBucket) => /5\\s*小时|hour|5h/i.test(b.displayName) && measured(b))\n ?? targetGroup.buckets.find(measured)\n if (shortBucket === undefined) return null\n const remaining = shortBucket.remainingFraction\n if (typeof remaining !== 'number' || !Number.isFinite(remaining)) return null\n\n return {\n groupName: targetGroup.displayName,\n bucketName: shortBucket.displayName,\n remainingPercent: Math.round(remaining * 100),\n resetTime: shortBucket.resetTime,\n }\n}\n\nfunction formatResetCountdown(resetTime?: string): string {\n if (!resetTime) return ''\n try {\n const diff = new Date(resetTime).getTime() - Date.now()\n if (diff <= 0) return '即将重置'\n const h = Math.floor(diff / 3600000)\n const m = Math.floor((diff % 3600000) / 60000)\n if (h > 0) return `${h}小时${m}分后重置`\n return `${m}分钟后重置`\n } catch {\n return ''\n }\n}\n\n/** The allowance the selected model actually draws on, as the badge's facts. */\nexport function selectBadgeFacts(status: AntigravityWebStatus | null, modelId?: string): ComposerQuotaFacts {\n const info = selectQuotaBucketForModel(status?.quota?.groups ?? [], modelId)\n if (info === null) return { text: '—', tooltip: '点击刷新 Antigravity 配额', level: 'normal' }\n const countdown = info.resetTime ? formatResetCountdown(info.resetTime) : ''\n return {\n text: `${info.remainingPercent}%`,\n tooltip: `[Antigravity] ${info.groupName} - ${info.bucketName}: 剩余 ${info.remainingPercent}%${countdown ? ` (${countdown})` : ''},点击刷新`,\n level: quotaLevel(info.remainingPercent),\n }\n}\n\nexport function AntigravityComposerQuota({ directory, loadModelDirectory, t }: Props): React.JSX.Element | null {\n return <ComposerQuotaBadge\n directory={directory}\n loadModelDirectory={loadModelDirectory}\n providerId=\"antigravity\"\n readStatus={(refresh) => (refresh\n ? api.post<AntigravityWebStatus>('/quota')\n : api.get<AntigravityWebStatus>('/status'))}\n selectFacts={selectBadgeFacts}\n label={t('composerLabel')}\n />\n}\n","import type { ModelDirectoryState } from '@deepseek-ai/dsh-client-ui-model-selection/client'\nimport type { PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\nimport type { ClaudeWebStatus } from '../../shared/claude-contracts.ts'\nimport { ComposerQuotaBadge, quotaLevel, type ComposerQuotaFacts } from '../common/ComposerQuotaBadge.tsx'\nimport { createLineApi } from '../common/line-api.ts'\nimport type { SnapshotStore } from '../store.ts'\nimport { NS_CLAUDE } from './locales.ts'\n\nconst api = createLineApi('/claude/api', 'Claude')\n\ntype Props = PropsRuntime<'conversation.input.right'> & PropsLocale<typeof NS_CLAUDE> & {\n directory: SnapshotStore<ModelDirectoryState>\n loadModelDirectory: () => void\n}\n\n/**\n * Pick the most meaningful number for the badge.\n *\n * A subscription is bounded by several windows at once — a 5-hour one and a\n * weekly one, and sometimes a per-model weekly one as well. They are not\n * interchangeable: the short window can be spent while the long one has room and\n * the reverse, so the TIGHTEST *remaining* percentage is what the badge shows\n * and its own label names the tooltip. Choosing \"the shortest window\" instead\n * would be a guess about which one runs out first, and the payload already\n * answers that.\n *\n * NOTE ON DIRECTION: the wire reports `usedPercent`, which is PERCENT USED, so\n * remaining is 100 - used. A window at 0% used is the normal empty state and\n * grades as 'normal', not as an error.\n */\nexport function selectBadgeFacts(status: ClaudeWebStatus | null): ComposerQuotaFacts | null {\n const quota = status?.quota\n if (quota === null || quota === undefined) {\n return { text: '—', tooltip: '[Claude] quota unavailable — click to refresh', level: 'normal' }\n }\n\n let tightest: { label: string; remaining: number } | null = null\n for (const window of quota.windows) {\n // A null is \"the source stated nothing\" — skipped rather than read as a\n // fully-spent window, which would be a fabricated alarm.\n const remaining = window.remainingPercent\n ?? (window.usedPercent === null ? null : 100 - window.usedPercent)\n if (remaining === null) continue\n if (tightest === null || remaining < tightest.remaining) {\n tightest = { label: window.label, remaining }\n }\n }\n if (tightest === null) {\n return { text: '—', tooltip: '[Claude] quota unavailable — click to refresh', level: 'normal' }\n }\n\n const remaining = Math.round(tightest.remaining)\n return {\n text: `${remaining}%`,\n tooltip: `[Claude] ${tightest.label}: ${remaining}% left`,\n level: quotaLevel(remaining),\n }\n}\n\nexport function ClaudeComposerQuota({ directory, loadModelDirectory, t }: Props): React.JSX.Element | null {\n return <ComposerQuotaBadge\n directory={directory}\n loadModelDirectory={loadModelDirectory}\n providerId=\"claude-subscription\"\n readStatus={(refresh) => (refresh\n ? api.post<ClaudeWebStatus>('/quota')\n : api.get<ClaudeWebStatus>('/status'))}\n selectFacts={selectBadgeFacts}\n label={t('composerLabel')}\n />\n}\n","import { installPluginStyle } from '../common/plugin-style.ts'\n\nexport const STYLE_ID = 'dsh-claude-settings-style'\n\n/**\n * Claude-only additions to the shared settings design system.\n *\n * The base control styles ('.dsha-page', '.dsha-group', '.dsha-models', the\n * account card, the meters, the composer badge, …) come from the stylesheet the\n * Kimi Code sibling installs, in the same order the client installs them, so\n * this file declares only what stays unique to this card — the same rule the\n * WorkBuddy and GLM cards follow.\n *\n * What stays unique here is the sign-in flow block and the borrowed-sign-in\n * markers, neither of which a sibling line renders.\n */\nexport function installClaudeStyles(): void {\n installPluginStyle('claude', `\n.dsha-badge.claude-adopted{background:color-mix(in srgb,var(--dsw-alias-button-info-fill,#397ee8) 16%,var(--dsw-alias-bg-layer-1));border-color:color-mix(in srgb,var(--dsw-alias-button-info-fill,#397ee8) 45%,var(--dsw-alias-border-l2));color:var(--dsw-alias-label-primary)}\n.dshcl-flow{border-bottom:0.5px solid var(--dsw-alias-border-l2);display:flex;flex-direction:column;gap:10px;padding:12px 0}\n.dshcl-flow-url{background:var(--dsw-alias-bg-layer-1,rgba(127,127,127,.14));border:0.5px solid var(--dsw-alias-border-l2);border-radius:7px;color:var(--dsw-alias-label-primary);font-family:ui-monospace,SFMono-Regular,Consolas,monospace;font-size:11px;overflow-wrap:anywhere;padding:8px 10px;user-select:all}\n.dshcl-paste{align-items:flex-start;display:flex;flex-direction:column;gap:8px}\n.dshcl-paste-row{align-items:center;display:flex;flex-wrap:wrap;gap:8px}\n.dshcl-paste-row input{flex:1 1 260px;min-width:200px}\n.dshcl-mono{font-family:ui-monospace,SFMono-Regular,Consolas,monospace;font-size:11px;overflow-wrap:anywhere}\n.dshcl-model-meta{color:var(--dsw-alias-label-tertiary);font-size:11px;margin-left:5px}\n.dshcl-empty-inline{color:var(--dsw-alias-label-tertiary);font-size:12px}\n`, STYLE_ID)\n}\n","import type { ModelDirectoryState } from '@deepseek-ai/dsh-client-ui-model-selection/client'\nimport type { PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\nimport type { CommandCodeWebStatus } from '../../shared/command-code-contracts.ts'\nimport { ComposerQuotaBadge, quotaLevel, type ComposerQuotaFacts } from '../common/ComposerQuotaBadge.tsx'\nimport { createLineApi } from '../common/line-api.ts'\nimport type { SnapshotStore } from '../store.ts'\nimport { NS_COMMAND_CODE } from './locales.ts'\n\nconst api = createLineApi('/command-code/api', 'Command Code')\n\ntype Props = PropsRuntime<'conversation.input.right'> & PropsLocale<typeof NS_COMMAND_CODE> & {\n directory: SnapshotStore<ModelDirectoryState>\n loadModelDirectory: () => void\n}\n\n/**\n * Pick the most meaningful number for the badge.\n *\n * A bounded usage window is the number a user actually spends down, so it wins\n * over a credit balance; the balance shows only when no window is reported.\n */\nexport function selectBadgeFacts(status: CommandCodeWebStatus | null): ComposerQuotaFacts | null {\n const quota = status?.quota\n if (quota === null || quota === undefined) {\n return { text: '—', tooltip: 'Command Code quota unavailable — click to refresh', level: 'normal' }\n }\n\n const window = [...(quota.windows ?? [])].sort((a, b) => (a.windowDurationMins ?? Infinity) - (b.windowDurationMins ?? Infinity))[0]\n if (window !== undefined) {\n const remaining = Math.max(0, 100 - window.usedPercent)\n return {\n text: `${remaining}%`,\n tooltip: `[Command Code] ${window.label}: ${remaining}% left`,\n level: quotaLevel(remaining),\n }\n }\n\n const meter = (quota.meters ?? []).find((candidate) => candidate.remainingFraction !== null)\n if (meter !== undefined && meter.remainingFraction !== null) {\n const remaining = Math.round(meter.remainingFraction * 100)\n return {\n text: `${remaining}%`,\n tooltip: `[Command Code] ${meter.label}: ${remaining}% left`,\n level: quotaLevel(remaining),\n }\n }\n\n if (quota.unlimited) {\n return { text: '∞', tooltip: '[Command Code] Unlimited plan allowance', level: 'normal' }\n }\n if (quota.creditBalance !== null) {\n return { text: quota.creditBalance, tooltip: `[Command Code] Remaining credits: ${quota.creditBalance}`, level: 'normal' }\n }\n return { text: '—', tooltip: 'Command Code quota unavailable — click to refresh', level: 'normal' }\n}\n\nexport function CommandCodeComposerQuota({ directory, loadModelDirectory, t }: Props): React.JSX.Element | null {\n return <ComposerQuotaBadge\n directory={directory}\n loadModelDirectory={loadModelDirectory}\n providerId=\"command-code\"\n readStatus={(refresh) => (refresh\n ? api.post<CommandCodeWebStatus>('/quota')\n : api.get<CommandCodeWebStatus>('/status'))}\n selectFacts={selectBadgeFacts}\n label={t('composerLabel')}\n />\n}\n","import type { ModelDirectoryState } from '@deepseek-ai/dsh-client-ui-model-selection/client'\nimport type { PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\nimport type { KimiCodeWebStatus } from '../../shared/kimi-code-contracts.ts'\nimport { ComposerQuotaBadge, quotaLevel, type ComposerQuotaFacts } from '../common/ComposerQuotaBadge.tsx'\nimport { createLineApi } from '../common/line-api.ts'\nimport type { SnapshotStore } from '../store.ts'\nimport { NS_KIMI_CODE } from './locales.ts'\n\nconst api = createLineApi('/kimi-code/api', 'Kimi Code')\n\ntype Props = PropsRuntime<'conversation.input.right'> & PropsLocale<typeof NS_KIMI_CODE> & {\n directory: SnapshotStore<ModelDirectoryState>\n loadModelDirectory: () => void\n}\n\n/**\n * Pick the most meaningful number for the badge.\n *\n * The shortest window is the one a user spends down first and the one that\n * blocks work soonest, so it wins over the longer pools; the 7-day allowance\n * shows only when no 5-hour window is reported.\n */\nexport function selectBadgeFacts(status: KimiCodeWebStatus | null): ComposerQuotaFacts | null {\n const quota = status?.quota\n if (quota === null || quota === undefined) {\n return { text: '—', tooltip: '[Kimi Code] quota unavailable — click to refresh', level: 'normal' }\n }\n\n const window = [...(quota.windows ?? [])]\n .filter((candidate) => candidate.windowDurationMins !== null)\n .sort((a, b) => (a.windowDurationMins ?? Infinity) - (b.windowDurationMins ?? Infinity))[0]\n ?? quota.windows[0]\n\n if (window !== undefined) {\n const remaining = Math.max(0, 100 - window.usedPercent)\n return {\n text: `${remaining}%`,\n tooltip: `[Kimi Code] ${window.label}: ${remaining}% left`,\n level: quotaLevel(remaining),\n }\n }\n\n const wallet = quota.extraUsage\n if (wallet !== null && wallet !== undefined && wallet.balanceCents !== null) {\n const amount = (wallet.balanceCents / 100).toFixed(2)\n return {\n text: amount,\n tooltip: `[Kimi Code] booster wallet: ${amount} ${wallet.currency ?? ''}`.trim(),\n level: 'normal',\n }\n }\n\n return { text: '—', tooltip: '[Kimi Code] quota unavailable — click to refresh', level: 'normal' }\n}\n\nexport function KimiCodeComposerQuota({ directory, loadModelDirectory, t }: Props): React.JSX.Element | null {\n return <ComposerQuotaBadge\n directory={directory}\n loadModelDirectory={loadModelDirectory}\n providerId=\"kimi-code\"\n readStatus={(refresh) => (refresh\n ? api.post<KimiCodeWebStatus>('/quota')\n : api.get<KimiCodeWebStatus>('/status'))}\n selectFacts={selectBadgeFacts}\n label={t('composerLabel')}\n />\n}\n","import { installPluginStyle } from '../common/plugin-style.ts'\n\nexport const STYLE_ID = 'dsh-kimi-code-settings-style'\n\n/**\n * Node the base control styles come from.\n *\n * The Kimi Code card renders the same controls as the sibling routes, so it\n * reuses one extracted stylesheet verbatim rather than re-declaring a parallel\n * design system that would drift from it.\n */\nconst BASE = `\n.dsha-page{box-sizing:border-box;color:var(--dsw-alias-label-primary);display:flex;flex-direction:column;gap:20px;max-width:780px;min-width:0;padding:2px 0 30px}\n.dsha-page *{box-sizing:border-box}\n.dsha-group{border-top:0.5px solid var(--dsw-alias-border-l2);min-width:0}\n.dsha-group:first-of-type{border-top:0}\n.dsha-grouphead{align-items:center;display:flex;gap:12px;justify-content:space-between;min-height:48px}\n.dsha-grouphead h3{font-size:14px;font-weight:650;margin:0;color:var(--dsw-alias-label-primary)}\n.dsha-row{align-items:center;border-bottom:0.5px solid var(--dsw-alias-border-l2);display:flex;gap:20px;justify-content:space-between;min-height:44px;padding:8px 0}\n.dsha-label{color:var(--dsw-alias-label-secondary);font-size:13px;flex:0 0 auto}\n.dsha-value{font-size:13px;min-width:0;overflow-wrap:anywhere;text-align:right;color:var(--dsw-alias-label-primary)}\n.dsha-actions{display:flex;flex-wrap:wrap;gap:8px;justify-content:flex-end;padding-top:12px}\n.dsha-btn{background:var(--dsw-alias-bg-layer-2);border:0.5px solid var(--dsw-alias-border-l2);border-radius:999px;corner-shape:round;color:var(--dsw-alias-label-primary);cursor:pointer;font:inherit;font-size:13px;line-height:1;padding:8px 13px;white-space:nowrap}\n.dsha-btn:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}\n.dsha-btn:disabled{cursor:default;opacity:.5}\n.dsha-btn-primary{background:var(--dsw-alias-button-info-fill,#397ee8);border-color:transparent;color:var(--dsw-alias-button-info-label,#fff)}\n.dsha-btn-primary:hover:not(:disabled){opacity:.9}\n.dsha-notice{background:var(--dsw-alias-bg-layer-2);border:0.5px solid var(--dsw-alias-border-l2);border-radius:7px;color:var(--dsw-alias-label-secondary);font-size:12px;line-height:1.55;margin:12px 0 0;padding:10px 12px}\n.dsha-muted{color:var(--dsw-alias-label-secondary);font-size:13px;line-height:1.55;margin:0}\n.dsha-models-hint{padding-top:10px}\n.dsha-pref-row{align-items:center;border-bottom:0.5px solid var(--dsw-alias-border-l2);display:flex;gap:16px;justify-content:space-between;min-height:58px;padding:10px 0}\n.dsha-pref-row strong{display:block;font-size:13px;font-weight:600;line-height:1.35;color:var(--dsw-alias-label-primary)}\n.dsha-select{background:var(--dsw-alias-bg-layer-2);border:0.5px solid var(--dsw-alias-border-l2);border-radius:7px;color:var(--dsw-alias-label-primary);font:inherit;font-size:12px;padding:7px 9px;max-width:220px;min-width:160px}\n.dsha-context-settings{border-bottom:0.5px solid var(--dsw-alias-border-l2);display:grid;gap:10px;padding:12px 0}\n.dsha-context-settings>div>strong{font-size:13px;font-weight:600;color:var(--dsw-alias-label-primary)}\n.dsha-context-row{align-items:center;display:flex;font-size:12px;gap:14px;justify-content:space-between}\n.dsha-capacity-control{align-items:center;display:flex;gap:7px}\n.dsha-capacity-control input{background:var(--dsw-alias-bg-layer-2);border:0.5px solid var(--dsw-alias-border-l2);border-radius:7px;color:var(--dsw-alias-label-primary);font:inherit;font-family:ui-monospace,SFMono-Regular,Consolas,monospace;font-size:12px;padding:7px 9px;text-align:right;width:90px}\n.dsha-capacity-control small{color:var(--dsw-alias-label-tertiary);font-size:11px;width:42px}\n.dsha-context-save{background:var(--dsw-alias-bg-layer-2);border:0.5px solid var(--dsw-alias-border-l2);border-radius:7px;color:var(--dsw-alias-label-primary);cursor:pointer;font:inherit;font-size:12px;line-height:1;padding:8px 10px;white-space:nowrap}\n.dsha-context-save:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}\n.dsha-context-save:disabled{cursor:default;opacity:.45}\n.dsha-context-reset{color:var(--dsw-alias-label-secondary)}\n.dsha-context-reset:hover:not(:disabled){color:var(--dsw-alias-label-primary)}\n.dsha-quota-card{background:var(--dsw-alias-bg-layer-2);border:0.5px solid var(--dsw-alias-border-l2);border-radius:8px;margin-top:12px;padding:12px}\n.dsha-quota-title{align-items:center;display:flex;font-size:13px;gap:8px;justify-content:space-between;color:var(--dsw-alias-label-primary);font-weight:650}\n.dsha-quota-title span{color:var(--dsw-alias-label-tertiary);font-size:11px;text-transform:uppercase}\n.dsha-meter-wrap{margin-top:13px}\n.dsha-meter-label,.dsha-meter-meta{display:flex;gap:10px;justify-content:space-between}\n.dsha-meter-label{font-size:12px;margin-bottom:6px;color:var(--dsw-alias-label-primary)}\n.dsha-meter-meta{color:var(--dsw-alias-label-tertiary);font-size:11px;line-height:1.45;margin-top:6px}\n.dsha-meter{background:var(--dsw-alias-bg-layer-1,rgba(127,127,127,.15));border-radius:999px;corner-shape:round;height:7px;overflow:hidden;width:100%}\n.dsha-meter>span{background:var(--dsw-alias-button-info-fill,#397ee8);border-radius:inherit;display:block;height:100%;max-width:100%;min-width:0;transition:width .25s ease}\n.dsha-meter-green>span{background:var(--dsw-alias-label-success,#10b981)}\n.dsha-meter-cyan>span{background:#06b6d4}\n.dsha-timestamp{color:var(--dsw-alias-label-tertiary);font-size:11px;margin:10px 0 0;text-align:right}\n.dsha-mini-btn{border:0;background:transparent;color:var(--dsw-alias-label-link,#397ee8);font-size:12px;line-height:18px;cursor:pointer;padding:0;margin-left:8px}\n.dsha-mini-btn:hover{text-decoration:underline}\n.dsha-empty{border:0.5px dashed var(--dsw-alias-border-l2);border-radius:7px;color:var(--dsw-alias-label-tertiary);font-size:12px;margin:12px 0 0;padding:16px;text-align:center}\n.dsha-error{color:var(--dsw-alias-label-danger,#d94b4b);font-size:12px;margin:8px 0 0}\n.dsha-composer-quota{align-items:center;background:var(--dsw-alias-bg-layer-2);border:0.5px solid var(--dsw-alias-border-l2);border-radius:999px;corner-shape:round;color:var(--dsw-alias-label-secondary);cursor:pointer;display:inline-flex;font-size:11px;gap:6px;height:28px;line-height:1;max-width:160px;padding:0 9px;white-space:nowrap;user-select:none;transition:all .15s ease}\n.dsha-composer-quota:hover{background:var(--dsw-alias-interactive-bg-hover);border-color:var(--dsw-alias-border-l1,var(--dsw-alias-border-l2))}\n.dsha-composer-quota strong{color:var(--dsw-alias-label-primary);font-size:11px;font-weight:650}\n.dsha-composer-quota[data-level=warning] strong{color:var(--dsw-alias-label-warning,#d58a24)}\n.dsha-composer-quota[data-level=danger] strong{color:var(--dsw-alias-label-danger,#d94b4b)}\n\n.dsha-device-box{background:var(--dsw-alias-bg-layer-2);border:0.5px solid var(--dsw-alias-border-l2);border-radius:8px;display:flex;flex-direction:column;gap:10px;margin-top:12px;padding:12px}\n.dsha-code-row{align-items:center;display:flex;flex-wrap:wrap;gap:10px;justify-content:space-between}\n.dsha-code{background:var(--dsw-alias-bg-layer-1,rgba(127,127,127,.14));border:0.5px solid var(--dsw-alias-border-l2);border-radius:7px;color:var(--dsw-alias-label-primary);font-family:ui-monospace,SFMono-Regular,Consolas,monospace;font-size:16px;font-weight:650;letter-spacing:.14em;padding:8px 12px}\n.dsha-link{color:var(--dsw-alias-label-link,#397ee8);font-size:12px;overflow-wrap:anywhere;text-decoration:none}\n.dsha-link:hover{text-decoration:underline}\n.dsha-model-meta{color:var(--dsw-alias-label-tertiary);font-size:11px;margin-left:5px}\n.dsha-badge{background:var(--dsw-alias-bg-layer-1,rgba(127,127,127,.14));border:0.5px solid var(--dsw-alias-border-l2);border-radius:999px;color:var(--dsw-alias-label-tertiary);font-size:10px;padding:2px 6px}\n.dsha-cap-table{border-bottom:0.5px solid var(--dsw-alias-border-l2);padding:12px 0}\n.dsha-cap-table table{border-collapse:collapse;font-size:11px;width:100%}\n.dsha-cap-table th{color:var(--dsw-alias-label-tertiary);font-size:11px;font-weight:500;padding:0 10px 6px 0;text-align:left;white-space:nowrap}\n.dsha-cap-table th:last-child,.dsha-cap-table td:last-child{padding-right:0}\n.dsha-cap-table td{border-top:0.5px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-label-secondary);padding:8px 10px 8px 0;vertical-align:top}\n.dsha-cap-table td:first-child{color:var(--dsw-alias-label-primary);font-family:ui-monospace,SFMono-Regular,Consolas,monospace;white-space:nowrap}\n.dsha-cap-table td:nth-child(2),.dsha-cap-table td:nth-child(3){white-space:nowrap}\n.dsha-cap-on{color:var(--dsw-alias-label-primary);font-weight:500}\n.dsha-cap-off{color:var(--dsw-alias-label-tertiary)}\n.dsha-cap-notes{line-height:1.5;min-width:200px}\n.dsha-cap-footnote{font-size:11px;line-height:1.55;margin:8px 0 0}\n.dsha-warn{border:0.5px solid var(--dsw-alias-border-l2);border-radius:6px;line-height:1.55;margin:0 0 10px;padding:8px 10px}\n`\n\n/** Kimi-specific rules layered on top of the shared control styles. */\nexport function installKimiCodeStyles(): void {\n installPluginStyle('kimi-code', BASE, STYLE_ID)\n}\n","import type { ModelDirectoryState } from '@deepseek-ai/dsh-client-ui-model-selection/client'\nimport type { PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\nimport type { MinimaxCodeWebStatus } from '../../shared/minimax-code-contracts.ts'\nimport { ComposerQuotaBadge, quotaLevel, type ComposerQuotaFacts } from '../common/ComposerQuotaBadge.tsx'\nimport { createLineApi } from '../common/line-api.ts'\nimport type { SnapshotStore } from '../store.ts'\nimport { NS_MINIMAX_CODE } from './locales.ts'\n\nconst api = createLineApi('/minimax-code/api', 'MiniMax Code')\n\ntype Props = PropsRuntime<'conversation.input.right'> & PropsLocale<typeof NS_MINIMAX_CODE> & {\n directory: SnapshotStore<ModelDirectoryState>\n loadModelDirectory: () => void\n}\n\n/**\n * Pick the badge facts for one status answer, or nothing at all.\n *\n * Quota is optional in the contract, and the usage read is allowed to fail (the\n * endpoint is undocumented and which host serves this subscription is\n * unmeasured), so a status without quota means the badge has nothing to say: it\n * is not rendered, rather than showing a placeholder that would read as a broken\n * meter. Callers must treat null as \"hide the badge\".\n */\nexport function selectBadgeFacts(status: MinimaxCodeWebStatus | null): ComposerQuotaFacts | null {\n const quota = status?.quota\n if (quota === undefined) return null\n\n if (quota.usedPercent !== undefined && Number.isFinite(quota.usedPercent)) {\n const remaining = Math.max(0, Math.round(100 - quota.usedPercent))\n return {\n text: `${remaining}%`,\n tooltip: `[MiniMax Code] ${quota.label}: ${remaining}% left`,\n level: quotaLevel(remaining),\n }\n }\n\n // A quota without a percentage still names something (a plan, a window), so\n // it is shown as text instead of a number.\n return { text: quota.label, tooltip: `[MiniMax Code] ${quota.label}`, level: 'normal' }\n}\n\nexport function MinimaxCodeComposerQuota({ directory, loadModelDirectory, t }: Props): React.JSX.Element | null {\n return <ComposerQuotaBadge\n directory={directory}\n loadModelDirectory={loadModelDirectory}\n providerId=\"minimax-code\"\n // `/quota` rather than `/status`: it answers with the same payload, but it\n // also refreshes the snapshot (subject to the host-side TTL), whereas\n // `/status` only ever reports the cached one. The badge is the one place a\n // stale number is visible at a glance, so it asks for the fresher read —\n // which is also why a click asks for nothing more than a re-read.\n readStatus={() => api.get<MinimaxCodeWebStatus>('/quota')}\n selectFacts={selectBadgeFacts}\n label={t('composerLabel')}\n />\n}\n","import { installPluginStyle } from '../common/plugin-style.ts'\n\nexport const STYLE_ID = 'dsh-minimax-code-settings-style'\n\n/**\n * MiniMax Code-only additions to the shared settings design system.\n *\n * The base control styles (.dsha-page, .dsha-group, .dsha-row, .dsha-models,\n * the device-code box, the meter, the composer badge, ...) come from the\n * stylesheet the sibling routes install, in the same order the client installs\n * them, so this file declares only what stays unique to this card: the mono\n * credential path and the model-name list.\n */\nexport function installMinimaxCodeStyles(): void {\n installPluginStyle('minimax-code', `\n.dshm-mono{font-family:ui-monospace,SFMono-Regular,Consolas,monospace;font-size:11px}\n.dshm-model-list{display:flex;flex-wrap:wrap;gap:7px;padding-top:8px}\n.dshm-model-list code{background:var(--dsw-alias-bg-layer-2);border:0.5px solid var(--dsw-alias-border-l2);border-radius:6px;color:var(--dsw-alias-label-secondary);font-family:ui-monospace,SFMono-Regular,Consolas,monospace;font-size:11px;padding:5px 8px;white-space:nowrap}\n.dshm-quota-note{margin-top:12px}\n`, STYLE_ID)\n}\n","import type { ModelDirectoryState } from '@deepseek-ai/dsh-client-ui-model-selection/client'\nimport type { PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\nimport type { WorkBuddyWebStatus } from '../../shared/workbuddy-contracts.ts'\nimport { ComposerQuotaBadge, quotaLevel, type ComposerQuotaFacts } from '../common/ComposerQuotaBadge.tsx'\nimport { createLineApi } from '../common/line-api.ts'\nimport type { SnapshotStore } from '../store.ts'\nimport { NS_WORKBUDDY } from './locales.ts'\n\nconst api = createLineApi('/workbuddy/api', 'WorkBuddy')\n\ntype Props = PropsRuntime<'conversation.input.right'> & PropsLocale<typeof NS_WORKBUDDY> & {\n directory: SnapshotStore<ModelDirectoryState>\n loadModelDirectory: () => void\n}\n\n/**\n * Pick the most meaningful number for the badge.\n *\n * A bounded allowance is what a user spends down, so it wins over a bare credit\n * balance; the balance shows only when no percentage is reported. The billing\n * payload reports both a cycle meter and a package meter, and the cycle meter\n * is the one that actually resets, so it is preferred when both exist.\n */\nexport function selectBadgeFacts(status: WorkBuddyWebStatus | null): ComposerQuotaFacts | null {\n const quota = status?.quota\n if (quota === null || quota === undefined) {\n return { text: '—', tooltip: 'WorkBuddy quota unavailable — click to refresh', level: 'normal' }\n }\n\n const meter = (quota.meters ?? []).find((candidate) => candidate.id === 'cycle' && candidate.remainingFraction !== null)\n ?? (quota.meters ?? []).find((candidate) => candidate.remainingFraction !== null)\n if (meter !== undefined && meter.remainingFraction !== null) {\n const remaining = Math.round(meter.remainingFraction * 100)\n return {\n text: `${remaining}%`,\n tooltip: `[WorkBuddy] ${meter.label}: ${remaining}% left`,\n level: quotaLevel(remaining),\n }\n }\n\n if (quota.remainingCredits !== null) {\n return {\n text: String(quota.remainingCredits),\n tooltip: `[WorkBuddy] Remaining credits: ${quota.remainingCredits}`,\n level: 'normal',\n }\n }\n return { text: '—', tooltip: 'WorkBuddy quota unavailable — click to refresh', level: 'normal' }\n}\n\nexport function WorkBuddyComposerQuota({ directory, loadModelDirectory, t }: Props): React.JSX.Element | null {\n return <ComposerQuotaBadge\n directory={directory}\n loadModelDirectory={loadModelDirectory}\n providerId=\"workbuddy-subscription\"\n readStatus={(refresh) => (refresh\n ? api.post<WorkBuddyWebStatus>('/quota')\n : api.get<WorkBuddyWebStatus>('/status'))}\n selectFacts={selectBadgeFacts}\n label={t('composerLabel')}\n />\n}\n","import { installPluginStyle } from '../common/plugin-style.ts'\n\nexport const STYLE_ID = 'dsh-workbuddy-settings-style'\n\n/**\n * WorkBuddy-only additions to the shared settings design system.\n *\n * The base control styles (`.dsha-page`, `.dsha-group`, `.dsha-models`, the\n * account card, …) come from the stylesheet the sibling routes install, in the\n * same order the client installs them, so this file declares only what stays\n * unique to this card: the mono credential paths and the login-progress line.\n *\n * Everything this tab used to declare locally — the per-model capability line\n * and the account-region headings — is gone: the model pill is name-only like\n * every sibling tab, and the account card is the shared one.\n */\nexport function installWorkBuddyStyles(): void {\n installPluginStyle('workbuddy', `\n.dshwb-mono{font-family:ui-monospace,SFMono-Regular,Consolas,monospace;font-size:11px}\n.dsha-account-add-actions{display:flex;flex-wrap:wrap;gap:8px}\n.dsha-account-add-actions .dsha-btn{background:var(--dsw-alias-button-info-fill,#397ee8);border-color:transparent;color:var(--dsw-alias-button-info-label,#fff)}\n.dsha-account-add-actions .dsha-btn:hover:not(:disabled){opacity:.9;background:var(--dsw-alias-button-info-fill,#397ee8)}\n`, STYLE_ID)\n}\n","const STRIP_ELEMENTS = new Set([\n 'foreignobject',\n 'script',\n 'img',\n 'iframe',\n 'object',\n 'embed',\n 'video',\n 'audio',\n 'input',\n 'button',\n 'form',\n 'link',\n 'meta',\n 'base',\n])\n\nexport function sanitizeSvg(svg: string): string {\n if (typeof DOMParser === 'undefined' || typeof XMLSerializer === 'undefined') return ''\n let doc: Document\n try {\n doc = new DOMParser().parseFromString(svg, 'image/svg+xml')\n } catch {\n return ''\n }\n if (doc.querySelector('parsererror') !== null) return ''\n if (doc.documentElement === null || doc.documentElement.localName !== 'svg') return ''\n doc.querySelectorAll('*').forEach((node) => {\n if (STRIP_ELEMENTS.has(node.localName.toLowerCase())) {\n node.remove()\n return\n }\n for (const attribute of [...node.attributes]) {\n const name = attribute.name\n const normalized = name.toLowerCase()\n if (normalized.startsWith('@') || normalized.startsWith('on')) {\n node.removeAttribute(name)\n continue\n }\n if (normalized === 'href' || normalized === 'xlink:href') {\n node.removeAttribute(name)\n }\n }\n })\n return new XMLSerializer().serializeToString(doc.documentElement)\n}","import { installPluginStyle } from '../common/plugin-style.ts'\n\nexport const MERMAID_STYLE_ID = 'dsh-mermaid-renderer-style'\n\nexport function installMermaidStyles(): void {\n installPluginStyle('mermaid', `\n.dsh-mermaid-wrapper{margin:12px 0;border:1px solid var(--dsw-alias-border-l2,rgba(255,255,255,0.12));border-radius:8px;overflow:hidden;background:var(--dsw-alias-bg-layer-2,#1a1a1a);box-shadow:0 2px 8px rgba(0,0,0,0.15)}\n.dsh-mermaid-header{display:flex;align-items:center;justify-content:space-between;padding:6px 12px;background:var(--dsw-alias-bg-layer-1,rgba(0,0,0,0.25));border-bottom:1px solid var(--dsw-alias-border-l2,rgba(255,255,255,0.08));font-size:12px;color:var(--dsw-alias-label-secondary,#888)}\n.dsh-mermaid-title{font-family:ui-monospace,SFMono-Regular,Consolas,monospace;font-size:11px;text-transform:uppercase;letter-spacing:0.5px;color:var(--dsw-alias-label-tertiary,#aaa);font-weight:600}\n.dsh-mermaid-controls{display:flex;gap:8px;align-items:center}\n.dsh-mermaid-btn{background:transparent;border:1px solid var(--dsw-alias-border-l2,rgba(255,255,255,0.15));border-radius:4px;color:var(--dsw-alias-label-secondary,#ccc);padding:2px 8px;font-size:11px;cursor:pointer;line-height:18px;transition:all .15s}\n.dsh-mermaid-btn:hover{background:var(--dsw-alias-interactive-bg-hover,rgba(255,255,255,0.08));color:var(--dsw-alias-label-primary,#fff);border-color:var(--dsw-alias-border-l1,rgba(255,255,255,0.3))}\n.dsh-mermaid-chart{padding:18px;overflow-x:auto;display:flex;justify-content:center;align-items:center;min-height:100px;background:var(--dsw-alias-bg-layer-2,#181818);cursor:zoom-in}\n.dsh-mermaid-chart svg{max-width:100%;height:auto;display:block;margin:0 auto}\n.dsh-mermaid-source{display:none;margin:0;padding:12px;background:var(--dsw-alias-bg-layer-1,#121212);border-top:1px solid var(--dsw-alias-border-l2,rgba(255,255,255,0.08));font-family:ui-monospace,SFMono-Regular,Consolas,monospace;font-size:12px;line-height:1.5;overflow-x:auto;white-space:pre-wrap;word-break:break-all}\n.dsh-mermaid-source.is-visible{display:block}\n\n/* 全屏缩放预览模态框 */\n.dsh-mermaid-modal-overlay{position:fixed;inset:0;background:rgba(0,0,0,0.8);backdrop-filter:blur(4px);z-index:99999;display:flex;flex-direction:column;justify-content:center;align-items:center}\n.dsh-mermaid-modal-toolbar{position:absolute;top:20px;right:24px;display:flex;gap:8px;background:rgba(20,20,20,0.85);border:1px solid rgba(255,255,255,0.15);border-radius:6px;padding:4px;box-shadow:0 8px 24px rgba(0,0,0,0.5)}\n.dsh-mermaid-modal-btn{background:transparent;border:0;color:#fff;font-size:14px;padding:6px 12px;cursor:pointer;border-radius:4px}\n.dsh-mermaid-modal-btn:hover{background:rgba(255,255,255,0.15)}\n.dsh-mermaid-modal-stage{flex:1;width:100%;height:100%;overflow:auto;display:flex;justify-content:center;align-items:center;padding:40px}\n.dsh-mermaid-modal-stage svg{max-width:90vw;max-height:85vh;height:auto}\n`, MERMAID_STYLE_ID)\n}","import { sanitizeSvg } from './sanitize.ts'\nimport { installMermaidStyles } from './styles.ts'\n\ninterface MermaidAPI {\n initialize: (config: Record<string, unknown>) => void\n render: (id: string, text: string) => Promise<{ svg: string }>\n}\n\nlet mermaidSeq = 0\nlet mermaidPromise: Promise<MermaidAPI | null> | null = null\nconst processedHosts = new WeakSet<HTMLElement>()\n\nfunction loadMermaid(): Promise<MermaidAPI | null> {\n if (typeof window === 'undefined') return Promise.resolve(null)\n const existing = (window as unknown as { mermaid?: MermaidAPI }).mermaid\n if (existing) return Promise.resolve(existing)\n if (mermaidPromise) return mermaidPromise\n\n mermaidPromise = new Promise((resolve) => {\n const current = (window as unknown as { mermaid?: MermaidAPI }).mermaid\n if (current) {\n resolve(current)\n return\n }\n\n const script = document.createElement('script')\n script.src = '/api/dsh-chatgpt-subscription/mermaid.min.js'\n script.async = true\n script.onload = () => {\n resolve((window as unknown as { mermaid?: MermaidAPI }).mermaid || null)\n }\n script.onerror = () => {\n const cdn = document.createElement('script')\n cdn.src = 'https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.min.js'\n cdn.async = true\n cdn.onload = () => resolve((window as unknown as { mermaid?: MermaidAPI }).mermaid || null)\n cdn.onerror = () => resolve(null)\n document.head.appendChild(cdn)\n }\n document.head.appendChild(script)\n })\n\n return mermaidPromise\n}\n\nfunction isDarkTheme(): boolean {\n if (typeof document === 'undefined') return false\n const root = document.documentElement\n return (\n root.classList.contains('dark') ||\n root.getAttribute('data-theme') === 'dark' ||\n root.getAttribute('data-color-mode') === 'dark' ||\n window.matchMedia('(prefers-color-scheme: dark)').matches\n )\n}\n\nasync function initMermaidConfig(): Promise<MermaidAPI | null> {\n const m = await loadMermaid()\n if (!m) return null\n try {\n m.initialize({\n startOnLoad: false,\n securityLevel: 'strict',\n htmlLabels: false,\n theme: isDarkTheme() ? 'dark' : 'default',\n fontFamily: 'ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica, Arial, sans-serif',\n })\n } catch {\n // best-effort\n }\n return m\n}\n\nfunction openZoomModal(svgHtml: string): void {\n const overlay = document.createElement('div')\n overlay.className = 'dsh-mermaid-modal-overlay'\n\n let scale = 1\n\n overlay.innerHTML = `\n <div class=\"dsh-mermaid-modal-toolbar\">\n <button type=\"button\" class=\"dsh-mermaid-modal-btn\" data-action=\"zoom-out\" title=\"缩小\">− 缩小</button>\n <button type=\"button\" class=\"dsh-mermaid-modal-btn\" data-action=\"zoom-in\" title=\"放大\">+ 放大</button>\n <button type=\"button\" class=\"dsh-mermaid-modal-btn\" data-action=\"reset\" title=\"重置\">⟳ 重置</button>\n <button type=\"button\" class=\"dsh-mermaid-modal-btn\" data-action=\"close\" title=\"关闭\">关闭</button>\n </div>\n <div class=\"dsh-mermaid-modal-stage\">\n <div class=\"dsh-mermaid-zoom-container\">${svgHtml}</div>\n </div>\n `\n\n const stage = overlay.querySelector('.dsh-mermaid-zoom-container') as HTMLElement\n const updateTransform = () => {\n if (stage) stage.style.transform = `scale(${scale})`\n }\n\n overlay.addEventListener('click', (e) => {\n const target = e.target as HTMLElement\n const action = target?.getAttribute('data-action')\n if (action === 'close' || target === overlay) {\n overlay.remove()\n document.removeEventListener('keydown', onKeyDown)\n } else if (action === 'zoom-in') {\n scale = Math.min(5, scale * 1.25)\n updateTransform()\n } else if (action === 'zoom-out') {\n scale = Math.max(0.2, scale / 1.25)\n updateTransform()\n } else if (action === 'reset') {\n scale = 1\n updateTransform()\n }\n })\n\n const onKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'Escape') {\n overlay.remove()\n document.removeEventListener('keydown', onKeyDown)\n }\n }\n document.addEventListener('keydown', onKeyDown)\n\n document.body.appendChild(overlay)\n}\n\nfunction findMermaidCandidate(codeEl: HTMLElement): { host: HTMLElement; code: string } | null {\n // 1. 绝对忽略我们自己渲染容器内的任何子元素\n if (codeEl.closest('.dsh-mermaid-wrapper')) return null\n\n // 2. 找到唯一的代码块宿主容器(优先 .md-code-block,其次 pre,最后自身)\n const host = (codeEl.closest('.md-code-block') as HTMLElement) || codeEl.closest('pre') || codeEl\n if (processedHosts.has(host) || host.getAttribute('data-dsh-mermaid-status')) return null\n if (host.previousElementSibling?.classList.contains('dsh-mermaid-wrapper')) return null\n\n const codeText = (codeEl.textContent || '').trim()\n if (!codeText || codeText.length < 5) return null\n\n // 3. 判断是否为 mermaid 语法或标记\n const hasMermaidClass = [...codeEl.classList].some((c) => c.toLowerCase().includes('mermaid'))\n const topText = host.firstElementChild?.textContent?.trim().toLowerCase()\n const isHeaderMermaid = topText === 'mermaid' || topText?.startsWith('mermaid ')\n\n const isGrammarStart = /^(flowchart|graph|sequenceDiagram|classDiagram|stateDiagram|erDiagram|gantt|pie|gitGraph|mindmap|timeline)\\b/i.test(codeText)\n\n if (hasMermaidClass || isHeaderMermaid || isGrammarStart) {\n return { host, code: codeText }\n }\n\n return null\n}\n\nasync function renderMermaidHost(host: HTMLElement, code: string): Promise<void> {\n // 同步立即锁死该宿主,杜绝并发与重入\n processedHosts.add(host)\n host.setAttribute('data-dsh-mermaid-status', 'processing')\n\n const m = await initMermaidConfig()\n if (!m) {\n processedHosts.delete(host)\n host.removeAttribute('data-dsh-mermaid-status')\n return\n }\n\n const renderId = `dsh-mermaid-${++mermaidSeq}`\n\n try {\n const { svg } = await m.render(renderId, code)\n const cleanSvg = sanitizeSvg(svg)\n if (!cleanSvg) {\n processedHosts.delete(host)\n host.removeAttribute('data-dsh-mermaid-status')\n return\n }\n\n // 再次双重检查:防止在异步等待期间被其他流程插入\n if (host.previousElementSibling?.classList.contains('dsh-mermaid-wrapper')) {\n host.setAttribute('data-dsh-mermaid-status', 'done')\n host.style.display = 'none'\n return\n }\n\n const wrapper = document.createElement('div')\n wrapper.className = 'dsh-mermaid-wrapper'\n\n let showSource = false\n\n wrapper.innerHTML = `\n <div class=\"dsh-mermaid-header\">\n <span class=\"dsh-mermaid-title\">Mermaid 图表</span>\n <div class=\"dsh-mermaid-controls\">\n <button type=\"button\" class=\"dsh-mermaid-btn\" data-btn=\"toggle-source\">源码</button>\n <button type=\"button\" class=\"dsh-mermaid-btn\" data-btn=\"copy\">复制</button>\n <button type=\"button\" class=\"dsh-mermaid-btn\" data-btn=\"zoom\" title=\"放大查看\">放大 ↗</button>\n </div>\n </div>\n <div class=\"dsh-mermaid-chart\" title=\"点击放大\">${cleanSvg}</div>\n <div class=\"dsh-mermaid-source\"><code>${code.replace(/</g, '&lt;').replace(/>/g, '&gt;')}</code></div>\n `\n\n const sourceEl = wrapper.querySelector('.dsh-mermaid-source') as HTMLElement\n const toggleBtn = wrapper.querySelector('[data-btn=\"toggle-source\"]') as HTMLButtonElement\n const copyBtn = wrapper.querySelector('[data-btn=\"copy\"]') as HTMLButtonElement\n const chartEl = wrapper.querySelector('.dsh-mermaid-chart') as HTMLElement\n\n toggleBtn?.addEventListener('click', (e) => {\n e.stopPropagation()\n showSource = !showSource\n if (showSource) {\n sourceEl.classList.add('is-visible')\n toggleBtn.textContent = '图表'\n } else {\n sourceEl.classList.remove('is-visible')\n toggleBtn.textContent = '源码'\n }\n })\n\n copyBtn?.addEventListener('click', async (e) => {\n e.stopPropagation()\n try {\n await navigator.clipboard.writeText(code)\n copyBtn.textContent = '已复制'\n setTimeout(() => {\n copyBtn.textContent = '复制'\n }, 1500)\n } catch {\n // fallback\n }\n })\n\n const handleZoom = (e: Event) => {\n e.stopPropagation()\n openZoomModal(cleanSvg)\n }\n\n wrapper.querySelector('[data-btn=\"zoom\"]')?.addEventListener('click', handleZoom)\n chartEl?.addEventListener('click', handleZoom)\n\n // 隐藏宿主并插入图表\n host.style.display = 'none'\n host.parentNode?.insertBefore(wrapper, host)\n host.setAttribute('data-dsh-mermaid-status', 'done')\n } catch {\n // 语法错误或流式未完成时释放锁,允许后续更新后重试\n processedHosts.delete(host)\n host.removeAttribute('data-dsh-mermaid-status')\n const errContainer = document.getElementById(renderId)\n if (errContainer) errContainer.remove()\n }\n}\n\nexport function scanAndRenderMermaid(): void {\n if (typeof document === 'undefined') return\n\n // 只以 code 标签为唯一的判定入口,彻底避免 querySelector 多级命中同一代码块\n const codeElements = document.querySelectorAll<HTMLElement>('pre code, .md-code-block code')\n\n for (const codeEl of codeElements) {\n const candidate = findMermaidCandidate(codeEl)\n if (candidate) {\n void renderMermaidHost(candidate.host, candidate.code)\n }\n }\n}\n\nexport function setupMermaidObserver(): () => void {\n if (typeof document === 'undefined') return () => {}\n\n installMermaidStyles()\n\n let timer: number | undefined\n const debouncedScan = () => {\n window.clearTimeout(timer)\n timer = window.setTimeout(() => {\n scanAndRenderMermaid()\n }, 250)\n }\n\n debouncedScan()\n\n const observer = new MutationObserver((mutations) => {\n let shouldScan = false\n for (const m of mutations) {\n // 只要 mutation 是我们自己的 wrapper 产生的变动,直接忽略\n for (const node of m.addedNodes) {\n if (node.nodeType === 1) {\n const el = node as HTMLElement\n if (el.classList?.contains('dsh-mermaid-wrapper') || el.closest?.('.dsh-mermaid-wrapper')) {\n continue\n }\n shouldScan = true\n break\n }\n }\n if (shouldScan) break\n }\n if (shouldScan) debouncedScan()\n })\n\n observer.observe(document.body, {\n childList: true,\n subtree: true,\n })\n\n const themeObserver = new MutationObserver(() => {\n void initMermaidConfig()\n for (const el of document.querySelectorAll<HTMLElement>('[data-dsh-mermaid-status=\"done\"]')) {\n processedHosts.delete(el)\n el.removeAttribute('data-dsh-mermaid-status')\n const prevWrapper = el.previousElementSibling\n if (prevWrapper && prevWrapper.classList.contains('dsh-mermaid-wrapper')) {\n prevWrapper.remove()\n }\n el.style.display = ''\n }\n debouncedScan()\n })\n\n themeObserver.observe(document.documentElement, {\n attributes: true,\n attributeFilter: ['class', 'data-theme', 'data-color-mode'],\n })\n\n return () => {\n observer.disconnect()\n themeObserver.disconnect()\n window.clearTimeout(timer)\n }\n}","import type { Context as ClientContext } from '@deepseek-ai/cordis'\nimport type { ImageAttachmentRef } from '@deepseek-ai/dsh-attachment'\nimport type { SessionId } from '@deepseek-ai/dsh-client-connection/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-settings/client'\nimport type {} from '@deepseek-ai/dsh-client-locale/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-slots'\nimport type {} from '@deepseek-ai/dsh-client-ui-model-selection/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-conversation/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-renderer/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-tool/client'\nimport { CODEX_IMAGE_TOOL_NAME } from '../compat.ts'\nimport { CodexComposerQuota } from './CodexComposerQuota.tsx'\nimport { CodexImageToolView, type ImageLoader } from './CodexImageToolView.tsx'\nimport { ProviderHubSection } from './ProviderHubSection.tsx'\nimport { SubscriptionApi } from './api.ts'\nimport { dictionaries, NS, type LocaleKey } from './locales.ts'\nimport { installStyles } from './styles.ts'\nimport { installHubStyles } from './hub/hub-styles.ts'\nimport { installModelChecklistStyles } from './common/model-checklist-styles.ts'\nimport { installAntigravityStyles } from './antigravity/styles.ts'\nimport { installPoolStyles } from './common/styles.ts'\nimport { dictionaries as antigravityDicts, NS_ANTIGRAVITY, type AntigravityLocaleKey } from './antigravity/locales.ts'\nimport { AntigravityComposerQuota } from './antigravity/AntigravityComposerQuota.tsx'\nimport { ClaudeComposerQuota } from './claude/ClaudeComposerQuota.tsx'\nimport { dictionaries as claudeDicts, NS_CLAUDE, type ClaudeLocaleKey } from './claude/locales.ts'\nimport { installClaudeStyles } from './claude/styles.ts'\nimport { CommandCodeComposerQuota } from './command-code/CommandCodeComposerQuota.tsx'\nimport { dictionaries as commandCodeDicts, NS_COMMAND_CODE, type CommandCodeLocaleKey } from './command-code/locales.ts'\nimport { KimiCodeComposerQuota } from './kimi-code/KimiCodeComposerQuota.tsx'\nimport { dictionaries as kimiCodeDicts, NS_KIMI_CODE, type KimiCodeLocaleKey } from './kimi-code/locales.ts'\nimport { installKimiCodeStyles } from './kimi-code/styles.ts'\nimport { MinimaxCodeComposerQuota } from './minimax-code/MinimaxCodeComposerQuota.tsx'\nimport { dictionaries as minimaxCodeDicts, NS_MINIMAX_CODE, type MinimaxCodeLocaleKey } from './minimax-code/locales.ts'\nimport { installMinimaxCodeStyles } from './minimax-code/styles.ts'\nimport { WorkBuddyComposerQuota } from './workbuddy/WorkBuddyComposerQuota.tsx'\nimport { dictionaries as workBuddyDicts, NS_WORKBUDDY, type WorkBuddyLocaleKey } from './workbuddy/locales.ts'\nimport { installWorkBuddyStyles } from './workbuddy/styles.ts'\nimport { dictionaries as ollamaDicts, NS_OLLAMA, type OllamaLocaleKey } from './ollama/locales.ts'\nimport { setupMermaidObserver } from './mermaid/renderer.ts'\n\ndeclare module '@deepseek-ai/dsh-client-ui-slots' {\n /**\n * Every namespace this plugin registers, typed by that line's own dictionary.\n *\n * These were `any`, which made a renamed or misspelled key invisible to the\n * compiler: the card rendered the key name itself and only a human noticed.\n * Each line exports its key union beside its dictionaries, so this map is now\n * the compile-time half of the locale contract.\n */\n interface LocaleNamespaceMap {\n 'dsh-chatgpt-subscription': LocaleKey\n 'dsh-antigravity': AntigravityLocaleKey\n 'dsh-claude': ClaudeLocaleKey\n 'dsh-command-code': CommandCodeLocaleKey\n 'dsh-kimi-code': KimiCodeLocaleKey\n 'dsh-minimax-code': MinimaxCodeLocaleKey\n 'dsh-workbuddy': WorkBuddyLocaleKey\n 'dsh-ollama': OllamaLocaleKey\n }\n}\n\nexport const inject = [\n 'slots',\n 'locale',\n 'modelDirectories',\n 'conversation',\n 'sessions',\n 'remote',\n 'remote.session',\n]\n\nexport function apply(ctx: ClientContext): void {\n ctx.effect(() => ctx.locale.register(NS, dictionaries), 'dsh-chatgpt-subscription: dictionaries')\n ctx.effect(() => installStyles(), 'dsh-chatgpt-subscription: styles')\n ctx.effect(() => {\n installHubStyles()\n installModelChecklistStyles()\n return () => {}\n }, 'dsh-chatgpt-subscription: hub styles')\n ctx.effect(() => ctx.locale.register(NS_ANTIGRAVITY, antigravityDicts), 'dsh-antigravity: dictionaries')\n ctx.effect(() => {\n installAntigravityStyles()\n return () => {}\n }, 'dsh-antigravity: styles')\n ctx.effect(() => ctx.locale.register(NS_CLAUDE, claudeDicts), 'dsh-claude: dictionaries')\n ctx.effect(() => {\n installClaudeStyles()\n return () => {}\n }, 'dsh-claude: styles')\n ctx.effect(() => ctx.locale.register(NS_COMMAND_CODE, commandCodeDicts), 'dsh-command-code: dictionaries')\n ctx.effect(() => ctx.locale.register(NS_KIMI_CODE, kimiCodeDicts), 'dsh-kimi-code: dictionaries')\n ctx.effect(() => {\n installKimiCodeStyles()\n return () => {}\n }, 'dsh-kimi-code: styles')\n ctx.effect(() => ctx.locale.register(NS_MINIMAX_CODE, minimaxCodeDicts), 'dsh-minimax-code: dictionaries')\n ctx.effect(() => {\n installMinimaxCodeStyles()\n return () => {}\n }, 'dsh-minimax-code: styles')\n ctx.effect(() => ctx.locale.register(NS_WORKBUDDY, workBuddyDicts), 'dsh-workbuddy: dictionaries')\n ctx.effect(() => ctx.locale.register(NS_OLLAMA, ollamaDicts), 'dsh-ollama: dictionaries')\n ctx.effect(() => {\n installWorkBuddyStyles()\n return () => {}\n }, 'dsh-workbuddy: styles')\n // Badge variants the shared account-pool card adds on top of each provider's\n // own stylesheet; additive, so it never restyles an existing tab.\n ctx.effect(() => {\n installPoolStyles()\n return () => {}\n }, 'dsh-chatgpt-subscription: pool styles')\n ctx.effect(() => setupMermaidObserver(), 'dsh-mermaid: observer')\n\n const t = ctx.locale.bind(NS)\n\n const handleModelDirectoryReload = () => {\n try {\n const conv = ctx.conversation as unknown as { activeSessionId?: string; currentSessionId?: string; activeId?: string }\n const activeSessionId = conv?.activeSessionId || conv?.currentSessionId || conv?.activeId\n if (activeSessionId && ctx.modelDirectories) {\n const dir = ctx.modelDirectories.directoryFor(activeSessionId as any)\n void dir?.load?.().catch?.(() => undefined)\n }\n } catch {\n // best-effort\n }\n }\n\n // One sidebar entry hosts every subscription provider behind tabs instead\n // of registering a separate settings page per provider.\n const ProviderHubSectionWrapper: React.FC<React.ComponentProps<typeof ProviderHubSection>> = (props) => {\n // The hub reuses the refresh callback contract so a model toggle in any\n // provider tab repaints the conversation model picker.\n return <ProviderHubSection {...props} onModelChange={handleModelDirectoryReload} />\n }\n\n ctx.slots.inject('settings.section', () => ctx.slots.register({\n name: 'settings.section',\n id: 'subscription-hub',\n order: 45,\n label: () => t('hubTitle'),\n locale: NS,\n }, ProviderHubSectionWrapper))\n\n ctx.slots.inject('conversation.input.right', () => ctx.slots.register({\n name: 'conversation.input.right', id: 'codex-subscription-quota', order: 35, locale: NS,\n inject: (sessionId) => composerBadgeInject(ctx, sessionId, { withApi: true }),\n }, CodexComposerQuota))\n ctx.slots.inject('conversation.input.right', () => ctx.slots.register({\n name: 'conversation.input.right', id: 'antigravity-quota', order: 36, locale: NS_ANTIGRAVITY,\n inject: (sessionId) => composerBadgeInject(ctx, sessionId),\n }, AntigravityComposerQuota))\n ctx.slots.inject('conversation.input.right', () => ctx.slots.register({\n name: 'conversation.input.right', id: 'command-code-quota', order: 37, locale: NS_COMMAND_CODE,\n inject: (sessionId) => composerBadgeInject(ctx, sessionId),\n }, CommandCodeComposerQuota))\n ctx.slots.inject('conversation.input.right', () => ctx.slots.register({\n name: 'conversation.input.right', id: 'kimi-code-quota', order: 38, locale: NS_KIMI_CODE,\n inject: (sessionId) => composerBadgeInject(ctx, sessionId),\n }, KimiCodeComposerQuota))\n ctx.slots.inject('conversation.input.right', () => ctx.slots.register({\n name: 'conversation.input.right', id: 'workbuddy-quota', order: 39, locale: NS_WORKBUDDY,\n inject: (sessionId) => composerBadgeInject(ctx, sessionId),\n }, WorkBuddyComposerQuota))\n ctx.slots.inject('conversation.input.right', () => ctx.slots.register({\n name: 'conversation.input.right', id: 'minimax-code-quota', order: 40, locale: NS_MINIMAX_CODE,\n inject: (sessionId) => composerBadgeInject(ctx, sessionId),\n }, MinimaxCodeComposerQuota))\n ctx.slots.inject('conversation.input.right', () => ctx.slots.register({\n name: 'conversation.input.right', id: 'claude-quota', order: 41, locale: NS_CLAUDE,\n inject: (sessionId) => composerBadgeInject(ctx, sessionId),\n }, ClaudeComposerQuota))\n ctx.slots.inject('tool.call.toolview', () => ctx.slots.register({\n name: 'tool.call.toolview',\n key: CODEX_IMAGE_TOOL_NAME,\n locale: NS,\n inject: (sessionId) => ({\n loadImage: imageLoader(ctx, sessionId),\n }),\n }, CodexImageToolView))\n}\n\ntype ImageUrlResolver = (sessionId: string, attachment: ImageAttachmentRef) => Promise<string>\n\n/**\n * The seats every composer badge is handed.\n *\n * Seven registrations each repeated this eight-line factory verbatim, and the\n * only difference between them was whether ChatGPT's own badge also reads the\n * subscription API directly. It lives here so a badge added later cannot forget\n * the directory seat (the badge resolves the session's model list through it) or\n * the reload callback that keeps that list fresh.\n *\n * The session id arrives as a plain string while the directory service takes the\n * branded one, so the cast lives here rather than at seven call sites.\n */\nfunction composerBadgeInject(ctx: ClientContext, sessionId: string, options: { withApi?: boolean } = {}) {\n const directory = ctx.modelDirectories.directoryFor(sessionId as SessionId)\n return {\n ...(options.withApi === true ? { api: new SubscriptionApi() } : {}),\n directory: directory.store,\n loadModelDirectory: () => {\n void directory.load().catch(() => undefined)\n },\n }\n}\n\n/**\n * Why the seven registrations below are spelled out rather than driven from a\n * table.\n *\n * `ctx.slots.register` is generic over the slot key *and* the locale namespace,\n * and it is overloaded; the component's props are composed from both. A table\n * would have to hold components of different namespaces, so the correlation\n * between a row's `locale` and its `component` would be erased — and a helper\n * that keeps the correlation generically fails overload resolution inside its\n * own body, because the namespace parameter is still unresolved there. Both\n * roads end in a cast against the harness's composed-props internals, which is a\n * version-sensitive seam this plugin does not add. What each row repeats is only\n * the registration object; the eight-line seat factory is\n * {@link composerBadgeInject}.\n */\n\n/**\n * Resolve one session-authorized image URL.\n *\n * Harness 0.1.2 moved this from `resolveImage` on `conversation` to `imageUrl`\n * on `uiConversation`, so both shapes stay supported.\n */\nfunction imageLoader(ctx: ClientContext, sessionId: string): ImageLoader {\n const current = ctx.get('uiConversation') as unknown as { imageUrl?: ImageUrlResolver } | undefined\n const currentResolve = current?.imageUrl?.bind(current)\n if (currentResolve !== undefined) return (attachment) => currentResolve(sessionId, attachment)\n const legacy = ctx.get('conversation') as unknown as { resolveImage?: ImageUrlResolver } | undefined\n const legacyResolve = legacy?.resolveImage?.bind(legacy)\n if (legacyResolve !== undefined) return (attachment) => legacyResolve(sessionId, attachment)\n return () => Promise.reject(new Error('no client service resolves an image URL'))\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"client.js","names":["formatPercent","request","post","messageOf","formatCapacity","formatDate","formatReset","parsePositiveCapacity","zh","en","dictionaries","api","zh","zh","en","dictionaries","EFFORT_LABELS","api","zh","zh","en","dictionaries","zh","api","zh","zh","en","dictionaries","API","api","zh","EFFORT_LABELS","zh","api","request","post","zh","en","dictionaries","zh","post","zh","en","dictionaries","api","zh","zh","API","zh","en","dictionaries","zh","CSS","CSS","STYLE_ID","api","selectBadgeFacts","api","selectBadgeFacts","STYLE_ID","api","selectBadgeFacts","api","selectBadgeFacts","STYLE_ID","api","selectBadgeFacts","STYLE_ID","antigravityDicts","claudeDicts","commandCodeDicts","kimiCodeDicts","minimaxCodeDicts","workBuddyDicts","ollamaDicts"],"sources":["../src/shared/minimax-code-contracts.ts","../src/compat.ts","../src/client/common/use-store.ts","../src/client/quota.ts","../src/client/CodexComposerQuota.tsx","../src/client/CodexImageToolView.tsx","../src/shared/hub-contracts.ts","../src/client/common/account-pool-labels.ts","../src/client/hub/brand-svg.ts","../src/client/hub/brand-icons.tsx","../src/shared/model-catalog.ts","../src/client/api.ts","../src/client/common/account-quota.tsx","../src/client/common/AccountPoolSection.tsx","../src/client/common/ModelChecklist.tsx","../src/client/common/quota-follow-up.ts","../src/client/CodexSubscriptionSection.tsx","../src/client/common/format.ts","../src/client/common/ContextWindowEditor.tsx","../src/client/common/line-api.ts","../src/client/antigravity/locales.ts","../src/client/antigravity/AntigravitySection.tsx","../src/shared/command-code-contracts.ts","../src/client/command-code/locales.ts","../src/client/command-code/CommandCodeSection.tsx","../src/shared/kimi-code-contracts.ts","../src/client/kimi-code/locales.ts","../src/client/kimi-code/KimiModelCapabilities.tsx","../src/client/kimi-code/KimiCodeSection.tsx","../src/shared/workbuddy-contracts.ts","../src/client/workbuddy/locales.ts","../src/client/workbuddy/useWorkBuddySection.ts","../src/client/workbuddy/WorkBuddySection.tsx","../src/client/minimax-code/api.ts","../src/client/minimax-code/locales.ts","../src/client/minimax-code/useMinimaxCodeSection.ts","../src/client/minimax-code/MinimaxCodeSection.tsx","../src/shared/claude-contracts.ts","../src/client/claude/locales.ts","../src/client/claude/useClaudeSection.ts","../src/client/claude/ClaudeSection.tsx","../src/client/ollama/api.ts","../src/client/ollama/locales.ts","../src/client/ollama/OllamaSection.tsx","../src/client/hub/providers.tsx","../src/client/hub/HubOverview.tsx","../src/client/ProviderHubSection.tsx","../src/client/locales.ts","../src/client/common/plugin-style.ts","../src/client/styles.ts","../src/client/hub/hub-styles.ts","../src/client/common/model-checklist-styles.ts","../src/client/antigravity/styles.ts","../src/client/common/styles.ts","../src/client/common/ComposerQuotaBadge.tsx","../src/client/antigravity/AntigravityComposerQuota.tsx","../src/client/claude/ClaudeComposerQuota.tsx","../src/client/claude/styles.ts","../src/client/command-code/CommandCodeComposerQuota.tsx","../src/client/kimi-code/KimiCodeComposerQuota.tsx","../src/client/kimi-code/styles.ts","../src/client/minimax-code/MinimaxCodeComposerQuota.tsx","../src/client/minimax-code/styles.ts","../src/client/workbuddy/WorkBuddyComposerQuota.tsx","../src/client/workbuddy/styles.ts","../src/client/mermaid/sanitize.ts","../src/client/mermaid/styles.ts","../src/client/mermaid/renderer.ts","../src/client/index.tsx"],"sourcesContent":["/**\n * MiniMax Code(编程订阅)线路的共享契约。\n *\n * host 与 client 两半只依赖本文件的类型与常量,互不 import。\n * 本文件由调度者冻结:类型名与常量名不得更改,可追加。\n */\n\nimport type {\n AccountRotationStrategy,\n PoolAccountSummaryDto,\n} from './account-pool-contracts.ts'\n\nexport const MINIMAX_CODE_PROVIDER_ID = 'minimax-code'\nexport const MINIMAX_CODE_PROVIDER_NAME = 'MiniMax Code(编程订阅)'\n\n/** 区域。cn 用 account.minimax.cn / agent.minimax.cn;global 用对应 .io 域名。 */\nexport type MinimaxCodeRegion = 'cn' | 'global'\n\n/** M3.1 的思考档位;M2.7 恒定开启,M3 为开关二态。 */\nexport type MinimaxCodeReasoningEffort = 'default' | 'low' | 'medium' | 'high' | 'xhigh' | 'max'\n\n/**\n * 全线共用的思考档位,按从小到大的顺序排列。\n *\n * 设置卡片只渲染这一份列表:档位是线路级的词汇表(`isMinimaxCodeReasoningEffort`\n * 就是按它校验的),而不是单个模型的能力表。某个模型实际接受哪些档位由\n * `MinimaxCodeModelOption.reasoningEfforts` 单独给出——把两者合成一份会让卡片\n * 在给一个只认 `default` 的模型显示 `max` 时无从判断是模型不支持还是文案没写。\n */\nexport const MINIMAX_CODE_REASONING_EFFORTS: readonly MinimaxCodeReasoningEffort[] =\n ['default', 'low', 'medium', 'high', 'xhigh', 'max']\n\n/**\n * 路由前缀(host 暴露、client 消费)。\n *\n * 与其余各订阅线路一致:每条线路把自己的设置面挂在 `/<line>/api` 下\n * (antigravity / claude / command-code / kimi-code / workbuddy 都是如此),\n * 而不是挂到 Codex 那条线路的 `/api/dsh-chatgpt-subscription` 前缀下面。\n * 唯一的 `/api/dsh-chatgpt-subscription` 前缀属于 Codex 自己的路由表。\n */\nexport const MINIMAX_CODE_ROUTE_PREFIX = '/minimax-code/api'\n\nexport interface MinimaxCodeAccount {\n id: string\n label: string\n email?: string\n /** 凭据代数,每次刷新自增;用于诊断两侧刷新争用。 */\n generation: number\n expiresAtMs: number\n}\n\nexport interface MinimaxCodeCredentialStorage {\n /** minimax-native = 直接复用 MiniMax Code 的 auth.json;其余为插件自持。 */\n kind: 'minimax-native' | 'dpapi' | 'file'\n path?: string\n}\n\nexport interface MinimaxCodeWebLogin {\n loginId: string\n userCode: string\n verificationUri: string\n expiresInSec: number\n}\n\n/**\n * 一个配额窗口。\n *\n * Token Plan 同时给两个窗口:5 小时滚动窗口与每周窗口。两者都要单独呈现,\n * 因为周窗口还带一个显示倍率(服务端返回 percentage 与 boost 两个值,渲染值\n * 是两者相乘),而把两个窗口合成一个数字会让用户无法判断是哪一边快用完了。\n */\nexport interface MinimaxCodeQuotaWindow {\n /** 稳定标识,由客户端本地化成窗口名;不要在这里放展示文案。 */\n key: 'interval' | 'weekly'\n /** 剩余百分比(周窗口已乘上 boost)。服务端未给出时为 null。 */\n remainingPercent: number | null\n /** 已用百分比;由剩余百分比取反得到。 */\n usedPercent?: number\n /** 已用/总量;仅当服务端计数与其百分比自洽时才有值(见 host 侧消歧说明)。 */\n used?: number\n total?: number\n /** 该窗口重置的绝对时刻(Unix 毫秒)。 */\n resetsAtMs?: number\n /** 服务端把该窗口标为不限量。 */\n unlimited?: boolean\n}\n\nexport interface MinimaxCodeQuota {\n label: string\n usedPercent?: number\n resetsAtMs?: number\n /** 每个窗口的明细;服务端只给了一个数字时缺省。 */\n windows?: MinimaxCodeQuotaWindow[]\n /** 本快照读取时刻(Unix 毫秒),便于卡片判断数据新旧。 */\n fetchedAtMs?: number\n}\n\n/** 一条模型行的思考形态;取值与 host 目录里的 MinimaxCodeThinkingMode 一致。 */\nexport type MinimaxCodeThinkingModeDto = 'always-on' | 'toggle' | 'forced-effort'\n\n/**\n * 设置卡片渲染的一行模型。\n *\n * 硬编码目录(host 的 `MINIMAX_CODE_MODELS`)带的是「模型是什么」,这里带的是\n * 「这个安装当前怎么用它」:启用与否、生效的上下文窗口、请求缺省输出上限。\n * 两者分开是因为前者随代码发布、后者随用户设置变化;把设置混进目录会让一份\n * 用户数据看起来像一条已发布的目录项。\n */\nexport interface MinimaxCodeModelOption {\n id: string\n name: string\n /** 是否由 DSH 提供给会话模型选择器。 */\n enabled: boolean\n /** 目录声明的默认上下文窗口。 */\n defaultContextWindow: number\n /** 生效窗口:有覆盖值时用覆盖值,否则等于 `defaultContextWindow`。 */\n contextWindow: number\n /** 调用方不指定时,本线路请求的输出上限。 */\n defaultMaxTokens: number\n /** 本模型接受的思考档位;没有可选档位时缺省。 */\n reasoningEfforts?: string[]\n /** 会话未指定档位时使用的档位。 */\n defaultReasoningEffort?: string\n /** 思考形态:恒定开启 / 开关二态 / 强制带档位。 */\n thinking: MinimaxCodeThinkingModeDto\n description: string | null\n}\n\n/**\n * 每日签到偏好。\n *\n * 签到面同时覆盖 cn 与 global 两个区域(官方 CLI 的 public-gateway 对两个\n * region 各有源站),因此这里不像 workbuddy 那样只限国区:账号自己的\n * region 决定走哪个源站。没有可配置的窗口:宿主启动后的第一次 tick\n * 就是当天签到。\n */\nexport interface MinimaxCodeCheckinSettings {\n /** 是否由进程内调度器自动签到。 */\n enabled: boolean\n}\n\n/**\n * 设置卡片渲染的签到聚合。\n *\n * 有意不带账号身份:卡片只显示一行「今日已签 x/y」,不做逐账号明细。\n */\nexport interface MinimaxCodeCheckinSummary {\n enabled: boolean\n /** 参与签到的账号数(号池中当前可选的账号)。 */\n totalAccounts: number\n /** 今日已确认签到的账号数(本已签过,或由某次运行签成)。 */\n doneToday: number\n /** 今日签到面报告不可签的账号数(当日格非「可领」状态,按小时复查)。 */\n skippedToday: number\n /** 今日重试次数耗尽仍未签成的账号数。 */\n failedToday: number\n /** 调度器上次运行时刻(Unix 毫秒),自动或手动。 */\n lastRunAt: number | null\n /** 已签到账号当前连续签到天数的最大值;今天还没人签时缺省。 */\n streakDays?: number\n /** 最近一次运行实际领到的积分;本轮没人新签时缺省。 */\n claimedPoints?: number\n}\n\nexport interface MinimaxCodeWebStatus {\n /** 线路总开关;关闭时适配器不暴露任何模型。 */\n enabled: boolean\n authenticated: boolean\n providerId: typeof MINIMAX_CODE_PROVIDER_ID\n region: MinimaxCodeRegion\n storage: MinimaxCodeCredentialStorage\n account?: MinimaxCodeAccount\n login?: MinimaxCodeWebLogin\n /** 硬编码目录渲染成的模型行(远端 `/v1/models` 不可用)。 */\n models: MinimaxCodeModelOption[]\n /** 每条被覆盖的模型当前保存的上下文窗口;未被覆盖的模型不出现。 */\n contextWindowOverrides: Record<string, number>\n /** 未指定时的全局思考档位;null 表示各模型用自己的默认档位。 */\n defaultReasoningEffort: MinimaxCodeReasoningEffort | null\n /** 无可用用量快照时为 undefined,UI 应优雅降级。 */\n quota?: MinimaxCodeQuota\n /**\n * 用量快照缺失、且原因值得告诉用户时给出。\n *\n * - `credential-not-accepted`:端点应答了,但**拒绝本线路持有的凭据类型**——\n * `/v1/token_plan/remains` 只接受平台 API 密钥,MiniMax Code 的\n * `mcode-public` 登录态在四种认证写法下都被拒(`base_resp.status_code: 1004`)。\n * - `unreachable`:没有任何候选主机给出可用应答。\n * - `token-expired`:所有候选主机都以 401/403 拒绝了 bearer,且随后那一次\n * 续期也失败了。注意这**不等于**未登录:access token 一小时到期是常态,\n * 账号仍然是登录态,UI 不应据此提示重新登录。\n * - `stale`:本次读取失败,但卡片仍在渲染上一次成功解析出的数值——数值是真的,\n * 只是不再新鲜。\n */\n quotaUnavailable?: 'credential-not-accepted' | 'unreachable' | 'token-expired' | 'stale'\n /**\n * 本次应答背后是否正在刷新用量。\n *\n * 卡片先用已有快照作答、不等待上游请求;该值为 true 时客户端应当稍后\n * 再问一次,让刷新后的快照尽快上屏。\n */\n quotaRefreshing?: boolean\n /** 本插件是否正在服务该 Provider 路由;被别的适配器占用时为 false。 */\n serving: boolean\n /** 路由被别的适配器占用时的诊断文案。 */\n conflict: string | null\n /**\n * 凭据是否由本插件自己持有(即本插件设备码登录写下的那一份)。\n *\n * false 有两种情况:尚未登录,或当前登录态属于 MiniMax Code 桌面端自己\n * (`~/.minimax/auth`)。后者本插件**会**在需要时续期并原子写回(只读优先),\n * 但**不会删除**它——删掉等于把用户从正在运行的官方客户端里踢下线。因此\n * 「登出」对它无效,卡片必须据此禁用按钮并说明原因,而不是给出一个按下去\n * 没有效果的按钮。\n */\n ownedByPlugin: boolean\n /**\n * 号池里的账号,供设置卡片的「账号管理」渲染。\n *\n * 与其余各线路同构(复用同一个共享卡片与同一份 DTO):每条元素只带非机密的\n * 展示信息,令牌永远不过这条边界。桌面端自有账号在其中会被标为\n * `removable: false`——它归 MiniMax Code 所有,本插件只读与续期。\n */\n accounts?: PoolAccountSummaryDto[]\n /** 下一个请求会使用的账号。 */\n activeAccountId?: string\n /** 号池调度策略;无号池时缺省为顺序耗尽。 */\n rotationStrategy?: AccountRotationStrategy\n /** 本进程是否装载了号池。false 时卡片按单凭据模式渲染。 */\n poolInstalled?: boolean\n /** 每日签到聚合;未装载签到调度器时为 null。 */\n checkin?: MinimaxCodeCheckinSummary | null\n}\n\n","/**\n * Compatibility constants for the ChatGPT-backed Codex flow. The backend and\n * OAuth parameters are not a public third-party API contract, so every such\n * value is isolated here for review and rollback.\n */\nexport const CHATGPT_OAUTH_ISSUER = 'https://auth.openai.com' as const\nexport const CHATGPT_OAUTH_CLIENT_ID = 'app_EMoamEEZ73f0CkXaXp7hrann' as const\nexport const OAUTH_CALLBACK_HOST = 'localhost' as const\nexport const OAUTH_CALLBACK_PORT = 1455 as const\nexport const OAUTH_CALLBACK_PATH = '/auth/callback' as const\nexport const OAUTH_REDIRECT_URI = `http://${OAUTH_CALLBACK_HOST}:${OAUTH_CALLBACK_PORT}${OAUTH_CALLBACK_PATH}` as const\nexport const OAUTH_SCOPE = 'openid profile email offline_access' as const\n/**\n * The single `originator` this line presents to the Codex backend on every\n * request, and the one OAuth sends during sign-in.\n *\n * This used to be three different values - `opencode` for chat and sign-in,\n * `pi` for the image and search endpoints - which was an archaeological record\n * of when each endpoint was reverse-engineered, not a decision. The Codex\n * backend keys behaviour off this value (`codex_cli_rs` is what the official\n * CLI sends) and treats it as one client identity, so splitting it across three\n * files meant three unrelated failure signatures for one account. Both spellings\n * are known-good against the backend; `opencode` is kept because it is the value\n * the OAuth flow has always presented, and changing the sign-in originator is a\n * different risk from changing the request originator.\n */\nexport const CODEX_ORIGINATOR = 'opencode' as const\n/** OAuth presents the same identity the request path does (see above). */\nexport const OAUTH_ORIGINATOR = CODEX_ORIGINATOR\nexport const OAUTH_LOGIN_TIMEOUT_MS = 5 * 60_000\nexport const TOKEN_REFRESH_MARGIN_MS = 60_000\nexport const ROUTE_PREFIX = '/api/dsh-chatgpt-subscription' as const\nexport const PLUGIN_VERSION = '0.1.0-alpha.0' as const\nexport const CODEX_CHATGPT_PROVIDER_ID = 'codex-chatgpt' as const\n\n//\n// MiniMax Code subscription line.\n//\n// The provider id and the route prefix are re-exported from the frozen shared\n// contract rather than restated here, so the two halves of the line cannot drift\n// apart. This line's settings routes live under its own `/minimax-code/api`\n// prefix like every other subscription line, NOT under the Codex\n// `/api/dsh-chatgpt-subscription` prefix below, which belongs to that one route\n// table alone. Exposing the constant here keeps the mounted prefixes discoverable\n// from the compatibility seam.\n//\nexport { MINIMAX_CODE_PROVIDER_ID, MINIMAX_CODE_ROUTE_PREFIX } from './shared/minimax-code-contracts.ts'\n\nexport const CODEX_API_BASE = 'https://chatgpt.com/backend-api/codex' as const\nexport const CODEX_RESPONSES_URL = `${CODEX_API_BASE}/responses` as const\nexport const CODEX_IMAGE_GENERATION_URL = `${CODEX_API_BASE}/images/generations` as const\nexport const CODEX_SEARCH_URL = `${CODEX_API_BASE}/alpha/search` as const\nexport const CODEX_USAGE_URL = 'https://chatgpt.com/backend-api/wham/usage' as const\n/**\n * The live model listing the subscription serves.\n *\n * Unlike the public `/v1/models`, this endpoint answers the *subscription*\n * entitlement: which models this plan can call, their real context window, and\n * the reasoning levels each one accepts. `client_version` is required and is the\n * same value the official CLI sends.\n */\nexport const CODEX_CLIENT_VERSION = '0.99.0' as const\nexport const CODEX_MODELS_URL = `${CODEX_API_BASE}/models?client_version=${CODEX_CLIENT_VERSION}` as const\n/**\n * Beta gate the Codex backend expects on every responses request.\n *\n * The subscription backend is served under a beta flag, not as stable API:\n * without this header the endpoint is a different (and, on older builds,\n * rejected) surface. Kept as a single constant so the value is reviewable in\n * one place with the rest of the wire contract in `wire-auth.ts`.\n */\nexport const CODEX_OPENAI_BETA = 'responses=experimental' as const\nexport const CODEX_RESET_CREDITS_URL = 'https://chatgpt.com/backend-api/wham/rate-limit-reset-credits' as const\nexport const CODEX_RESET_CREDITS_CONSUME_URL = `${CODEX_RESET_CREDITS_URL}/consume` as const\nexport const CODEX_IMAGE_TOOL_NAME = 'codex_image_generate' as const\nexport const CODEX_IMAGE_MODEL = 'gpt-image-2' as const\nexport const CODEX_SEARCH_PROVIDER_ID = 'codex-subscription' as const\nexport const CODEX_FETCH_PROVIDER_ID = 'codex-subscription' as const\nexport const QUOTA_CACHE_MS = 60_000\nexport const QUOTA_MIN_UPSTREAM_INTERVAL_MS = 15_000\n\nexport const OAUTH_AUTHORIZE_URL = `${CHATGPT_OAUTH_ISSUER}/oauth/authorize` as const\nexport const OAUTH_TOKEN_URL = `${CHATGPT_OAUTH_ISSUER}/oauth/token` as const\n","/**\n * Subscribe to a snapshot store as a React value.\n *\n * Two copies of this existed — the shared composer badge and the ChatGPT badge —\n * which is why it lives in its own module rather than being exported from the\n * badge: a component module exporting a generic hook reads as if the hook\n * belonged to that component.\n */\nimport { useSyncExternalStore } from 'react'\nimport type { SnapshotStore } from '../store.ts'\n\nexport function useStore<T>(store: SnapshotStore<T>): T {\n return useSyncExternalStore(\n (listener) => store.subscribe(listener),\n () => store.getSnapshot(),\n () => store.getSnapshot(),\n )\n}\n","import type { QuotaBucketDto, QuotaStatusDto, QuotaWindowDto } from '../shared/contracts.ts'\n\nexport interface SelectedQuotaWindow {\n bucket: QuotaBucketDto\n window: QuotaWindowDto\n remainingPercent: number\n}\n\nexport function selectQuotaForModel(quota: QuotaStatusDto | undefined, modelId: string | undefined): SelectedQuotaWindow | null {\n if (quota === undefined || quota.buckets.length === 0) return null\n const model = modelId?.toLowerCase() ?? ''\n const wantsSpark = model.includes('spark')\n const bucket = wantsSpark\n ? quota.buckets.find(candidate => `${candidate.id} ${candidate.name}`.toLowerCase().includes('spark'))\n : quota.buckets.find(candidate => candidate.id === 'codex')\n ?? quota.buckets.find(candidate => candidate.name.toLowerCase() === 'codex')\n if (bucket === undefined) return null\n const windows = quotaWindows(bucket)\n if (windows.length === 0) return null\n // 优先选取 5h 等短周期额度(按 windowDurationMins 升序排序),没有短周期时选取周额度\n const sorted = [...windows].sort((a, b) => {\n const durA = a.windowDurationMins ?? Infinity\n const durB = b.windowDurationMins ?? Infinity\n return durA - durB\n })\n const window = sorted[0]!\n return {\n bucket,\n window,\n remainingPercent: Math.max(0, 100 - window.usedPercent),\n }\n}\n\nexport function quotaWindows(bucket: QuotaBucketDto): QuotaWindowDto[] {\n if (bucket.windows.length > 0) return bucket.windows\n return [bucket.primary, bucket.secondary].filter((window): window is QuotaWindowDto => window !== null)\n}\n","import { useEffect, useMemo, useRef, useState } from 'react'\nimport type { ModelDirectoryState } from '@deepseek-ai/dsh-client-ui-model-selection/client'\nimport type { PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\nimport { CODEX_CHATGPT_PROVIDER_ID } from '../compat.ts'\nimport type { PluginStatusDto } from '../shared/contracts.ts'\nimport { SubscriptionApi } from './api.ts'\nimport { useStore } from './common/use-store.ts'\nimport { NS } from './locales.ts'\nimport { selectQuotaForModel } from './quota.ts'\nimport type { SnapshotStore } from './store.ts'\n\ntype Props = PropsRuntime<'conversation.input.right'> & PropsLocale<typeof NS> & {\n api: SubscriptionApi\n directory: SnapshotStore<ModelDirectoryState>\n loadModelDirectory: () => void\n}\n\nexport function CodexComposerQuota({ api, directory, loadModelDirectory, t }: Props): React.JSX.Element | null {\n const modelState = useStore(directory)\n const [status, setStatus] = useState<PluginStatusDto | null>(null)\n const [loading, setLoading] = useState(false)\n const mountedRef = useRef(false)\n const selected = modelState.current\n const isCodex = selected?.provider === CODEX_CHATGPT_PROVIDER_ID\n\n useEffect(() => {\n loadModelDirectory()\n }, [loadModelDirectory])\n\n useEffect(() => {\n mountedRef.current = true\n return () => {\n mountedRef.current = false\n }\n }, [])\n\n useEffect(() => {\n if (!isCodex) return\n let disposed = false\n const refresh = async (): Promise<void> => {\n setLoading(true)\n try {\n const next = await api.status()\n if (!disposed && mountedRef.current) setStatus(next)\n } catch {\n if (!disposed && mountedRef.current) setStatus(null)\n } finally {\n if (!disposed && mountedRef.current) setLoading(false)\n }\n }\n void refresh()\n const timer = window.setInterval(() => {\n if (document.visibilityState === 'visible') void refresh()\n }, 60_000)\n return () => {\n disposed = true\n window.clearInterval(timer)\n }\n }, [api, isCodex])\n\n const quota = useMemo(() => selectQuotaForModel(status?.quota, selected?.model), [selected?.model, status?.quota])\n if (!isCodex || status?.preferences.quickQuotaVisible !== true) return null\n const level = quota === null\n ? 'normal'\n : quota.remainingPercent <= 5\n ? 'danger'\n : quota.remainingPercent <= 20\n ? 'warning'\n : 'normal'\n return <span className=\"dsh-codex-composer-quota\" data-level={level} aria-label={quota === null ? t('quickQuotaLoading') : `${t('quickQuotaLabel')}: ${formatPercent(quota.remainingPercent)}`}>\n <span>{t('quickQuotaLabel')}</span>\n <strong>{quota === null ? (loading ? t('quickQuotaLoading') : '—') : formatPercent(quota.remainingPercent)}</strong>\n </span>\n}\n\nfunction formatPercent(value: number): string {\n return `${new Intl.NumberFormat(undefined, { maximumFractionDigits: 0 }).format(value)}%`\n}\n","import { useEffect, useState } from 'react'\nimport type { ImageAttachmentRef } from '@deepseek-ai/dsh-attachment'\nimport type { ContentBlock } from '@deepseek-ai/dsh-client-connection/client'\nimport type { PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\nimport { NS } from './locales.ts'\n\nexport type ImageLoader = (attachment: ImageAttachmentRef) => Promise<string>\n\ntype Props = PropsRuntime<'tool.call.toolview'> & PropsLocale<typeof NS> & {\n loadImage: ImageLoader\n}\n\nexport function CodexImageToolView({ block, loadImage, t }: Props): React.JSX.Element {\n const settled = 'kind' in block\n const isError = settled ? block.isError : false\n const prompt = promptFromBlock(block)\n const images = settled && !isError ? imageBlocks(block.content) : []\n const label = isError ? t('imageToolFailed') : settled ? t('imageToolDone') : t('imageToolRunning')\n const summary = prompt ?? textSummary(settled ? block.content : [])\n return <div className=\"dsh-codex-image-tool\" data-state={isError ? 'error' : settled ? 'done' : 'running'}>\n <div className=\"dsh-codex-image-tool-head\">\n <span className=\"dsh-codex-image-dot\" aria-hidden=\"true\" />\n <span className=\"dsh-codex-image-title\">{label}</span>\n {summary !== null ? <span className=\"dsh-codex-image-summary\">{summary}</span> : null}\n </div>\n {images.length > 0 ? <div className=\"dsh-codex-image-grid\">\n {images.map((attachment) => <GeneratedImage key={String(attachment.attachmentId)} attachment={attachment} load={loadImage} label={attachment.name ?? t('image')} t={t} />)}\n </div> : null}\n </div>\n}\n\nfunction GeneratedImage({ attachment, load, label, t }: {\n attachment: ImageAttachmentRef\n load: ImageLoader\n label: string\n t: Props['t']\n}): React.JSX.Element {\n const [src, setSrc] = useState<string | null>(null)\n const [failed, setFailed] = useState(false)\n useEffect(() => {\n let disposed = false\n setSrc(null)\n setFailed(false)\n load(attachment).then((url) => {\n if (!disposed) setSrc(url)\n }, () => {\n if (!disposed) setFailed(true)\n })\n return () => {\n disposed = true\n }\n }, [attachment, load])\n if (failed) return <span className=\"dsh-codex-image-failed\">{t('imageLoadFailed')}</span>\n if (src === null) return <span className=\"dsh-codex-image-loading\">{t('imageLoading')}</span>\n return <img className=\"dsh-codex-image-preview\" src={src} alt={label} />\n}\n\nfunction promptFromBlock(block: Props['block']): string | null {\n const raw = 'kind' in block ? block.call?.argsRaw : dispatchedArgsRaw(block)\n if (typeof raw !== 'string' || raw.trim() === '') return null\n try {\n const value = JSON.parse(raw) as unknown\n return typeof value === 'object'\n && value !== null\n && !Array.isArray(value)\n && typeof (value as { prompt?: unknown }).prompt === 'string'\n ? (value as { prompt: string }).prompt\n : null\n } catch {\n return null\n }\n}\n\n/**\n * Arguments of a dispatched call that has no result yet.\n *\n * Harness 0.1.7-rc.1 dispatches a view as soon as its call starts *preparing*,\n * before the arguments exist, so the preparing shape carries no `argsRaw` at\n * all. Older generations only ever sent the dispatched shape.\n */\nfunction dispatchedArgsRaw(block: Props['block']): string | undefined {\n return 'argsRaw' in block ? block.argsRaw : undefined\n}\n\n/** Pre-0.1.7 tool-result block: a harness that still carries one nests its content here. */\ninterface LegacyToolResultBlock {\n type: 'tool-result'\n content: readonly ContentBlock[]\n}\n\ntype ToolViewBlock = ContentBlock | LegacyToolResultBlock\n\nfunction imageBlocks(blocks: readonly ToolViewBlock[]): ImageAttachmentRef[] {\n const result: ImageAttachmentRef[] = []\n for (const block of blocks) {\n if (block.type === 'image') result.push(block.attachment)\n if (block.type === 'tool-result') result.push(...imageBlocks(block.content))\n }\n return result\n}\n\nfunction textSummary(blocks: readonly ToolViewBlock[]): string | null {\n const text = blocks\n .map((block) => block.type === 'text' || block.type === 'reasoning' ? block.text : '')\n .filter(Boolean)\n .join(' ')\n .trim()\n return text === '' ? null : text\n}\n","/**\n * Wire contracts for the subscription hub's overview route.\n *\n * The overview is the settings page's opening screen: one card per provider\n * line, annotated with how many accounts it holds and whether it is enabled.\n * Everything here is a non-secret fact a settings card may render; no\n * credential, quota figure, or upstream call ever crosses this boundary.\n */\nimport { ROUTE_PREFIX } from '../compat.ts'\n\n/** The aggregated, read-only overview the hub's opening screen renders. */\nexport const HUB_OVERVIEW_PATH = `${ROUTE_PREFIX}/hub/overview` as const\n\n/** One provider line as the hub's overview card renders it. */\nexport interface HubProviderSummaryDto {\n /** Client descriptor key, e.g. 'chatgpt', 'kimi-code', 'ollama'. */\n id: string\n /** LLM route id the line serves, e.g. 'codex-chatgpt', 'workbuddy-subscription'. */\n providerId: string\n /**\n * Whether the line has an \"enable this provider\" switch at all.\n *\n * Ollama has none (a key line is always servable), so its card renders no\n * switch instead of a frozen one.\n */\n canToggle: boolean\n /** Whether the line currently serves its route. Always true when `canToggle` is false. */\n enabled: boolean\n /** Signed-in / stored accounts the pool currently holds. */\n accountCount: number\n /** Whether at least one account can authenticate right now. */\n authenticated: boolean\n /**\n * Enabled model count, when the line can determine it locally.\n *\n * Lines whose catalog only exists upstream report null rather than guessing,\n * and the card simply omits the model annotation.\n */\n enabledModelCount: number | null\n /** Total catalog size when locally known; null otherwise. */\n totalModelCount: number | null\n /** True when this line's summary could not be read and the counts are placeholders. */\n error?: boolean\n}\n\nexport interface HubOverviewDto {\n providers: HubProviderSummaryDto[]\n}\n","/**\n * Labels every provider tab's account-pool card renders.\n *\n * They live here rather than in each provider's locale file so the four tabs\n * cannot drift apart in wording, ordering or meaning. The active locale is the\n * one the host already selects per provider; each `locales.ts` spreads the set\n * it needs and may override individual keys.\n */\n\n/** Labels the shared card needs, in the order its markup uses them. */\nexport interface AccountPoolLabels {\n accountPool: string\n addAccount: string\n /** `{count}` is replaced with the number of signed-in accounts. */\n accountCount: string\n primaryAccount: string\n activeAccount: string\n setPrimary: string\n deleteAccount: string\n cooling: string\n /** `{minutes}` is replaced with the remaining cooldown in whole minutes. */\n cooldownLeft: string\n clearCooldown: string\n needsRelogin: string\n relogin: string\n rotationStrategy: string\n strategySequential: string\n strategyRoundRobin: string\n strategySticky: string\n noAccounts: string\n email: string\n expires: string\n lastUsed: string\n accountId: string\n /** Legend of the per-account quota block. */\n accountQuota: string\n /** Shown when no quota was ever read for that account. */\n quotaNone: string\n /** `{time}` is replaced with the snapshot's read time. */\n quotaSnapshot: string\n /** Prefix of a window's reset moment, e.g. `重置 3 小时后`. */\n quotaResets: string\n /** Drawn in place of a percentage once a window is spent. */\n quotaExhausted: string\n /** Fallback window name when the line gave neither a label nor a length. */\n quotaWindow: string\n /** Read out by a screen reader beside the bar's percentage. */\n quotaUsed: string\n /** Explains that the page-level facts belong to the current account only. */\n quotaFactsScope: string\n /** The composer badge's own label, in front of its number. */\n composerLabel: string\n}\n\n/** Chinese labels; the wording the Antigravity card shipped with. */\nexport const accountPoolZh: AccountPoolLabels = {\n accountPool: '账号管理',\n addAccount: '添加账号',\n accountCount: '已登录 {count} 个账号',\n primaryAccount: '主账号',\n activeAccount: '当前使用',\n setPrimary: '设为主账号',\n deleteAccount: '删除',\n cooling: '冷却中',\n cooldownLeft: '剩 {minutes} 分',\n clearCooldown: '重置冷却',\n needsRelogin: '需重新登录',\n relogin: '重新登录',\n rotationStrategy: '调度策略',\n strategySequential: '顺序耗尽(当前优先,遇限流自动切号)',\n strategyRoundRobin: '轮询调度(按账号循环均匀分摊)',\n strategySticky: '粘性会话(保持当前账号,遇限流才切换)',\n noAccounts: '暂无账号,点击「添加账号」完成登录授权。',\n email: '邮箱',\n expires: '令牌到期',\n lastUsed: '上次调用',\n accountId: '账号 ID',\n accountQuota: '配额',\n quotaNone: '尚无配额数据',\n quotaSnapshot: '快照 {time}',\n quotaResets: '重置',\n quotaExhausted: '已用尽',\n quotaWindow: '额度窗口',\n quotaUsed: '已用',\n quotaFactsScope: '以下为当前账号的配额事实;每个账号自己的进度显示在它的账号卡片里。',\n composerLabel: '额度',\n}\n\n/** English labels for the ChatGPT tab, which is the bilingual one. */\nexport const accountPoolEn: AccountPoolLabels = {\n accountPool: 'Account Management',\n addAccount: 'Add Account',\n accountCount: '{count} account(s) signed in',\n primaryAccount: 'Primary',\n activeAccount: 'In Use',\n setPrimary: 'Set as Primary',\n deleteAccount: 'Delete',\n cooling: 'In Cooldown',\n cooldownLeft: '{minutes} min left',\n clearCooldown: 'Clear Cooldown',\n needsRelogin: 'Sign-in required',\n relogin: 'Sign in again',\n rotationStrategy: 'Scheduling Strategy',\n strategySequential: 'Sequential Drain (primary first, fail over on 429)',\n strategyRoundRobin: 'Round-Robin (evenly rotate across accounts)',\n strategySticky: 'Sticky Session (keep the current account until it is limited)',\n noAccounts: 'No accounts yet. Click \"Add Account\" to authorize.',\n email: 'Email',\n expires: 'Token expires',\n lastUsed: 'Last used',\n accountId: 'Account ID',\n accountQuota: 'Quota',\n quotaNone: 'No quota read yet',\n quotaSnapshot: 'Snapshot {time}',\n quotaResets: 'Resets',\n quotaExhausted: 'Exhausted',\n quotaWindow: 'Limit window',\n quotaUsed: 'used',\n quotaFactsScope: 'These facts describe the current account; each account\\u2019s own progress is shown on its card above.',\n composerLabel: 'Quota',\n}\n\n/** Replace `{name}` placeholders in one label. */\nexport function formatPoolLabel(template: string, values: Record<string, string | number>): string {\n return template.replace(/\\{(\\w+)\\}/g, (match, name: string) => (\n name in values ? String(values[name]) : match\n ))\n}\n","/**\n * Inline brand marks, extracted from the vendored combine lockups\n * (dsh-claude-style/src/assets/icons/combine). Each entry is the\n * mark-color group's inner artwork with its original transform, cropped\n * to a square, mark-centered viewBox measured against the rendered lockup.\n * Regenerate with temp/gen-brand-svg.cjs; do not hand-edit the artwork.\n */\nexport interface BrandMarkSvg { viewBox: string; body: string }\n\nexport const BRAND_MARKS = {\n 'openai': {\n viewBox: '0 -0.225 1.45 1.45',\n body: '<g transform=\"translate(-0.2852 -2.0104) scale(0.002787)\"><g fill=\"currentColor\"><path d=\"M583.793,841.346c11.778,-44.127 0.356,-93.159 -34.264,-127.777c-34.616,-34.618 -83.65,-46.041 -127.777,-34.264c-32.329,-32.262 -80.503,-46.887 -127.794,-34.215c-47.289,12.672 -81.694,49.424 -93.563,93.526c-44.102,11.866 -80.854,46.274 -93.523,93.564c-12.673,47.289 1.952,95.462 34.214,127.791c-11.776,44.126 -0.354,93.16 34.264,127.777c34.618,34.62 83.651,46.041 127.779,34.264c32.329,32.263 80.503,46.888 127.79,34.215c47.289,-12.672 81.695,-49.425 93.564,-93.526c44.104,-11.865 80.857,-46.274 93.526,-93.563c12.672,-47.291 -1.952,-95.462 -34.216,-127.792Zm-179.693,-124.105c39.682,-22.943 91.303,-17.439 125.254,16.511c23.963,23.965 33.748,56.745 29.367,87.904l-111.77,-64.53c-4.415,-2.549 -9.855,-2.549 -14.27,0l-130.876,75.563l0,-50.806c0,-3.427 1.837,-6.63 4.803,-8.343l97.49,-56.297l0.002,-0.002Zm-41.659,113.397l60.638,35.01l0,70.02l-60.638,35.01l-60.639,-35.01l0,-70.02l60.639,-35.01Zm-138.015,-57.766c-0.029,-45.836 30.549,-87.793 76.926,-100.217c32.734,-8.773 66.015,-0.856 90.81,18.518l-111.768,64.53c-4.415,2.549 -7.134,7.261 -7.134,12.359l0,151.125l-44.001,-25.405c-2.967,-1.715 -4.824,-4.909 -4.824,-8.332l-0.009,-112.576l0,-0.002Zm-89.99,66.69c8.773,-32.735 32.268,-57.601 61.443,-69.386l0,129.056c0,5.099 2.719,9.81 7.134,12.359l130.877,75.564l-44.002,25.405c-2.964,1.713 -6.661,1.724 -9.627,0.011l-97.498,-56.279c-39.71,-22.893 -60.754,-70.353 -48.329,-116.727l0.002,-0.003Zm186.345,244.515c-39.681,22.943 -91.303,17.437 -125.253,-16.512c-23.965,-23.965 -33.749,-56.745 -29.368,-87.904l111.769,64.53c4.414,2.549 9.856,2.549 14.271,0l130.876,-75.564l0,50.807c0,3.429 -1.837,6.632 -4.803,8.343l-97.49,56.298l-0.002,0.002Zm179.675,-55.631c0.028,45.837 -30.55,87.793 -76.927,100.216c-32.736,8.774 -66.017,0.856 -90.81,-18.519l111.767,-64.529c4.417,-2.549 7.136,-7.262 7.136,-12.359l0,-151.123l44.001,25.404c2.965,1.713 4.824,4.909 4.824,8.332l0.009,112.578Zm89.986,-66.691c-8.773,32.735 -32.268,57.601 -61.444,69.387l0,-129.058c0,-5.097 -2.718,-9.808 -7.133,-12.359l-130.878,-75.562l44.002,-25.405c2.965,-1.714 6.662,-1.726 9.628,-0.012l97.497,56.278c39.712,22.893 60.754,70.355 48.329,116.729l-0.001,0.002Z\" style=\"\"/></g></g>',\n },\n 'gemini': {\n viewBox: '0 -0.1644 1.329 1.329',\n body: '<g transform=\"translate(-0.0604 -0.2250) scale(0.060417)\"><g><path d=\"M20.616 10.835a14.147 14.147 0 01-4.45-3.001 14.111 14.111 0 01-3.678-6.452.503.503 0 00-.975 0 14.134 14.134 0 01-3.679 6.452 14.155 14.155 0 01-4.45 3.001c-.65.28-1.318.505-2.002.678a.502.502 0 000 .975c.684.172 1.35.397 2.002.677a14.147 14.147 0 014.45 3.001 14.112 14.112 0 013.679 6.453.502.502 0 00.975 0c.172-.685.397-1.351.677-2.003a14.145 14.145 0 013.001-4.45 14.113 14.113 0 016.453-3.678.503.503 0 000-.975 13.245 13.245 0 01-2.003-.678z\" fill=\"#3186FF\"></path><path d=\"M20.616 10.835a14.147 14.147 0 01-4.45-3.001 14.111 14.111 0 01-3.678-6.452.503.503 0 00-.975 0 14.134 14.134 0 01-3.679 6.452 14.155 14.155 0 01-4.45 3.001c-.65.28-1.318.505-2.002.678a.502.502 0 000 .975c.684.172 1.35.397 2.002.677a14.147 14.147 0 014.45 3.001 14.112 14.112 0 013.679 6.453.502.502 0 00.975 0c.172-.685.397-1.351.677-2.003a14.145 14.145 0 013.001-4.45 14.113 14.113 0 016.453-3.678.503.503 0 000-.975 13.245 13.245 0 01-2.003-.678z\" fill=\"url(#lobe-icons-gemini-0-_R_0_)\"></path><path d=\"M20.616 10.835a14.147 14.147 0 01-4.45-3.001 14.111 14.111 0 01-3.678-6.452.503.503 0 00-.975 0 14.134 14.134 0 01-3.679 6.452 14.155 14.155 0 01-4.45 3.001c-.65.28-1.318.505-2.002.678a.502.502 0 000 .975c.684.172 1.35.397 2.002.677a14.147 14.147 0 014.45 3.001 14.112 14.112 0 013.679 6.453.502.502 0 00.975 0c.172-.685.397-1.351.677-2.003a14.145 14.145 0 013.001-4.45 14.113 14.113 0 016.453-3.678.503.503 0 000-.975 13.245 13.245 0 01-2.003-.678z\" fill=\"url(#lobe-icons-gemini-1-_R_0_)\"></path><path d=\"M20.616 10.835a14.147 14.147 0 01-4.45-3.001 14.111 14.111 0 01-3.678-6.452.503.503 0 00-.975 0 14.134 14.134 0 01-3.679 6.452 14.155 14.155 0 01-4.45 3.001c-.65.28-1.318.505-2.002.678a.502.502 0 000 .975c.684.172 1.35.397 2.002.677a14.147 14.147 0 014.45 3.001 14.112 14.112 0 013.679 6.453.502.502 0 00.975 0c.172-.685.397-1.351.677-2.003a14.145 14.145 0 013.001-4.45 14.113 14.113 0 016.453-3.678.503.503 0 000-.975 13.245 13.245 0 01-2.003-.678z\" fill=\"url(#lobe-icons-gemini-2-_R_0_)\"></path><defs><linearGradient gradientUnits=\"userSpaceOnUse\" id=\"lobe-icons-gemini-0-_R_0_\" x1=\"7\" x2=\"11\" y1=\"15.5\" y2=\"12\"><stop stop-color=\"#08B962\"></stop><stop offset=\"1\" stop-color=\"#08B962\" stop-opacity=\"0\"></stop></linearGradient><linearGradient gradientUnits=\"userSpaceOnUse\" id=\"lobe-icons-gemini-1-_R_0_\" x1=\"8\" x2=\"11.5\" y1=\"5.5\" y2=\"11\"><stop stop-color=\"#F94543\"></stop><stop offset=\"1\" stop-color=\"#F94543\" stop-opacity=\"0\"></stop></linearGradient><linearGradient gradientUnits=\"userSpaceOnUse\" id=\"lobe-icons-gemini-2-_R_0_\" x1=\"3.5\" x2=\"17.5\" y1=\"13.5\" y2=\"12\"><stop stop-color=\"#FABC12\"></stop><stop offset=\".46\" stop-color=\"#FABC12\" stop-opacity=\"0\"></stop></linearGradient></defs></g></g>',\n },\n 'kimi': {\n viewBox: '0.0488 -0.225 1.2083 1.2083',\n body: '<g transform=\"translate(-0.1812 -0.2250) scale(0.060417)\"><g><path d=\"M21.846 0a1.923 1.923 0 110 3.846H20.15a.226.226 0 01-.227-.226V1.923C19.923.861 20.784 0 21.846 0z\" fill=\"#1783FF\"></path><path d=\"M11.065 11.199l7.257-7.2c.137-.136.06-.41-.116-.41H14.3a.164.164 0 00-.117.051l-7.82 7.756c-.122.12-.302.013-.302-.179V3.82c0-.127-.083-.23-.185-.23H3.186c-.103 0-.186.103-.186.23V19.77c0 .128.083.23.186.23h2.69c.103 0 .186-.102.186-.23v-3.25c0-.069.025-.135.069-.178l2.424-2.406a.158.158 0 01.205-.023l6.484 4.772a7.677 7.677 0 003.453 1.283c.108.012.2-.095.2-.23v-3.06c0-.117-.07-.212-.164-.227a5.028 5.028 0 01-2.027-.807l-5.613-4.064c-.117-.078-.132-.279-.028-.381z\" fill=\"currentColor\"></path></g></g>',\n },\n 'minimax': {\n viewBox: '0 -0.225 1.45 1.45',\n body: '<g transform=\"translate(-0.0000 -0.2250) scale(0.060417)\"><g><defs><linearGradient id=\"lobe-icons-minimax-_R_0_\" x1=\"0%\" x2=\"100.182%\" y1=\"50.057%\" y2=\"50.057%\"><stop offset=\"0%\" stop-color=\"#E2167E\"></stop><stop offset=\"100%\" stop-color=\"#FE603C\"></stop></linearGradient></defs><path d=\"M16.278 2c1.156 0 2.093.927 2.093 2.07v12.501a.74.74 0 00.744.709.74.74 0 00.743-.709V9.099a2.06 2.06 0 012.071-2.049A2.06 2.06 0 0124 9.1v6.561a.649.649 0 01-.652.645.649.649 0 01-.653-.645V9.1a.762.762 0 00-.766-.758.762.762 0 00-.766.758v7.472a2.037 2.037 0 01-2.048 2.026 2.037 2.037 0 01-2.048-2.026v-12.5a.785.785 0 00-.788-.753.785.785 0 00-.789.752l-.001 15.904A2.037 2.037 0 0113.441 22a2.037 2.037 0 01-2.048-2.026V18.04c0-.356.292-.645.652-.645.36 0 .652.289.652.645v1.934c0 .263.142.506.372.638.23.131.514.131.744 0a.734.734 0 00.372-.638V4.07c0-1.143.937-2.07 2.093-2.07zm-5.674 0c1.156 0 2.093.927 2.093 2.07v11.523a.648.648 0 01-.652.645.648.648 0 01-.652-.645V4.07a.785.785 0 00-.789-.78.785.785 0 00-.789.78v14.013a2.06 2.06 0 01-2.07 2.048 2.06 2.06 0 01-2.071-2.048V9.1a.762.762 0 00-.766-.758.762.762 0 00-.766.758v3.8a2.06 2.06 0 01-2.071 2.049A2.06 2.06 0 010 12.9v-1.378c0-.357.292-.646.652-.646.36 0 .653.29.653.646V12.9c0 .418.343.757.766.757s.766-.339.766-.757V9.099a2.06 2.06 0 012.07-2.048 2.06 2.06 0 012.071 2.048v8.984c0 .419.343.758.767.758.423 0 .766-.339.766-.758V4.07c0-1.143.937-2.07 2.093-2.07z\" fill=\"url(#lobe-icons-minimax-_R_0_)\" fill-rule=\"nonzero\"></path></g></g>',\n },\n 'tencent': {\n viewBox: '0 -0.225 1.45 1.45',\n body: '<g transform=\"translate(-0.0000 -0.2250) scale(0.060417)\"><g><circle cx=\"12\" cy=\"12\" fill=\"#0055E9\" r=\"12\"></circle><path d=\"M12 0c.518 0 1.028.033 1.528.096A6.188 6.188 0 0112.12 12.28l-.12.001c-2.99 0-5.242 2.179-5.554 5.11-.223 2.086.353 4.412 2.242 6.146C3.672 22.1 0 17.479 0 12 0 5.373 5.373 0 12 0z\" fill=\"currentColor\"></path><path d=\"M5.286 5a2.438 2.438 0 01.682 3.38c-3.962 5.966-3.215 10.743 2.648 15.136C3.636 22.056 0 17.452 0 12c0-1.787.39-3.482 1.09-5.006.253-.435.525-.872.817-1.311A2.438 2.438 0 015.286 5z\" fill=\"#0055E9\"></path><path d=\"M12.98.04c.272.021.543.053.81.093.583.106 1.117.254 1.538.44 6.638 2.927 8.07 10.052 1.748 15.642a4.125 4.125 0 01-5.822-.358c-1.51-1.706-1.3-4.184.357-5.822.858-.848 3.108-1.223 4.045-2.441 1.257-1.634 2.122-6.009-2.523-7.506L12.98.039z\" fill=\"#00BCFF\"></path><path d=\"M13.528.096A6.187 6.187 0 0112 12.281a5.75 5.75 0 00-1.71.255c.147-.905.595-1.784 1.321-2.501.858-.848 3.108-1.223 4.045-2.441 1.27-1.651 2.14-6.104-2.676-7.554.184.014.367.033.548.056z\" fill=\"#ECECEE\"></path></g></g>',\n },\n 'qwen': {\n viewBox: '-0.0125 -0.1646 1.3417 1.3417',\n body: '<g transform=\"translate(-0.0604 -0.2250) scale(0.060417)\"><g><path d=\"M12.604 1.34c.393.69.784 1.382 1.174 2.075a.18.18 0 00.157.091h5.552c.174 0 .322.11.446.327l1.454 2.57c.19.337.24.478.024.837-.26.43-.513.864-.76 1.3l-.367.658c-.106.196-.223.28-.04.512l2.652 4.637c.172.301.111.494-.043.77-.437.785-.882 1.564-1.335 2.34-.159.272-.352.375-.68.37-.777-.016-1.552-.01-2.327.016a.099.099 0 00-.081.05 575.097 575.097 0 01-2.705 4.74c-.169.293-.38.363-.725.364-.997.003-2.002.004-3.017.002a.537.537 0 01-.465-.271l-1.335-2.323a.09.09 0 00-.083-.049H4.982c-.285.03-.553-.001-.805-.092l-1.603-2.77a.543.543 0 01-.002-.54l1.207-2.12a.198.198 0 000-.197 550.951 550.951 0 01-1.875-3.272l-.79-1.395c-.16-.31-.173-.496.095-.965.465-.813.927-1.625 1.387-2.436.132-.234.304-.334.584-.335a338.3 338.3 0 012.589-.001.124.124 0 00.107-.063l2.806-4.895a.488.488 0 01.422-.246c.524-.001 1.053 0 1.583-.006L11.704 1c.341-.003.724.032.9.34zm-3.432.403a.06.06 0 00-.052.03L6.254 6.788a.157.157 0 01-.135.078H3.253c-.056 0-.07.025-.041.074l5.81 10.156c.025.042.013.062-.034.063l-2.795.015a.218.218 0 00-.2.116l-1.32 2.31c-.044.078-.021.118.068.118l5.716.008c.046 0 .08.02.104.061l1.403 2.454c.046.081.092.082.139 0l5.006-8.76.783-1.382a.055.055 0 01.096 0l1.424 2.53a.122.122 0 00.107.062l2.763-.02a.04.04 0 00.035-.02.041.041 0 000-.04l-2.9-5.086a.108.108 0 010-.113l.293-.507 1.12-1.977c.024-.041.012-.062-.035-.062H9.2c-.059 0-.073-.026-.043-.077l1.434-2.505a.107.107 0 000-.114L9.225 1.774a.06.06 0 00-.053-.031zm6.29 8.02c.046 0 .058.02.034.06l-.832 1.465-2.613 4.585a.056.056 0 01-.05.029.058.058 0 01-.05-.029L8.498 9.841c-.02-.034-.01-.052.028-.054l.216-.012 6.722-.012z\" fill=\"url(#lobe-icons-qwen-_R_0_)\" fill-rule=\"nonzero\"></path><defs><linearGradient id=\"lobe-icons-qwen-_R_0_\" x1=\"0%\" x2=\"100%\" y1=\"0%\" y2=\"0%\"><stop offset=\"0%\" stop-color=\"#6336E7\" stop-opacity=\".84\"></stop><stop offset=\"100%\" stop-color=\"#6F69F7\" stop-opacity=\".84\"></stop></linearGradient></defs></g></g>',\n },\n 'deepseek': {\n viewBox: '0 -0.2352 1.45 1.45',\n body: '<g transform=\"translate(-0.0000 -0.2250) scale(0.060417)\"><g><path d=\"M23.748 4.482c-.254-.124-.364.113-.512.234-.051.039-.094.09-.137.136-.372.397-.806.657-1.373.626-.829-.046-1.537.214-2.163.848-.133-.782-.575-1.248-1.247-1.548-.352-.156-.708-.311-.955-.65-.172-.241-.219-.51-.305-.774-.055-.16-.11-.323-.293-.35-.2-.031-.278.136-.356.276-.313.572-.434 1.202-.422 1.84.027 1.436.633 2.58 1.838 3.393.137.093.172.187.129.323-.082.28-.18.552-.266.833-.055.179-.137.217-.329.14a5.526 5.526 0 01-1.736-1.18c-.857-.828-1.631-1.742-2.597-2.458a11.365 11.365 0 00-.689-.471c-.985-.957.13-1.743.388-1.836.27-.098.093-.432-.779-.428-.872.004-1.67.295-2.687.684a3.055 3.055 0 01-.465.137 9.597 9.597 0 00-2.883-.102c-1.885.21-3.39 1.102-4.497 2.623C.082 8.606-.231 10.684.152 12.85c.403 2.284 1.569 4.175 3.36 5.653 1.858 1.533 3.997 2.284 6.438 2.14 1.482-.085 3.133-.284 4.994-1.86.47.234.962.327 1.78.397.63.059 1.236-.03 1.705-.128.735-.156.684-.837.419-.961-2.155-1.004-1.682-.595-2.113-.926 1.096-1.296 2.746-2.642 3.392-7.003.05-.347.007-.565 0-.845-.004-.17.035-.237.23-.256a4.173 4.173 0 001.545-.475c1.396-.763 1.96-2.015 2.093-3.517.02-.23-.004-.467-.247-.588zM11.581 18c-2.089-1.642-3.102-2.183-3.52-2.16-.392.024-.321.471-.235.763.09.288.207.486.371.739.114.167.192.416-.113.603-.673.416-1.842-.14-1.897-.167-1.361-.802-2.5-1.86-3.301-3.307-.774-1.393-1.224-2.887-1.298-4.482-.02-.386.093-.522.477-.592a4.696 4.696 0 011.529-.039c2.132.312 3.946 1.265 5.468 2.774.868.86 1.525 1.887 2.202 2.891.72 1.066 1.494 2.082 2.48 2.914.348.292.625.514.891.677-.802.09-2.14.11-3.054-.614zm1-6.44a.306.306 0 01.415-.287.302.302 0 01.2.288.306.306 0 01-.31.307.303.303 0 01-.304-.308zm3.11 1.596c-.2.081-.399.151-.59.16a1.245 1.245 0 01-.798-.254c-.274-.23-.47-.358-.552-.758a1.73 1.73 0 01.016-.588c.07-.327-.008-.537-.239-.727-.187-.156-.426-.199-.688-.199a.559.559 0 01-.254-.078c-.11-.054-.2-.19-.114-.358.028-.054.16-.186.192-.21.356-.202.767-.136 1.146.016.352.144.618.408 1.001.782.391.451.462.576.685.914.176.265.336.537.445.848.067.195-.019.354-.25.452z\" fill=\"#4D6BFE\"></path></g></g>',\n },\n 'grok': {\n viewBox: '0 -0.2237 1.45 1.45',\n body: '<g transform=\"translate(-0.0000 -0.2250) scale(0.060417)\"><g fill=\"#000\" fill-rule=\"evenodd\"><path d=\"M9.27 15.29l7.978-5.897c.391-.29.95-.177 1.137.272.98 2.369.542 5.215-1.41 7.169-1.951 1.954-4.667 2.382-7.149 1.406l-2.711 1.257c3.889 2.661 8.611 2.003 11.562-.953 2.341-2.344 3.066-5.539 2.388-8.42l.006.007c-.983-4.232.242-5.924 2.75-9.383.06-.082.12-.164.179-.248l-3.301 3.305v-.01L9.267 15.292M7.623 16.723c-2.792-2.67-2.31-6.801.071-9.184 1.761-1.763 4.647-2.483 7.166-1.425l2.705-1.25a7.808 7.808 0 00-1.829-1A8.975 8.975 0 005.984 5.83c-2.533 2.536-3.33 6.436-1.962 9.764 1.022 2.487-.653 4.246-2.34 6.022-.599.63-1.199 1.259-1.682 1.925l7.62-6.815\"></path></g></g>',\n },\n 'claude': {\n viewBox: '0 0 148.09 148.18',\n body: '<g transform=\\'translate(-75.96,-223.53)\\'><path d=\\'m 105.01,322.07 29.14,-16.35 0.49,-1.42 -0.49,-0.79 h -1.42 l -4.87,-0.3 -16.65,-0.45 -14.44,-0.6 -13.99,-0.75 -3.52,-0.75 -3.3,-4.35 0.34,-2.17 2.96,-1.99 4.24,0.37 9.37,0.64 14.06,0.97 10.2,0.6 15.11,1.57 h 2.4 l 0.34,-0.97 -0.82,-0.6 -0.64,-0.6 -14.55,-9.86 -15.75,-10.42 -8.25,-6 -4.46,-3.04 -2.25,-2.85 -0.97,-6.22 4.05,-4.46 5.44,0.37 1.39,0.37 5.51,4.24 11.77,9.11 15.37,11.32 2.25,1.87 0.9,-0.64 0.11,-0.45 -1.01,-1.69 -8.36,-15.11 -8.92,-15.37 -3.97,-6.37 -1.05,-3.82 c -0.37,-1.57 -0.64,-2.89 -0.64,-4.5 l 4.61,-6.26 2.55,-0.82 6.15,0.82 2.59,2.25 3.82,8.74 6.19,13.76 9.6,18.71 2.81,5.55 1.5,5.14 0.56,1.57 h 0.97 v -0.9 l 0.79,-10.54 1.46,-12.94 1.42,-16.65 0.49,-4.69 2.32,-5.62 4.61,-3.04 3.6,1.72 2.96,4.24 -0.41,2.74 -1.76,11.44 -3.45,17.92 -2.25,12 h 1.31 l 1.5,-1.5 6.07,-8.06 10.2,-12.75 4.5,-5.06 5.25,-5.59 3.37,-2.66 h 6.37 l 4.69,6.97 -2.1,7.2 -6.56,8.32 -5.44,7.05 -7.8,10.5 -4.87,8.4 0.45,0.67 1.16,-0.11 17.62,-3.75 9.52,-1.72 11.36,-1.95 5.14,2.4 0.56,2.44 -2.02,4.99 -12.15,3 -14.25,2.85 -21.22,5.02 -0.26,0.19 0.3,0.37 9.56,0.9 4.09,0.22 h 10.01 l 18.64,1.39 4.87,3.22 2.92,3.94 -0.49,3 -7.5,3.82 -10.12,-2.4 -23.62,-5.62 -8.1,-2.02 h -1.12 v 0.67 l 6.75,6.6 12.37,11.17 15.49,14.4 0.79,3.56 -1.99,2.81 -2.1,-0.3 -13.61,-10.24 -5.25,-4.61 -11.89,-10.01 h -0.79 v 1.05 l 2.74,4.01 14.47,21.75 0.75,6.67 -1.05,2.17 -3.75,1.31 -4.12,-0.75 -8.47,-11.89 -8.74,-13.39 -7.05,-12 -0.86,0.49 -4.16,44.81 -1.95,2.29 -4.5,1.72 -3.75,-2.85 -1.99,-4.61 1.99,-9.11 2.4,-11.89 1.95,-9.45 1.76,-11.74 1.05,-3.9 -0.07,-0.26 -0.86,0.11 -8.85,12.15 -13.46,18.19 -10.65,11.4 -2.55,1.01 -4.42,-2.29 0.41,-4.09 2.47,-3.64 14.74,-18.75 8.89,-11.62 5.74,-6.71 -0.04,-0.97 h -0.34 l -39.15,25.42 -6.97,0.9 -3,-2.81 0.37,-4.61 1.42,-1.5 11.77,-8.1 -0.04,0.04 z\\'/></g>',\n },\n} as const satisfies Record<string, BrandMarkSvg>\n\nexport type BrandMarkKey = keyof typeof BRAND_MARKS\n","/**\n * Provider and vendor brand marks for the hub overview cards and the shared\n * model checklist.\n *\n * The artwork lives in brand-svg.ts as inline strings (extracted from the\n * vendored combine lockups); this module adds the presentation: a rounded,\n * brand-tinted tile for provider cards, a bare mark for model rows, and the\n * ordered model-id → vendor rules. A model no rule claims draws no mark at\n * all — a wrong vendor's mark reads as a wrong answer, not a missing one\n * (the same principle claude-style's brand.js documents).\n */\nimport { BRAND_MARKS, type BrandMarkKey } from './brand-svg.ts'\n\nexport type HubProviderId =\n | 'chatgpt' | 'antigravity' | 'command-code' | 'kimi-code'\n | 'workbuddy' | 'minimax-code' | 'claude' | 'ollama'\n\ninterface ProviderBrand {\n /** Key into BRAND_MARKS; absent for monogram-only providers. */\n mark?: BrandMarkKey\n /**\n * Text color for artwork that draws in currentColor (OpenAI's knot, Kimi's\n * K, Claude's mark). Self-colored artwork (gradients, multi-fill marks)\n * leaves this undefined.\n */\n color?: string\n /** Brand color the tile's tinted background is mixed from. */\n tile: string\n /** Monogram for providers without vendored artwork. */\n monogram?: string\n}\n\nexport const PROVIDER_BRANDS: Record<HubProviderId, ProviderBrand> = {\n chatgpt: { mark: 'openai', color: '#10A37F', tile: '#10A37F' },\n antigravity: { mark: 'gemini', tile: '#3186FF' },\n 'command-code': { monogram: '>_', color: '#7C6AEF', tile: '#7C6AEF' },\n 'kimi-code': { mark: 'kimi', color: '#1F1F1F', tile: '#1783FF' },\n workbuddy: { mark: 'tencent', tile: '#0055E9' },\n 'minimax-code': { mark: 'minimax', tile: '#E2167E' },\n claude: { mark: 'claude', color: '#D97757', tile: '#D97757' },\n ollama: { monogram: 'O', color: '#3B3B3B', tile: '#3B3B3B' },\n}\n\n/** One brand mark at a given box size; the artwork is decorative. */\nexport function BrandMark({ mark, color, size = 22 }: { mark: BrandMarkKey; color?: string; size?: number }): React.JSX.Element {\n const art = BRAND_MARKS[mark]\n return <svg\n aria-hidden=\"true\"\n viewBox={art.viewBox}\n width={size}\n height={size}\n style={color === undefined ? undefined : { color }}\n dangerouslySetInnerHTML={{ __html: art.body }}\n />\n}\n\n/**\n * The overview card's logo tile: the mark centered on a rounded square tinted\n * with the brand color, in the QQ-mail idiom. The tile element doubles as the\n * fallback surface for monogram providers.\n */\nexport function BrandTile({ id, size = 40 }: { id: HubProviderId; size?: number }): React.JSX.Element {\n const brand = PROVIDER_BRANDS[id]\n return <span\n className=\"dsh-hub-brand-tile\"\n aria-hidden=\"true\"\n style={{ width: size, height: size, ['--dsh-hub-brand' as string]: brand.tile }}\n >\n {brand.mark !== undefined\n ? <BrandMark mark={brand.mark} color={brand.color} size={Math.round(size * 0.58)} />\n : <span className=\"dsh-hub-brand-mono\" style={brand.color === undefined ? undefined : { color: brand.color }}>{brand.monogram}</span>}\n </span>\n}\n\n/**\n * The vendor that made one model, resolved from its id. Ordered: the first\n * matching rule wins, so a specific rule ('kimi') precedes a looser one.\n */\nconst MODEL_BRAND_RULES: ReadonlyArray<{ re: RegExp; mark: BrandMarkKey }> = [\n { re: /gpt|codex|o[0-9]/, mark: 'openai' },\n { re: /claude|anthropic/, mark: 'claude' },\n { re: /kimi|moonshot|\\bk[0-9]/, mark: 'kimi' },\n { re: /minimax|\\bm[0-9]/, mark: 'minimax' },\n { re: /gemini/, mark: 'gemini' },\n { re: /qwen/, mark: 'qwen' },\n { re: /deepseek/, mark: 'deepseek' },\n { re: /grok/, mark: 'grok' },\n]\n\nexport function modelBrandMark(modelId: string): BrandMarkKey | null {\n const id = modelId.toLowerCase()\n for (const rule of MODEL_BRAND_RULES) {\n if (rule.re.test(id)) return rule.mark\n }\n return null\n}\n","import type { CodexOutputVerbosity } from './contracts.ts'\n\nexport type CodexModelModality = 'text' | 'image'\n\nexport const GPT_56_MAX_CONTEXT_WINDOW = 1_000_000\n// Codex subscription limits from the model catalog; the public API advertises 1.05M\n// for these families instead.\nexport const GPT_6_MAX_CONTEXT_WINDOW = 872_000\n/** Effective context the GPT-6 family starts at, before any user override. */\nexport const GPT_6_DEFAULT_CONTEXT_WINDOW = 384_000\n/** Output cap of the GPT-6 family; the vendor declares 128K for all three. */\nexport const GPT_6_MAX_TOKENS = 128_000\n/** Output cap for the models predating the GPT-6 family. */\nexport const CODEX_DEFAULT_MAX_TOKENS = 32_768\n\nexport interface CodexModelCatalogEntry {\n id: string\n name: string\n contextWindow: number\n inputModalities: readonly CodexModelModality[]\n defaultReasoningEffort: string\n reasoningProfile: 'standard' | 'gpt-5.6' | 'gpt-6'\n supportsReasoningSummary: boolean\n /**\n * Whether the Responses `text.verbosity` control applies to this model.\n *\n * Official Codex gates the field on the catalog's own `support_verbosity`:\n * a model that does not accept it is sent none, and the official client warns\n * instead of guessing. An absent flag therefore means \"not established\" — this\n * line will not invent the field for a model it has no evidence about.\n */\n supportsOutputVerbosity?: boolean\n /**\n * Verbosity the official client sends when the user has chosen none.\n *\n * Read from the same catalog: every model the backend currently lists declares\n * `default_verbosity: \"low\"`, so \"follow the provider\" means low — not the\n * server's own (medium) fallback, which is what omitting the field gets.\n */\n defaultOutputVerbosity?: CodexOutputVerbosity\n /** Output cap when the caller omits one; falls back to {@link CODEX_DEFAULT_MAX_TOKENS}. */\n maxTokens?: number\n fallbackModelId?: string\n}\n\nexport const CODEX_MODEL_CATALOG = [\n {\n id: 'gpt-5.6-sol',\n name: '5.6 Sol',\n contextWindow: 272_000,\n inputModalities: ['text', 'image'],\n defaultReasoningEffort: 'medium',\n reasoningProfile: 'gpt-5.6',\n supportsReasoningSummary: true,\n fallbackModelId: 'gpt-5.6-terra',\n supportsOutputVerbosity: true,\n defaultOutputVerbosity: 'low',\n },\n {\n id: 'gpt-6-astra',\n name: '6 Astra',\n contextWindow: GPT_6_DEFAULT_CONTEXT_WINDOW,\n inputModalities: ['text', 'image'],\n defaultReasoningEffort: 'medium',\n reasoningProfile: 'gpt-6',\n supportsReasoningSummary: true,\n maxTokens: GPT_6_MAX_TOKENS,\n supportsOutputVerbosity: true,\n defaultOutputVerbosity: 'low',\n },\n {\n id: 'gpt-6.1-sol',\n name: '6.1 Sol',\n contextWindow: GPT_6_DEFAULT_CONTEXT_WINDOW,\n inputModalities: ['text', 'image'],\n defaultReasoningEffort: 'medium',\n reasoningProfile: 'gpt-6',\n supportsReasoningSummary: true,\n maxTokens: GPT_6_MAX_TOKENS,\n supportsOutputVerbosity: true,\n defaultOutputVerbosity: 'low',\n },\n {\n id: 'gpt-6-sol',\n name: '6 Sol',\n contextWindow: GPT_6_DEFAULT_CONTEXT_WINDOW,\n inputModalities: ['text', 'image'],\n defaultReasoningEffort: 'medium',\n reasoningProfile: 'gpt-6',\n supportsReasoningSummary: true,\n maxTokens: GPT_6_MAX_TOKENS,\n supportsOutputVerbosity: true,\n defaultOutputVerbosity: 'low',\n },\n {\n id: 'gpt-6-luna',\n name: '6 Luna',\n contextWindow: GPT_6_DEFAULT_CONTEXT_WINDOW,\n inputModalities: ['text', 'image'],\n defaultReasoningEffort: 'medium',\n reasoningProfile: 'gpt-6',\n supportsReasoningSummary: true,\n maxTokens: GPT_6_MAX_TOKENS,\n supportsOutputVerbosity: true,\n defaultOutputVerbosity: 'low',\n },\n {\n id: 'gpt-5.6-terra',\n name: '5.6 Terra',\n contextWindow: 272_000,\n inputModalities: ['text', 'image'],\n defaultReasoningEffort: 'medium',\n reasoningProfile: 'gpt-5.6',\n supportsReasoningSummary: true,\n fallbackModelId: 'gpt-5.5',\n supportsOutputVerbosity: true,\n defaultOutputVerbosity: 'low',\n },\n {\n id: 'gpt-5.6-luna',\n name: '5.6 Luna',\n contextWindow: 272_000,\n inputModalities: ['text', 'image'],\n defaultReasoningEffort: 'medium',\n reasoningProfile: 'gpt-5.6',\n supportsReasoningSummary: true,\n fallbackModelId: 'gpt-5.5',\n supportsOutputVerbosity: true,\n defaultOutputVerbosity: 'low',\n },\n {\n id: 'gpt-5.5',\n name: '5.5',\n contextWindow: 272_000,\n inputModalities: ['text', 'image'],\n defaultReasoningEffort: 'medium',\n reasoningProfile: 'standard',\n supportsReasoningSummary: true,\n supportsOutputVerbosity: true,\n defaultOutputVerbosity: 'low',\n },\n {\n id: 'gpt-5.4',\n name: '5.4',\n contextWindow: 272_000,\n inputModalities: ['text', 'image'],\n defaultReasoningEffort: 'none',\n reasoningProfile: 'standard',\n supportsReasoningSummary: true,\n fallbackModelId: 'gpt-5.4-mini',\n },\n {\n id: 'gpt-5.4-mini',\n name: '5.4 Mini',\n contextWindow: 272_000,\n inputModalities: ['text', 'image'],\n defaultReasoningEffort: 'none',\n reasoningProfile: 'standard',\n supportsReasoningSummary: true,\n },\n {\n id: 'gpt-5.3-codex-spark',\n name: '5.3 Codex Spark',\n contextWindow: 258_000,\n inputModalities: ['text'],\n defaultReasoningEffort: 'high',\n reasoningProfile: 'standard',\n supportsReasoningSummary: false,\n },\n] as const satisfies readonly CodexModelCatalogEntry[]\n\nexport type CodexModelId = typeof CODEX_MODEL_CATALOG[number]['id']\n\nexport const DEFAULT_VISIBLE_CODEX_MODEL_IDS = [\n 'gpt-6-astra',\n 'gpt-6.1-sol',\n 'gpt-6-sol',\n 'gpt-6-luna',\n 'gpt-5.6-sol',\n 'gpt-5.6-terra',\n 'gpt-5.6-luna',\n] as const satisfies readonly CodexModelId[]\n\nexport const DEFAULT_CODEX_MODEL = CODEX_MODEL_CATALOG[0]\n\nexport const STANDARD_REASONING_EFFORTS = ['none', 'low', 'medium', 'high', 'xhigh'] as const\nexport const GPT_56_REASONING_EFFORTS = [...STANDARD_REASONING_EFFORTS, 'max'] as const\n// Ultra in Codex also controls subagent orchestration; expose the Responses efforts here.\nexport const GPT_6_REASONING_EFFORTS = ['low', 'medium', 'high', 'xhigh', 'max'] as const\nexport type CodexReasoningEffort = typeof GPT_56_REASONING_EFFORTS[number]\n\nexport function reasoningEffortsForModel(model: string): readonly CodexReasoningEffort[] {\n const profile = resolveCodexCatalogEntry(model).reasoningProfile\n if (profile === 'gpt-6') return GPT_6_REASONING_EFFORTS\n return profile === 'gpt-5.6'\n ? GPT_56_REASONING_EFFORTS\n : STANDARD_REASONING_EFFORTS\n}\n\nexport function isCodexReasoningEffort(value: unknown): value is CodexReasoningEffort {\n return typeof value === 'string' && GPT_56_REASONING_EFFORTS.some((effort) => effort === value)\n}\n\nexport function modelSupportsReasoningEffort(model: string, effort: unknown): effort is CodexReasoningEffort {\n return isCodexReasoningEffort(effort) && reasoningEffortsForModel(model).some((candidate) => candidate === effort)\n}\n\nexport function isCodexModelId(model: unknown): model is CodexModelId {\n return typeof model === 'string' && CODEX_MODEL_CATALOG.some((entry) => entry.id === model)\n}\n\n/**\n * Upper bound for one model's context window override. The Codex subscription\n * caps the whole GPT-6 family at 872K and everything older at 1M, so a model's\n * catalog default is where the number starts, not where it has to stay.\n */\nexport function contextWindowLimitForModel(model: CodexModelId): number {\n return resolveCodexCatalogEntry(model).reasoningProfile === 'gpt-6'\n ? GPT_6_MAX_CONTEXT_WINDOW\n : GPT_56_MAX_CONTEXT_WINDOW\n}\n\nexport function resolveCodexCatalogEntry(model: string): CodexModelCatalogEntry {\n return CODEX_MODEL_CATALOG.find((entry) => entry.id === model) ?? DEFAULT_CODEX_MODEL\n}\n\nexport function codexModelSupportsImageInput(model: string): boolean {\n return resolveCodexCatalogEntry(model).inputModalities.includes('image')\n}\n\nexport function codexModelSupportsReasoningSummary(model: string): boolean {\n return resolveCodexCatalogEntry(model).supportsReasoningSummary\n}\n\n/**\n * One catalog entry by exact id, or undefined when this table has no record.\n *\n * Deliberately NOT {@link resolveCodexCatalogEntry}, which answers an unknown id\n * with the default entry: that substitution is the right guide for a model whose\n * capabilities only need a sensible floor, but it cannot tell \"this model\n * declares verbosity support\" apart from \"nobody said\". A wire field must not be\n * invented from silence.\n */\nfunction codexCatalogEntryById(model: string): CodexModelCatalogEntry | undefined {\n return CODEX_MODEL_CATALOG.find((entry) => entry.id === model)\n}\n\n/**\n * Verbosity to send when the user has not chosen one.\n *\n * \"Follow the provider\" has to mean what the provider's own client sends. The\n * official catalog declares `default_verbosity: \"low\"` for every model it\n * lists, so the answer is low — not the server's implicit medium, which is what\n * omitting the field gets.\n *\n * @returns the verbosity to send, or `undefined` to omit the field entirely.\n */\nexport function codexDefaultOutputVerbosity(model: string): CodexOutputVerbosity | undefined {\n const entry = codexCatalogEntryById(model)\n if (entry?.supportsOutputVerbosity !== true) return undefined\n return entry.defaultOutputVerbosity ?? 'low'\n}\n\n/**\n * Declared output ceiling for one model, or the pre-GPT-6 default when it\n * declares none.\n *\n * This is NOT a request field. The subscription Responses endpoint rejects\n * `max_output_tokens` outright (400 Unsupported parameter, issue #29 — and the\n * official CLI's own request struct has no such field), so nothing is sent to\n * the wire from here. The value reaches DSH only as the adapter's\n * `defaultMaxTokens`, which compaction uses as a local completion reservation\n * when it plans a fold; that number never leaves this process.\n */\nexport function codexModelMaxTokens(model: string): number {\n return resolveCodexCatalogEntry(model).maxTokens ?? CODEX_DEFAULT_MAX_TOKENS\n}\n\n/**\n * The effort the Responses wire accepts for one model. The GPT-6 family dropped\n * `none`/`minimal`, so a request that still carries one — a session started on an\n * older model, or the `none` default of a model this route no longer offers — is\n * sent as `low` instead of being rejected.\n */\nexport function codexWireReasoningEffort(model: string, effort: string): string {\n if (resolveCodexCatalogEntry(model).reasoningProfile !== 'gpt-6') return effort\n return effort === 'none' || effort === 'minimal' ? 'low' : effort\n}\n\nexport function resolveCodexFallbackModel(model: string): CodexModelCatalogEntry | undefined {\n const entry = resolveCodexCatalogEntry(model)\n if (!entry.fallbackModelId) return undefined\n return CODEX_MODEL_CATALOG.find((cand) => cand.id === entry.fallbackModelId)\n}\n","import { ROUTE_PREFIX } from '../compat.ts'\nimport type {\n ApiEnvelope,\n LoginEventDto,\n LoginStartDto,\n PluginStatusDto,\n QuotaStatusDto,\n ConnectionTestDto,\n SubscriptionPreferencesDto,\n SubscriptionPreferencesUpdateDto,\n} from '../shared/contracts.ts'\n\nexport class SubscriptionApi {\n status(): Promise<PluginStatusDto> {\n return request<PluginStatusDto>(`${ROUTE_PREFIX}/status`)\n }\n\n startLogin(): Promise<LoginStartDto> {\n return post<LoginStartDto>(`${ROUTE_PREFIX}/login/start`, {})\n }\n\n cancelLogin(loginId: string): Promise<{ cancelled: boolean }> {\n return post(`${ROUTE_PREFIX}/login/cancel`, { loginId })\n }\n\n /** Sign out one pooled account; without an id, the active one. */\n logout(accountId?: string): Promise<{ authenticated: false }> {\n return post(`${ROUTE_PREFIX}/logout`, accountId === undefined ? {} : { accountId })\n }\n\n /**\n * One account-pool action, returning the refreshed status.\n *\n * The host answers with the same envelope the status route uses, so the card\n * never has to guess what the pool looks like after a change.\n */\n accountAction(action: 'set-primary' | 'set-alias' | 'delete' | 'clear-cooldown' | 'strategy' | 'relogin', body: { accountId?: string; alias?: string; strategy?: string } = {}): Promise<PluginStatusDto> {\n return post<PluginStatusDto>(`${ROUTE_PREFIX}/accounts`, { action, ...body })\n }\n\n /**\n * Import this machine's Codex CLI sign-in, answering with the refreshed status.\n *\n * The body names the source rather than the URL carrying it, so the host can\n * refuse a sign-in it does not import with a sentence instead of a silent\n * no-op. The type is 'codex' alone on purpose: Claude Code and MiniMax Code are\n * imported from their own provider settings, and a union here would invite a\n * call the host always answers with a 400.\n */\n adoptLocalLogin(source: 'codex'): Promise<PluginStatusDto> {\n return post<PluginStatusDto>(`${ROUTE_PREFIX}/adopt`, { source })\n }\n\n /** Forget every imported snapshot. The CLIs' own files are never touched. */\n disableAdoptedLocalLogins(): Promise<PluginStatusDto> {\n return post<PluginStatusDto>(`${ROUTE_PREFIX}/adopt/disable`, {})\n }\n\n refresh(): Promise<PluginStatusDto> {\n return post(`${ROUTE_PREFIX}/token/refresh`, {})\n }\n\n refreshQuota(): Promise<QuotaStatusDto> {\n return post(`${ROUTE_PREFIX}/quota/refresh`, {})\n }\n\n useResetCredit(): Promise<QuotaStatusDto> {\n return post(`${ROUTE_PREFIX}/quota/reset-credit/use`, {})\n }\n\n testConnection(): Promise<ConnectionTestDto> {\n return post(`${ROUTE_PREFIX}/connection/test`, {})\n }\n\n updatePreferences(patch: SubscriptionPreferencesUpdateDto): Promise<SubscriptionPreferencesDto> {\n return post(`${ROUTE_PREFIX}/preferences/update`, patch)\n }\n\n events(loginId: string): EventSource {\n return new EventSource(`${ROUTE_PREFIX}/login/events?loginId=${encodeURIComponent(loginId)}`)\n }\n}\n\nasync function post<T>(url: string, body: object): Promise<T> {\n return request<T>(url, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(body),\n })\n}\n\nasync function request<T>(url: string, init?: RequestInit): Promise<T> {\n const response = await fetch(url, { ...init, credentials: 'same-origin' })\n const envelope = await response.json() as ApiEnvelope<T>\n if (!response.ok || !envelope.ok) {\n throw new Error(envelope.ok ? `Request failed (${response.status})` : envelope.error.message)\n }\n return envelope.value\n}\n\nexport function parseLoginEvent(event: MessageEvent<string>): LoginEventDto | null {\n try {\n const value = JSON.parse(event.data) as LoginEventDto\n return typeof value === 'object' && value !== null && typeof value.type === 'string' ? value : null\n } catch {\n return null\n }\n}\n","/**\n * The quota block that lives INSIDE one account row.\n *\n * Quota follows the account: a rotation decides which account spends the next\n * request, so a line-level quota figure describes whichever account happened to\n * be active when it was read. The host therefore reports each account's own\n * newest snapshot on that account's summary, and this renders it where the\n * account is — beside its alias, its cooldown and its last-used time.\n *\n * Every line disagrees about the wire (buckets, groups, meters, ISO strings,\n * unix seconds, remaining fractions) and agrees about the shape the host\n * normalizes into: a labeled window, a consumed share, and usually a moment it\n * reopens. Nothing here fetches: an account whose quota was never read shows\n * that it was never read, which is a different statement from \"nothing used\".\n */\nimport type { PoolAccountQuotaDto, PoolAccountQuotaWindowDto } from '../../shared/account-pool-contracts.ts'\nimport { formatPoolLabel, type AccountPoolLabels } from './account-pool-labels.ts'\n\n/** The label keys this block needs, all of them already on every tab's set. */\nexport type AccountQuotaLabels = Pick<\n AccountPoolLabels,\n 'accountQuota' | 'quotaNone' | 'quotaSnapshot' | 'quotaResets' | 'quotaExhausted' | 'quotaWindow' | 'quotaUsed'\n>\n\n/**\n * Percent with at most one decimal.\n *\n * A share that is not a finite number renders as `0%` rather than `NaN%`. Every\n * caller has already tested `Number.isFinite` and skips the row, so this is the\n * last line of defence, not a claim about an unmeasured window.\n */\nexport function formatQuotaPercent(value: number): string {\n if (!Number.isFinite(value)) return '0%'\n try {\n return `${new Intl.NumberFormat(undefined, { maximumFractionDigits: 1 }).format(value)}%`\n } catch {\n return `${value}%`\n }\n}\n\n/**\n * When a window reopens, in the reader's own words.\n *\n * Always a distance. The page's own quota block counts down (\"7天 3时\"), and a\n * row that switched to an absolute date past a threshold described the same\n * window two different ways inside one card. Days carry a long window, hours\n * the short ones, minutes the last stretch.\n */\nexport function formatQuotaReset(resetsAt: number | null | undefined, now = Date.now()): string {\n if (typeof resetsAt !== 'number' || !Number.isFinite(resetsAt) || resetsAt <= now) return '—'\n const deltaMinutes = Math.round((resetsAt - now) / 60_000)\n try {\n const relative = new Intl.RelativeTimeFormat(undefined, { numeric: 'auto' })\n if (deltaMinutes < 60) return relative.format(deltaMinutes, 'minute')\n if (deltaMinutes < 36 * 60) return relative.format(Math.round(deltaMinutes / 60), 'hour')\n return relative.format(Math.round(deltaMinutes / 1440), 'day')\n } catch {\n return '—'\n }\n}\n\n/**\n * When the snapshot was read.\n *\n * A time alone reads as \"just now\" — which is a lie about a snapshot taken\n * yesterday, and the card's whole promise is that this is what we last saw.\n */\nexport function formatQuotaSnapshot(fetchedAt: number, now = Date.now()): string {\n try {\n const sameDay = new Date(fetchedAt).toDateString() === new Date(now).toDateString()\n return new Intl.DateTimeFormat(undefined, sameDay\n ? { timeStyle: 'short' }\n : { dateStyle: 'short', timeStyle: 'short' }).format(fetchedAt)\n } catch {\n return '—'\n }\n}\n\n/** A window's name: the line's own label, else its length, else a generic one. */\nexport function quotaWindowLabel(window: PoolAccountQuotaWindowDto, labels: AccountQuotaLabels): string {\n if (window.label !== '') return window.label\n const minutes = window.windowDurationMins\n if (typeof minutes !== 'number' || !Number.isFinite(minutes) || minutes <= 0) return labels.quotaWindow\n const [value, unit]: [number, Intl.NumberFormatOptions['unit']] = minutes % 1440 === 0\n ? [minutes / 1440, 'day']\n : minutes % 60 === 0 ? [minutes / 60, 'hour'] : [Math.round(minutes), 'minute']\n try {\n return new Intl.NumberFormat(undefined, { style: 'unit', unit, unitDisplay: 'long' }).format(value)\n } catch {\n return `${value} ${unit}`\n }\n}\n\nfunction levelFor(usedPercent: number): 'normal' | 'warning' | 'danger' {\n return usedPercent >= 95 ? 'danger' : usedPercent >= 80 ? 'warning' : 'normal'\n}\n\n/**\n * One account's quota, or the honest statement that none was ever read.\n *\n * `showEmpty` lets the hosting card stay quiet on a line that has no quota to\n * speak of, while still saying \"not read yet\" for an account the line does read\n * (its active one, or any account once a sibling has a snapshot).\n */\nexport function AccountQuota(props: {\n quota: PoolAccountQuotaDto | undefined\n labels: AccountQuotaLabels\n /** True to render the \"no quota read yet\" line instead of nothing. */\n showEmpty: boolean\n now?: number\n}): React.JSX.Element | null {\n const { quota, labels } = props\n if (quota === undefined) {\n return props.showEmpty\n ? <div className=\"dsha-account-quota\"><span className=\"dsha-account-quota-empty\">{labels.quotaNone}</span></div>\n : null\n }\n const now = props.now ?? Date.now()\n return <div className=\"dsha-account-quota\">\n <span className=\"dsha-account-quota-head\">\n {labels.accountQuota}\n {quota.fetchedAt > 0 && (\n <em>{formatPoolLabel(labels.quotaSnapshot, { time: formatQuotaSnapshot(quota.fetchedAt, now) })}</em>\n )}\n </span>\n {quota.windows.length === 0\n ? <span className=\"dsha-account-quota-empty\">{labels.quotaNone}</span>\n : quota.windows.map((window, index) => {\n const percent = Number.isFinite(window.usedPercent) ? window.usedPercent : 0\n const label = quotaWindowLabel(window, labels)\n const reset = formatQuotaReset(window.resetsAt, now)\n return <div key={`${label}:${index}`} className=\"dsha-account-quota-row\" data-level={levelFor(percent)}>\n <span className=\"dsha-account-quota-name\" title={label}>{label}</span>\n <span\n className=\"dsha-account-quota-track\"\n role=\"progressbar\"\n aria-label={`${label}: ${formatQuotaPercent(percent)} ${labels.quotaUsed}`}\n aria-valuemin={0}\n aria-valuemax={100}\n aria-valuenow={percent}\n >\n <i className=\"dsha-account-quota-fill\" style={{ width: `${Math.min(100, Math.max(0, percent))}%` }} />\n </span>\n <span className=\"dsha-account-quota-value\">\n {percent >= 100 ? labels.quotaExhausted : formatQuotaPercent(percent)}\n </span>\n <span className=\"dsha-account-quota-meta\">{reset === '—' ? '—' : `${labels.quotaResets} ${reset}`}</span>\n </div>\n })}\n </div>\n}\n","import React, { type ReactNode } from 'react'\nimport type {\n AccountPoolStatusDto,\n AccountRotationStrategy,\n PoolAccountSummaryDto,\n} from '../../shared/account-pool-contracts.ts'\nimport { formatPoolLabel, type AccountPoolLabels } from './account-pool-labels.ts'\nimport { AccountQuota } from './account-quota.tsx'\n\nexport type { AccountPoolLabels } from './account-pool-labels.ts'\n\nexport interface AccountPoolSectionProps<\n TAccount extends PoolAccountSummaryDto = PoolAccountSummaryDto,\n> extends Omit<Pick<AccountPoolStatusDto, 'activeAccountId' | 'rotationStrategy'>, 'accounts'> {\n accounts: TAccount[]\n /** Label set of the hosting tab; see {@link AccountPoolLabels}. */\n labels: AccountPoolLabels\n /** Action currently in flight, used to disable every control at once. */\n busy: string | null\n /** Overrides the login button text while a sign-in flow is running. */\n loginBusyLabel?: string\n onLogin(): void\n /**\n * Replaces the single header button with the provider's own entry points.\n *\n * WorkBuddy signs in against two regional deployments, so one \"add account\"\n * button cannot express it; every other line keeps the default button.\n */\n renderLoginActions?(): ReactNode\n onSetPrimary(accountId: string): void\n onDelete(accountId: string): void\n onClearCooldown(accountId: string): void\n /** Offered on an account whose credential no longer authenticates. */\n onRelogin?(accountId: string): void\n onSetStrategy(strategy: AccountRotationStrategy): void\n /** Provider-specific detail rows, rendered before the shared ones. */\n renderDetails?(account: TAccount): ReactNode\n /**\n * Whether this line has a quota concept at all.\n *\n * Quota follows the account, so an account the host never read shows \"no\n * quota read yet\" instead of nothing — but only on a line that reads quota in\n * the first place. A line without one (Ollama: spend, no allowance) leaves\n * this off and its rows stay silent about quota.\n */\n showQuota?: boolean\n /**\n * Provider-specific per-account buttons, rendered before the shared ones.\n *\n * Used by a line that adopts accounts it does not own: hiding or restoring\n * an externally-managed account replaces the delete it must never offer.\n */\n renderAccountActions?(account: TAccount): ReactNode\n /** Extra controls inside the group, after the account list. */\n children?: ReactNode\n}\n\n/** Format one account timestamp the way every tab renders it. */\nexport function formatAccountDate(ms?: number): string {\n if (!ms || ms <= 0) return '—'\n try {\n return new Intl.DateTimeFormat(undefined, { dateStyle: 'medium', timeStyle: 'short' }).format(ms)\n } catch {\n return '—'\n }\n}\n\n/** Whole minutes left in a cooldown, never below one. */\nexport function cooldownMinutesLeft(cooldownUntil: number, now = Date.now()): number {\n return Math.max(1, Math.ceil((cooldownUntil - now) / 60_000))\n}\n\n/** Whether one account currently carries a live 429 cooldown. */\nexport function isCoolingDown(account: PoolAccountSummaryDto, now = Date.now()): boolean {\n return typeof account.cooldownUntil === 'number' && account.cooldownUntil > now\n}\n\n/**\n * The account-management group every provider tab renders.\n *\n * One component rather than four near-identical blocks: the account card, its\n * badges and the rotation-strategy picker are identical across providers, and\n * only the identity details differ.\n *\n * Credential storage is deliberately NOT shown here. Where the host keeps a\n * token is not a setting a user can act on, and rendering it as a labeled row\n * invited exactly that reading; several lines' notices went further and printed\n * the credential file's path.\n */\nexport function AccountPoolSection<TAccount extends PoolAccountSummaryDto = PoolAccountSummaryDto>(\n props: AccountPoolSectionProps<TAccount>,\n): React.ReactElement {\n const t = props.labels\n const accounts = props.accounts\n const now = Date.now()\n // One sibling holding a snapshot proves the line reads quota per account, so\n // the accounts it has not read yet may say so. Without this, a line that has\n // no quota concept would grow a row of \"not read yet\" on every account.\n const anyQuota = accounts.some((account) => account.quota !== undefined)\n\n return (\n <section className=\"dsha-group\">\n <div className=\"dsha-grouphead\">\n <h3>\n {t.accountPool}\n {accounts.length > 0 && (\n <span className=\"dsha-muted\" style={{ fontWeight: 400, marginLeft: 8 }}>\n ({formatPoolLabel(t.accountCount, { count: accounts.length })})\n </span>\n )}\n </h3>\n {props.renderLoginActions !== undefined ? props.renderLoginActions() : (\n <button className=\"dsha-btn dsha-btn-primary\" disabled={props.busy !== null} onClick={props.onLogin}>\n {props.loginBusyLabel || t.addAccount}\n </button>\n )}\n </div>\n\n {accounts.length > 1 && (\n <div className=\"dsha-pref-row\">\n <div>\n <strong>{t.rotationStrategy}</strong>\n <p className=\"dsha-muted\" style={{ fontSize: 12, marginTop: 2 }}>\n {props.rotationStrategy === 'round-robin'\n ? t.strategyRoundRobin\n : props.rotationStrategy === 'sticky' ? t.strategySticky : t.strategySequential}\n </p>\n </div>\n <select\n className=\"dsha-select\"\n aria-label={t.rotationStrategy}\n value={props.rotationStrategy}\n disabled={props.busy !== null}\n onChange={(event) => props.onSetStrategy(event.target.value as AccountRotationStrategy)}\n >\n <option value=\"sequential\">顺序耗尽</option>\n <option value=\"round-robin\">轮询调度</option>\n <option value=\"sticky\">粘性会话</option>\n </select>\n </div>\n )}\n\n {accounts.length === 0 ? (\n <div className=\"dsha-empty\">{t.noAccounts}</div>\n ) : (\n <div className=\"dsha-accounts-list\">\n {accounts.map((account) => {\n const isActive = account.id === props.activeAccountId\n const cooling = isCoolingDown(account, now)\n const needsRelogin = account.authStatus !== undefined && account.authStatus !== 'ok'\n return (\n <div key={account.id} className={`dsha-account-card ${isActive ? 'active' : ''}`}>\n <div className=\"dsha-account-header\">\n <div className=\"dsha-account-identity\">\n <span className=\"dsha-account-title\">{account.alias || account.email || account.id}</span>\n <div className=\"dsha-badges\">\n {account.isPrimary && <span className=\"dsha-badge primary\">{t.primaryAccount}</span>}\n {isActive && <span className=\"dsha-badge active\">{t.activeAccount}</span>}\n {cooling && (\n <span className=\"dsha-badge cooldown\">\n {t.cooling}({formatPoolLabel(t.cooldownLeft, { minutes: cooldownMinutesLeft(account.cooldownUntil!, now) })})\n </span>\n )}\n {needsRelogin && <span className=\"dsha-badge danger\">{t.needsRelogin}</span>}\n </div>\n </div>\n <div className=\"dsha-account-actions\">\n {props.renderAccountActions?.(account)}\n {!account.isPrimary && (\n <button\n className=\"dsha-btn\"\n disabled={props.busy !== null}\n onClick={() => props.onSetPrimary(account.id)}\n >\n {t.setPrimary}\n </button>\n )}\n {cooling && (\n <button\n className=\"dsha-btn\"\n disabled={props.busy !== null}\n onClick={() => props.onClearCooldown(account.id)}\n >\n {t.clearCooldown}\n </button>\n )}\n {needsRelogin && props.onRelogin && (\n <button\n className=\"dsha-btn\"\n disabled={props.busy !== null}\n onClick={() => props.onRelogin!(account.id)}\n >\n {t.relogin}\n </button>\n )}\n {/* An account this plugin does not own must never be\n destroyed from here; its line supplies the action. */}\n {account.removable !== false && (\n <button\n className=\"dsha-btn\"\n disabled={props.busy !== null}\n onClick={() => props.onDelete(account.id)}\n >\n {t.deleteAccount}\n </button>\n )}\n </div>\n </div>\n\n <div className=\"dsha-account-details\">\n {/* The line's own facts first, then the shared ones. Neither\n repeats the card's title: on most lines the alias IS the\n address, so printing \"邮箱: <same address>\" under a title\n that already reads as that address is the same fact twice.\n The same rule is why no line's renderDetails may render\n e-mail, expiry or last-used itself. */}\n {props.renderDetails?.(account)}\n {account.email !== undefined && account.email !== account.alias\n && <span>{t.email}: {account.email}</span>}\n {account.expiresAt !== undefined && <span>{t.expires}: {formatAccountDate(account.expiresAt)}</span>}\n {account.lastUsedAt !== undefined && <span>{t.lastUsed}: {formatAccountDate(account.lastUsedAt)}</span>}\n </div>\n <AccountQuota\n quota={account.quota}\n labels={t}\n showEmpty={props.showQuota === true || anyQuota}\n now={now}\n />\n {needsRelogin && account.authFailedReason && (\n <div className=\"dsha-account-details\">\n <span>{account.authFailedReason}</span>\n </div>\n )}\n </div>\n )\n })}\n </div>\n )}\n\n {props.children}\n </section>\n )\n}\n","/**\n * The shared \"which models appear in the picker\" list every provider section\n * renders.\n *\n * The visual language follows the claude-style model picker: one row per\n * model — vendor mark, name, a single quiet hint line (context window when\n * the catalog carries one) — with the selection state drawn as a trailing\n * check dot instead of a bare checkbox. Unlike the picker this list is\n * multi-select, so rows are `role=\"checkbox\"` and the header carries the\n * select-all / clear-all pair the old checkbox blocks had.\n *\n * One component rather than eight near-identical blocks: sections differ only\n * in where the items come from and which dictionary supplies the labels.\n */\nimport { BrandMark, modelBrandMark } from '../hub/brand-icons.tsx'\n\nexport interface ModelChecklistItem {\n id: string\n name: string\n /** One quiet line under the name (e.g. the context window); omit when none. */\n hint?: string\n enabled: boolean\n}\n\nexport interface ModelChecklistLabels {\n selectAll: string\n clearAll: string\n /**\n * `{count}` and `{total}` are replaced with the enabled/total numbers.\n * Optional: a provider dictionary without the key gets the bare \"3/8\" form.\n */\n countTemplate?: string\n /** aria-label of the list itself; omit when the section header already names it. */\n list?: string\n}\n\ninterface Props {\n items: ModelChecklistItem[]\n /** Disables every row and the header buttons while a commit is in flight. */\n busy: boolean\n onToggle(id: string, enabled: boolean): void\n onToggleAll(enabled: boolean): void\n labels: ModelChecklistLabels\n}\n\nconst CHECK_SVG = '<svg viewBox=\"0 0 16 16\" width=\"11\" height=\"11\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M3 8.5l3.2 3.2L13 5\"/></svg>'\n\nexport function ModelChecklist({ items, busy, onToggle, onToggleAll, labels }: Props): React.JSX.Element {\n const enabledCount = items.filter((item) => item.enabled).length\n const count = (labels.countTemplate ?? '{count}/{total}')\n .replace('{count}', String(enabledCount))\n .replace('{total}', String(items.length))\n return <div className=\"dsh-mcl\">\n <div className=\"dsh-mcl-head\">\n <span className=\"dsh-mcl-count\">{count}</span>\n <span className=\"dsh-mcl-head-actions\">\n <button type=\"button\" className=\"dsh-mcl-action\" disabled={busy || enabledCount === items.length} onClick={() => onToggleAll(true)}>{labels.selectAll}</button>\n <button type=\"button\" className=\"dsh-mcl-action\" disabled={busy || enabledCount === 0} onClick={() => onToggleAll(false)}>{labels.clearAll}</button>\n </span>\n </div>\n <div className=\"dsh-mcl-list\" role=\"group\" aria-label={labels.list}>\n {items.map((item) => {\n const mark = modelBrandMark(item.id)\n return <button\n key={item.id}\n type=\"button\"\n role=\"checkbox\"\n aria-checked={item.enabled}\n className=\"dsh-mcl-option\"\n data-enabled={item.enabled}\n disabled={busy}\n title={item.id}\n onClick={() => onToggle(item.id, !item.enabled)}\n >\n {mark !== null ? <BrandMark mark={mark} size={18} /> : null}\n <span className=\"dsh-mcl-copy\">\n <span className=\"dsh-mcl-name\">{item.name}</span>\n {item.hint !== undefined ? <span className=\"dsh-mcl-hint\">{item.hint}</span> : null}\n </span>\n <span className=\"dsh-mcl-check\" aria-hidden=\"true\" dangerouslySetInnerHTML={{ __html: item.enabled ? CHECK_SVG : '' }} />\n </button>\n })}\n </div>\n </div>\n}\n","/**\n * One follow-up poll after a status answer that carried a background refresh.\n *\n * The host answers a status card from the snapshot it already has and refreshes\n * the quota behind that answer, so a tab renders immediately instead of waiting\n * on the upstream request. The refreshed numbers would otherwise only appear on\n * the next 60 s poll, so an answer that reports a refresh in flight schedules\n * one short follow-up.\n *\n * The chain is bounded. A refresh that keeps failing leaves the snapshot aged,\n * so every answer would keep asking for a follow-up; after a few consecutive\n * attempts the surface falls back to its ordinary polling and stops hammering\n * the host.\n */\n\nconst FOLLOW_UP_DELAY_MS = 1_500\nconst MAX_ATTEMPTS = 3\n\nexport interface QuotaFollowUp {\n /**\n * Record one status answer.\n *\n * @param refreshing - whether the host reported a refresh behind this answer.\n * @param reload - how to ask again; used only when a follow-up is owed.\n */\n observe(refreshing: boolean, reload: () => void): void\n /** Drop any pending follow-up; call when the surface unmounts. */\n cancel(): void\n}\n\nexport function createQuotaFollowUp(\n options: { delayMs?: number; maxAttempts?: number } = {},\n): QuotaFollowUp {\n const delayMs = options.delayMs ?? FOLLOW_UP_DELAY_MS\n const maxAttempts = options.maxAttempts ?? MAX_ATTEMPTS\n let attempts = 0\n let timer: ReturnType<typeof setTimeout> | undefined\n\n return {\n observe(refreshing: boolean, reload: () => void): void {\n if (!refreshing) {\n // A settled answer ends the chain, so the next stale answer starts fresh.\n attempts = 0\n return\n }\n // One follow-up at a time: a poll landing while one is pending must not\n // stack another.\n if (timer !== undefined || attempts >= maxAttempts) return\n attempts += 1\n timer = setTimeout(() => {\n timer = undefined\n reload()\n }, delayMs)\n },\n cancel(): void {\n if (timer !== undefined) clearTimeout(timer)\n timer = undefined\n attempts = 0\n },\n }\n}","import { useCallback, useEffect, useRef, useState } from 'react'\nimport type { PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\nimport type { CodexReasoningSummary, PluginStatusDto, QuotaBucketDto, QuotaWindowDto, SearchProviderPreference, SubscriptionPreferencesUpdateDto } from '../shared/contracts.ts'\nimport { CODEX_MODEL_CATALOG, DEFAULT_VISIBLE_CODEX_MODEL_IDS, GPT_56_MAX_CONTEXT_WINDOW, contextWindowLimitForModel, resolveCodexCatalogEntry } from '../shared/model-catalog.ts'\nimport type { CodexModelId } from '../shared/model-catalog.ts'\nimport { SubscriptionApi, parseLoginEvent } from './api.ts'\nimport { AccountPoolSection, type AccountPoolLabels } from './common/AccountPoolSection.tsx'\nimport { formatPoolLabel } from './common/account-pool-labels.ts'\nimport { ModelChecklist } from './common/ModelChecklist.tsx'\nimport { createQuotaFollowUp, type QuotaFollowUp } from './common/quota-follow-up.ts'\nimport type { AccountRotationStrategy } from '../shared/account-pool-contracts.ts'\nimport { NS } from './locales.ts'\nimport { quotaWindows } from './quota.ts'\n\ntype Props = PropsRuntime<'settings.section'> & PropsLocale<typeof NS>\ntype BusyAction = 'login' | 'token' | 'quota' | 'reset-credit' | 'test' | 'logout' | 'preferences'\n | 'set-primary' | 'delete' | 'clear-cooldown' | 'strategy' | 'adopt' | 'adopt-disable' | null\ntype Translate = Props['t']\n\nexport function CodexSubscriptionSection({ t }: Props): React.JSX.Element {\n const apiRef = useRef(new SubscriptionApi())\n const eventSourceRef = useRef<EventSource | null>(null)\n /** Follow-up poll owed while the host refreshes the quota behind an answer. */\n const quotaFollowUp = useRef<QuotaFollowUp | null>(null)\n const [status, setStatus] = useState<PluginStatusDto | null>(null)\n const [busy, setBusy] = useState<BusyAction>(null)\n const [error, setError] = useState<string | null>(null)\n const [authUrl, setAuthUrl] = useState<string | null>(null)\n const [popupBlocked, setPopupBlocked] = useState(false)\n const [resetCreditNotice, setResetCreditNotice] = useState<string | null>(null)\n const [connection, setConnection] = useState<{ latencyMs: number; checkedAt: number } | null>(null)\n const [contextDrafts, setContextDrafts] = useState<Record<string, string>>({})\n const [customProxyDraft, setCustomProxyDraft] = useState<string | null>(null)\n\n const load = useCallback(async (quiet = false) => {\n if (!quiet) setError(null)\n try {\n const next = await apiRef.current.status()\n setStatus(next)\n if (next.error !== undefined) setError(next.error.message)\n // An answer that refreshed the quota behind itself is followed up shortly,\n // so the fresh numbers land without waiting for the next poll.\n quotaFollowUp.current ??= createQuotaFollowUp()\n quotaFollowUp.current.observe(next.quotaRefreshing === true, () => { void load(true) })\n } catch (cause) {\n if (!quiet) setError(messageOf(cause))\n }\n }, [])\n\n useEffect(() => {\n void load()\n const refreshWhenVisible = (): void => {\n if (document.visibilityState === 'visible') void load(true)\n }\n document.addEventListener('visibilitychange', refreshWhenVisible)\n const timer = window.setInterval(refreshWhenVisible, 60_000)\n return () => {\n window.clearInterval(timer)\n document.removeEventListener('visibilitychange', refreshWhenVisible)\n quotaFollowUp.current?.cancel()\n eventSourceRef.current?.close()\n }\n }, [load])\n\n const watchLogin = useCallback((loginId: string) => {\n eventSourceRef.current?.close()\n const source = apiRef.current.events(loginId)\n eventSourceRef.current = source\n const finish = async (message?: string): Promise<void> => {\n source.close()\n eventSourceRef.current = null\n setBusy(null)\n setAuthUrl(null)\n if (message !== undefined) setError(message)\n // Preserve the terminal OAuth error while refreshing the account DTO.\n await load(true)\n }\n source.addEventListener('completed', (event) => {\n const parsed = parseLoginEvent(event as MessageEvent<string>)\n if (parsed?.type === 'completed') void finish()\n })\n source.addEventListener('cancelled', () => void finish())\n source.addEventListener('failed', (event) => {\n const parsed = parseLoginEvent(event as MessageEvent<string>)\n void finish(parsed?.type === 'failed' ? parsed.error.message : 'ChatGPT sign-in failed.')\n })\n }, [load])\n\n useEffect(() => {\n const loginId = status?.login.active ? status.login.loginId : null\n if (loginId !== null && loginId !== undefined && eventSourceRef.current === null) watchLogin(loginId)\n }, [status?.login.active, status?.login.loginId, watchLogin])\n\n const startLogin = async (): Promise<void> => {\n setBusy('login')\n setError(null)\n setPopupBlocked(false)\n const popup = window.open('about:blank', 'dsh-chatgpt-oauth', 'popup,width=560,height=760')\n try {\n const login = await apiRef.current.startLogin()\n setAuthUrl(login.authUrl)\n if (popup === null) setPopupBlocked(true)\n else popup.location.replace(login.authUrl)\n watchLogin(login.loginId)\n await load(true)\n } catch (cause) {\n popup?.close()\n setBusy(null)\n setError(messageOf(cause))\n }\n }\n\n const cancelLogin = async (): Promise<void> => {\n const loginId = status?.login.loginId\n if (loginId === null || loginId === undefined) return\n setBusy('login')\n try {\n await apiRef.current.cancelLogin(loginId)\n eventSourceRef.current?.close()\n eventSourceRef.current = null\n setAuthUrl(null)\n await load()\n } catch (cause) {\n setError(messageOf(cause))\n } finally {\n setBusy(null)\n }\n }\n\n const refreshToken = async (): Promise<void> => run('token', async () => {\n setStatus(await apiRef.current.refresh())\n })\n\n const refreshQuota = async (): Promise<void> => run('quota', async () => {\n const quota = await apiRef.current.refreshQuota()\n setStatus((current) => current === null ? current : { ...current, quota })\n })\n\n const useResetCredit = async (): Promise<void> => {\n if (!window.confirm(t('useResetCreditConfirm'))) return\n await run('reset-credit', async () => {\n const quota = await apiRef.current.useResetCredit()\n setStatus((current) => current === null ? current : { ...current, quota })\n setResetCreditNotice(t('resetCreditUsed'))\n })\n }\n\n const testConnection = async (): Promise<void> => run('test', async () => {\n const result = await apiRef.current.testConnection()\n setConnection({ latencyMs: result.latencyMs, checkedAt: result.checkedAt })\n })\n\n const updatePreferences = async (patch: SubscriptionPreferencesUpdateDto): Promise<void> => run('preferences', async () => {\n const preferences = await apiRef.current.updatePreferences(patch)\n setStatus((current) => current === null ? current : { ...current, preferences })\n })\n\n const selectSearchProvider = (provider: SearchProviderPreference): void => {\n setStatus(current => current ? { ...current, preferences: { ...current.preferences, searchProvider: provider } } : current)\n void updatePreferences({ searchProvider: provider })\n }\n\n const toggleVisibleModel = async (modelId: string, checked: boolean): Promise<void> => {\n const current = status?.preferences.visibleModelIds ?? [...DEFAULT_VISIBLE_CODEX_MODEL_IDS]\n const visibleModelIds = checked ? [...current, modelId] : current.filter(id => id !== modelId)\n await updatePreferences({ visibleModelIds })\n }\n\n const setAllVisibleModels = async (selectAll: boolean): Promise<void> => {\n const visibleModelIds = selectAll ? CODEX_MODEL_CATALOG.map(m => m.id) : []\n await updatePreferences({ visibleModelIds })\n }\n\n const updateContextWindow = async (model: CodexModelId): Promise<void> => {\n const current = status?.preferences.contextWindowOverrides[model] ?? resolveCodexCatalogEntry(model).contextWindow\n const parsed = parseCapacity(contextDrafts[model] ?? String(current), contextWindowLimitForModel(model))\n if (parsed === null) {\n setError(t('contextWindowInvalid'))\n return\n }\n await updatePreferences({ contextWindowOverrides: { [model]: parsed } })\n setContextDrafts((drafts) => ({ ...drafts, [model]: String(parsed) }))\n }\n\n /** Drop one model's override; the row falls back to the catalog value. */\n const resetContextWindow = async (model: CodexModelId): Promise<void> => {\n await updatePreferences({ contextWindowOverrides: { [model]: null } })\n setContextDrafts((drafts) => ({ ...drafts, [model]: formatCapacity(resolveCodexCatalogEntry(model).contextWindow) }))\n }\n\n /** Clear every stored override, including models the picker no longer shows. */\n const resetAllContextWindows = async (): Promise<void> => {\n const models = Object.keys(status?.preferences.contextWindowOverrides ?? {})\n if (models.length === 0) return\n if (!window.confirm(t('contextWindowResetAllConfirm'))) return\n await updatePreferences({ contextWindowOverrides: Object.fromEntries(models.map((model) => [model, null])) })\n setContextDrafts({})\n }\n\n const updateCustomProxyUrl = async (): Promise<void> => {\n const draft = customProxyDraft?.trim()\n await updatePreferences({ customProxyUrl: draft ? draft : null })\n setCustomProxyDraft(null)\n }\n\n /**\n * The shared card takes a label object while this tab translates by key, so\n * every pool label is resolved through the tab's own translator and follows\n * whichever locale is active.\n */\n const poolLabels: AccountPoolLabels = {\n accountPool: t('accountPool'),\n addAccount: t('addAccount'),\n accountCount: t('accountCount'),\n primaryAccount: t('primaryAccount'),\n activeAccount: t('activeAccount'),\n setPrimary: t('setPrimary'),\n deleteAccount: t('deleteAccount'),\n cooling: t('cooling'),\n cooldownLeft: t('cooldownLeft'),\n clearCooldown: t('clearCooldown'),\n needsRelogin: t('needsRelogin'),\n relogin: t('relogin'),\n rotationStrategy: t('rotationStrategy'),\n strategySequential: t('strategySequential'),\n strategyRoundRobin: t('strategyRoundRobin'),\n strategySticky: t('strategySticky'),\n noAccounts: t('noAccounts'),\n email: t('email'),\n expires: t('expires'),\n lastUsed: t('lastUsed'),\n accountId: t('accountId'),\n accountQuota: t('accountQuota'),\n quotaNone: t('quotaNone'),\n quotaSnapshot: t('quotaSnapshot'),\n quotaResets: t('quotaResets'),\n quotaExhausted: t('quotaExhausted'),\n quotaWindow: t('quotaWindow'),\n quotaUsed: t('quotaUsed'),\n quotaFactsScope: t('quotaFactsScope'),\n composerLabel: t('composerLabel'),\n }\n\n const accountAction = async (\n action: 'set-primary' | 'delete' | 'clear-cooldown',\n accountId: string,\n ): Promise<void> => {\n await run(action, async () => {\n const next = await apiRef.current.accountAction(action, { accountId })\n setStatus(next)\n })\n }\n\n /**\n * Forget every imported snapshot: the undo for the local sign-in import below.\n *\n * ONE control for the whole pool rather than one per row, because the host's\n * route deliberately ignores an accountId and clears every imported row at once.\n * That is not an oversight to route around: the pool refuses to delete an\n * adopted credential, so a per-row control here could only ever be a button that\n * silently clears its neighbours — a worse bug than offering no button at all.\n * The Codex CLI's own file is not deleted, rewritten or moved by this; it only\n * makes this plugin forget the copy it took.\n */\n const stopImporting = async (): Promise<void> => {\n await run('adopt-disable', async () => {\n setStatus(await apiRef.current.disableAdoptedLocalLogins())\n })\n }\n\n /**\n * Copy this machine's Codex CLI sign-in into the pool as a snapshot.\n *\n * The status is re-read rather than taken from the route's answer: the route\n * answers with the pool's refreshed status, which knows nothing about the\n * CLI file, so adopting from its value would flip the block to \"not detected\"\n * one click after the import succeeded. The file is still there — the import\n * copies it — so /status is the answer that tells the truth, and the row the\n * account just created comes back with it.\n */\n const importLocalSignIn = async (): Promise<void> => {\n await run('adopt', async () => {\n await apiRef.current.adoptLocalLogin('codex')\n await load(true)\n })\n }\n\n const setRotationStrategy = async (strategy: AccountRotationStrategy): Promise<void> => {\n await run('strategy', async () => {\n const next = await apiRef.current.accountAction('strategy', { strategy })\n setStatus(next)\n })\n }\n\n /**\n * Re-authorize one account.\n *\n * The failure marker is cleared first and nothing is deleted: the account\n * keeps its alias and place in the rotation.\n */\n const relogin = (accountId: string): void => {\n void (async () => {\n try {\n const next = await apiRef.current.accountAction('relogin', { accountId })\n setStatus(next)\n } catch (cause) {\n setError(messageOf(cause))\n return\n }\n await startLogin()\n })()\n }\n\n const logout = async (): Promise<void> => run('logout', async () => {\n await apiRef.current.logout()\n eventSourceRef.current?.close()\n eventSourceRef.current = null\n setAuthUrl(null)\n setConnection(null)\n await load()\n })\n\n const run = async (action: Exclude<BusyAction, null>, task: () => Promise<void>): Promise<void> => {\n setBusy(action)\n setError(null)\n setResetCreditNotice(null)\n try {\n await task()\n } catch (cause) {\n setError(messageOf(cause))\n } finally {\n setBusy(null)\n }\n }\n\n // `removable: false` is the shared summary DTO's own signal for a borrowed\n // credential (it is what suppresses Delete on the shared card). The Codex pool\n // also puts an `adopted` flag on the wire, but that field is not in the shared\n // contract this tab is typed against, so the declared one is what is read.\n const importedAccounts = (status?.accounts ?? []).filter((account) => account.removable === false)\n const account = status?.account\n const preferences = status?.preferences\n const quota = status?.quota\n const login = status?.login\n const visibleModelIds = preferences?.visibleModelIds ?? DEFAULT_VISIBLE_CODEX_MODEL_IDS\n // Only checked models get a context row, in catalog order.\n const contextModels = CODEX_MODEL_CATALOG.filter((entry) => visibleModelIds.some((id) => id === entry.id))\n const overrideCount = Object.keys(preferences?.contextWindowOverrides ?? {}).length\n return <section className=\"dsha-page\" aria-labelledby=\"dsh-codex-title\">\n <header>\n <h2 id=\"dsh-codex-title\" className=\"dsh-codex-title\">{t('title')}</h2>\n <p className=\"dsh-codex-intro\">{t('intro')}</p>\n </header>\n\n {error !== null ? <div className=\"dsh-codex-errorbar\" role=\"alert\">\n <span>{error}</span>\n {status === null ? <Button disabled={busy !== null} onClick={() => load()}>{t('retry')}</Button> : null}\n </div> : null}\n\n {status === null && error === null ? <Skeleton label={t('loading')} /> : <>\n <AccountPoolSection\n accounts={status?.accounts ?? []}\n activeAccountId={status?.activeAccountId}\n rotationStrategy={status?.rotationStrategy ?? 'sequential'}\n busy={busy}\n labels={poolLabels}\n loginBusyLabel={login?.active ? t('pending') : undefined}\n onLogin={() => void startLogin()}\n onSetPrimary={(accountId) => void accountAction('set-primary', accountId)}\n onDelete={(accountId) => void accountAction('delete', accountId)}\n onClearCooldown={(accountId) => void accountAction('clear-cooldown', accountId)}\n onRelogin={(accountId) => relogin(accountId)}\n onSetStrategy={(strategy) => void setRotationStrategy(strategy)}\n showQuota\n renderLoginActions={() => (\n // The pool card's own login row, in the shape the Claude section uses:\n // the sign-in keeps the primary treatment, and a sign-in that already\n // exists on this machine sits beside it as the alternative way in.\n //\n // The first button REPRODUCES the shared card's default login button\n // (same classes, same label, same disable rule), because taking the row\n // over means reproducing it — nothing about signing in changes here.\n <div className=\"dsha-account-add-actions\">\n <button\n className=\"dsha-btn dsha-btn-primary\"\n disabled={busy !== null}\n onClick={() => void startLogin()}\n >\n {login?.active ? t('pending') : t('addAccount')}\n </button>\n {/* The second entry: a local Codex CLI sign-in can be imported instead\n of running a fresh ChatGPT OAuth flow.\n\n ALWAYS RENDERED, exactly as the Claude section renders its own —\n including when the host found no sign-in, which is the decision\n stated here rather than left to drift: a button that DISAPPEARS\n when there is nothing to import cannot answer whether one exists,\n and \"is my CLI signed in here?\" is the question this row is here to\n answer. Clicking it with nothing there is not a dead end and needs\n no substitute prose: the host refuses in a sentence, and that\n sentence lands in the card's existing error strip. */}\n <button\n className=\"dsha-btn\"\n disabled={busy !== null}\n aria-label={t('localCodexLoginImport')}\n onClick={() => void importLocalSignIn()}\n >\n {busy === 'adopt' ? t('localCodexLoginImporting') : t('localCodexLoginImport')}\n </button>\n </div>\n )}\n renderDetails={(entry) => (\n <>\n {entry.planLabel && <span>{t('plan')}: {entry.planLabel}</span>}\n </>\n )}\n >\n {login?.active ? <p className=\"dsha-muted\" role=\"status\">{t('pending')}</p> : null}\n {popupBlocked ? <p className=\"dsh-codex-error\">{t('popupBlocked')}</p> : null}\n {authUrl !== null ? <a className=\"dsh-codex-link\" href={authUrl} target=\"_blank\" rel=\"noreferrer\">{t('continueLogin')}</a> : null}\n <div className=\"dsha-actions\">\n {login?.active ? <Button disabled={busy !== null} onClick={cancelLogin}>{t('cancel')}</Button> : null}\n {status?.authenticated ? <Button disabled={busy !== null} onClick={refreshToken}>{t('refreshToken')}</Button> : null}\n </div>\n {/* The imported rows have no Delete (the shared card hides it for a\n borrowed credential), so without the import button above this would be\n a one-way door. Rendered once, below the list, and its label says \"all\":\n the route it calls forgets every snapshot at once. */}\n {importedAccounts.length > 0 ? (\n <>\n <p className=\"dsha-muted\">{formatPoolLabel(t('stopImportingHint'), { count: importedAccounts.length })}</p>\n <div className=\"dsha-actions\">\n <button\n className=\"dsha-btn\"\n type=\"button\"\n disabled={busy !== null}\n aria-label={formatPoolLabel(t('stopImportingLabel'), { count: importedAccounts.length })}\n onClick={() => void stopImporting()}\n >{busy === 'adopt-disable' ? t('stopImportingBusy') : t('stopImporting')}</button>\n </div>\n </>\n ) : null}\n </AccountPoolSection>\n\n <Section title={t('connection')}>\n {connection !== null ? <InfoRow label={t('latency')} value={`${connection.latencyMs} ms · ${formatDate(connection.checkedAt)}`} /> : null}\n <p className=\"dsha-muted dsha-models-hint\">{t('modelsHint')}</p>\n <ModelChecklist\n items={CODEX_MODEL_CATALOG.map((model) => ({\n id: model.id,\n name: model.name,\n hint: `${formatCapacity(model.contextWindow)} ${t('tokens')}`,\n enabled: visibleModelIds.some(id => id === model.id),\n }))}\n busy={busy !== null}\n onToggle={(id, enabled) => void toggleVisibleModel(id, enabled)}\n onToggleAll={(enabled) => void setAllVisibleModels(enabled)}\n labels={{ selectAll: t('selectAll'), clearAll: t('unselectAll'), countTemplate: t('modelChecklistCount'), list: t('models') }}\n />\n <div className=\"dsha-actions\">\n <Button disabled={!status?.authenticated || busy !== null} onClick={testConnection}>{busy === 'test' ? t('testing') : t('testConnection')}</Button>\n </div>\n </Section>\n\n <Section title={t('proxySettings')}>\n <div className=\"dsha-pref-row\">\n <div>\n <strong>{t('proxyMode')}</strong>\n <p className=\"dsha-muted\">{t('proxyModeHint')}</p>\n </div>\n <select\n className=\"dsha-select\"\n aria-label={t('proxyMode')}\n value={preferences?.proxyMode ?? 'auto'}\n disabled={busy !== null}\n onChange={(event) => {\n const mode = event.currentTarget.value as 'auto' | 'custom' | 'direct'\n setStatus(current => current ? { ...current, preferences: { ...current.preferences, proxyMode: mode } } : current)\n void updatePreferences({ proxyMode: mode })\n }}\n >\n <option value=\"auto\">{t('proxyModeAuto')}</option>\n <option value=\"custom\">{t('proxyModeCustom')}</option>\n <option value=\"direct\">{t('proxyModeDirect')}</option>\n </select>\n </div>\n\n {(preferences?.proxyMode ?? 'auto') === 'auto' ? <div className=\"dsh-codex-proxy-status\">\n {status?.detectedProxy ? <>\n <span>{t('proxyDetected')}:</span>\n <code className=\"dsh-codex-proxy-tag\">{status.detectedProxy}</code>\n <span className=\"dsh-codex-success\">{t('proxyDetectedEffective')}</span>\n </> : <span className=\"dsha-muted\">{t('proxyNoneDetected')}</span>}\n </div> : null}\n\n {preferences?.proxyMode === 'direct' ? <p className=\"dsha-muted\" style={{ margin: '8px 0 0' }}>{t('proxyDirectHint')}</p> : null}\n\n {preferences?.proxyMode === 'custom' ? <div className=\"dsha-context-settings\">\n <div>\n <strong>{t('customProxyUrl')}</strong>\n <p className=\"dsha-muted\">{t('customProxyUrlHint')}</p>\n </div>\n <div className=\"dsha-context-row\">\n <span className=\"dsh-codex-proxy-control\">\n <input\n id=\"dsh-codex-custom-proxy\"\n type=\"text\"\n placeholder={t('customProxyUrlPlaceholder')}\n value={customProxyDraft ?? (preferences?.customProxyUrl ?? '')}\n disabled={busy !== null}\n aria-label={t('customProxyUrl')}\n onChange={(event) => {\n setCustomProxyDraft(event.currentTarget.value)\n }}\n onKeyDown={(event) => {\n if (event.key !== 'Enter') return\n event.preventDefault()\n void updateCustomProxyUrl()\n }}\n />\n <button\n className=\"dsha-context-save\"\n type=\"button\"\n aria-label={t('saveProxyUrl')}\n disabled={busy !== null || customProxyDraft === null}\n onClick={() => void updateCustomProxyUrl()}\n >\n {t('save')}\n </button>\n </span>\n </div>\n </div> : null}\n </Section>\n\n <Section title={t('enhancements')}>\n <div className=\"dsha-pref-row\">\n <div>\n <strong>{t('searchProvider')}</strong>\n <p className=\"dsha-muted\">{t('searchProviderHint')}</p>\n </div>\n <div className=\"dsh-codex-segments\" role=\"group\" aria-label={t('searchProvider')}>\n <button\n type=\"button\"\n className={preferences?.searchProvider === 'dsh' ? 'active' : ''}\n aria-pressed={preferences?.searchProvider === 'dsh'}\n disabled={busy !== null}\n onClick={() => selectSearchProvider('dsh')}\n >\n {t('searchProviderDsh')}\n </button>\n <button\n type=\"button\"\n className={preferences?.searchProvider === 'codex' ? 'active' : ''}\n aria-pressed={preferences?.searchProvider === 'codex'}\n disabled={busy !== null}\n onClick={() => selectSearchProvider('codex')}\n >\n {t('searchProviderCodex')}\n </button>\n </div>\n </div>\n <FetchProviderStatusCard status={status} t={t} />\n <div className=\"dsha-pref-row\">\n <div>\n <strong>{t('outputVerbosity')}</strong>\n <p className=\"dsha-muted\">{t('outputVerbosityHint')}</p>\n </div>\n <select className=\"dsha-select\" aria-label={t('outputVerbosity')} value={preferences?.outputVerbosity ?? ''} disabled={busy !== null} onChange={(event) => {\n const value = event.currentTarget.value\n void updatePreferences({ outputVerbosity: value === '' ? null : value as 'low' | 'medium' | 'high' })\n }}>\n <option value=\"\">{t('providerDefault')}</option>\n <option value=\"low\">{t('verbosityLow')}</option>\n <option value=\"medium\">{t('verbosityMedium')}</option>\n <option value=\"high\">{t('verbosityHigh')}</option>\n </select>\n </div>\n <div className=\"dsha-pref-row\">\n <div>\n <strong>{t('reasoningSummary')}</strong>\n <p className=\"dsha-muted\">{t('reasoningSummaryHint')}</p>\n </div>\n <select className=\"dsha-select\" aria-label={t('reasoningSummary')} value={preferences?.reasoningSummary ?? ''} disabled={busy !== null} onChange={(event) => {\n const value = event.currentTarget.value\n void updatePreferences({ reasoningSummary: value === '' ? null : value as CodexReasoningSummary })\n }}>\n <option value=\"\">{t('providerDefault')}</option>\n <option value=\"auto\">{t('summaryAuto')}</option>\n <option value=\"concise\">{t('summaryConcise')}</option>\n <option value=\"detailed\">{t('summaryDetailed')}</option>\n <option value=\"none\">{t('summaryNone')}</option>\n </select>\n </div>\n <div className=\"dsha-context-settings\">\n <div>\n <strong>{t('contextWindows')}</strong>\n <p className=\"dsha-muted\">{t('contextWindowsHint')}</p>\n </div>\n {contextModels.length === 0 ? <p className=\"dsha-muted\">{t('contextWindowsNoneEnabled')}</p> : null}\n {contextModels.map((entry) => {\n const model = entry.id\n const fallback = preferences?.contextWindowOverrides?.[model] ?? entry.contextWindow\n const draft = contextDrafts[model]\n const parsedDraft = draft === undefined ? fallback : parseCapacity(draft, contextWindowLimitForModel(model))\n const dirty = draft !== undefined && parsedDraft !== fallback\n const overridden = preferences?.contextWindowOverrides?.[model] !== undefined\n const inputId = `dsh-codex-context-${model}`\n return <div className=\"dsha-context-row\" key={model}>\n <label htmlFor={inputId}>{entry.name}</label>\n <span className=\"dsha-capacity-control\">\n <input id={inputId} type=\"text\" inputMode=\"numeric\" value={draft ?? formatCapacity(fallback)} disabled={busy !== null} aria-label={entry.name + ' ' + t('contextWindow')} onChange={(event) => {\n const value = event.currentTarget.value\n setContextDrafts((drafts) => ({ ...drafts, [model]: value }))\n }} onKeyDown={(event) => {\n if (event.key !== 'Enter' || !dirty) return\n event.preventDefault()\n void updateContextWindow(model)\n }} />\n <small>{t('tokens')}</small>\n <button className=\"dsha-context-save\" type=\"button\" data-model={model} aria-label={entry.name + ' ' + t('saveContextWindow')} disabled={busy !== null || !dirty} onClick={() => void updateContextWindow(model)}>{t('save')}</button>\n <button className=\"dsha-context-save dsha-context-reset\" type=\"button\" data-reset-model={model} aria-label={entry.name + ' ' + t('contextWindowReset')} disabled={busy !== null || !overridden} onClick={() => void resetContextWindow(model)}>{t('contextWindowReset')}</button>\n </span>\n </div>\n })}\n <div className=\"dsha-actions\">\n <Button disabled={busy !== null || overrideCount === 0} onClick={resetAllContextWindows}>{t('contextWindowResetAll')}</Button>\n </div>\n </div>\n <label className=\"dsh-codex-check\">\n <input type=\"checkbox\" checked={preferences?.fastMode === true} disabled={busy !== null} onChange={(event) => updatePreferences({ fastMode: event.currentTarget.checked })} />\n <span>\n <strong>{t('fastMode')}</strong>\n <small>{t('fastModeHint')}</small>\n </span>\n </label>\n <label className=\"dsh-codex-check\">\n <input type=\"checkbox\" checked={preferences?.quickQuotaVisible === true} disabled={busy !== null} onChange={(event) => updatePreferences({ quickQuotaVisible: event.currentTarget.checked })} />\n <span>\n <strong>{t('quickQuota')}</strong>\n <small>{t('quickQuotaHint')}</small>\n </span>\n </label>\n </Section>\n\n <Section title={t('quota')} aside={<Button disabled={!status?.authenticated || busy !== null} onClick={refreshQuota}>{busy === 'quota' ? t('refreshing') : t('refreshQuota')}</Button>}>\n <p className=\"dsha-muted\">{t('quotaIntro')}</p>\n {/* The progress bars moved into each account card: quota follows the\n account, so a bar here could only ever describe whichever account\n happened to be active when the snapshot was read. What stays is what\n has no per-account bar to live in — the plan, the credits, the\n monthly spend, the reset cards and the freshness of this reading. */}\n <p className=\"dsha-muted\">{poolLabels.quotaFactsScope}</p>\n {quota?.state === 'signed-out' || !status?.authenticated ? <p className=\"dsh-codex-empty\">{t('quotaSignedOut')}</p> : null}\n {quota?.buckets?.map((bucket) => <QuotaFact key={bucket.id} label={bucket.name} value={bucket.planType ?? '—'} />)}\n {quota?.credits !== null && quota?.credits !== undefined ? <QuotaFact label={t('credits')} value={quota.credits.unlimited ? t('unlimited') : quota.credits.balance ?? (quota.credits.hasCredits ? t('available') : t('unavailable'))} /> : null}\n {quota?.individualLimit !== null && quota?.individualLimit !== undefined ? <QuotaFact label={t('monthlySpend')} value={individualLimitLabel(quota.individualLimit, t)} /> : null}\n {quota?.resetCredits !== null && quota?.resetCredits !== undefined ? <ResetCreditsFact resetCredits={quota.resetCredits} busy={busy} onUse={useResetCredit} t={t} /> : null}\n {resetCreditNotice !== null ? <p className=\"dsh-codex-success\" role=\"status\">{resetCreditNotice}</p> : null}\n {quota?.spendControlReached === true ? <p className=\"dsh-codex-warning\" role=\"status\">{t('spendControlReached')}</p> : null}\n {quota?.state === 'empty' ? <p className=\"dsh-codex-empty\">{t('noQuota')}</p> : null}\n {quota?.stale ? <p className=\"dsh-codex-warning\" role=\"status\">{t('stale')}</p> : null}\n {quota?.error ? <p className=\"dsh-codex-error\" role=\"alert\">{quota.error.message}</p> : null}\n {quota?.fetchedAt ? <p className=\"dsh-codex-timestamp\">{t('updated')}: {formatDate(quota.fetchedAt)}</p> : null}\n </Section>\n </>}\n\n <span className=\"dsh-codex-sr\" aria-live=\"polite\">{busy === null ? '' : busy}</span>\n </section>\n}\n\nfunction Section({ title, aside, children }: { title: string; aside?: React.ReactNode; children: React.ReactNode }): React.JSX.Element {\n return <section className=\"dsha-group\">\n <div className=\"dsha-grouphead\"><h3>{title}</h3>{aside}</div>\n {children}\n </section>\n}\n\nfunction Button({ primary = false, disabled, onClick, children }: { primary?: boolean; disabled?: boolean; onClick: () => void | Promise<void>; children: React.ReactNode }): React.JSX.Element {\n return <button className={`dsha-btn${primary ? ' dsha-btn-primary' : ''}`} type=\"button\" disabled={disabled} onClick={() => void onClick()}>{children}</button>\n}\n\nfunction InfoRow({ label, value }: { label: string; value: string }): React.JSX.Element {\n return <div className=\"dsha-row\"><span className=\"dsha-label\">{label}</span><span className=\"dsha-value\">{value}</span></div>\n}\n\nconst SWITCHER_STATE_LABELS = {\n idle: 'switcherStateIdle',\n applying: 'switcherStateApplying',\n applied: 'switcherStateApplied',\n missing: 'switcherStateMissing',\n failed: 'switcherStateFailed',\n} as const\n\nconst FETCH_MODE_LABELS = {\n auto: 'fetchModeAuto',\n plugin: 'fetchModePlugin',\n dsh: 'fetchModeDsh',\n} as const\n\n/**\n * Read-only view of the fetch selection, shown under the search source.\n *\n * Both blocks are optional on the status DTO, so every row is rendered only from\n * a value the host actually reported. That distinction is load-bearing: a\n * missing `switcher` means the host tells us nothing and the row stays hidden,\n * while a reported `configuredFetchProvider: null` is a real answer — the host\n * pinned no provider, which is the DSH default. Guessing an id there would claim\n * a provider the settings page never observed.\n *\n * Nothing here is editable: the mode and the limits live in the plugin Config,\n * not in the preferences this card sits in, so the numbers cannot be mistaken for\n * a setting that this page can change.\n */\nexport function FetchProviderStatusCard({ status, t }: { status: PluginStatusDto | null | undefined; t: Translate }): React.JSX.Element | null {\n const switcher = status?.switcher\n const configuration = status?.fetchConfiguration\n if (switcher === undefined && configuration === undefined) return null\n const state = switcher !== null && switcher !== undefined && switcher.state in SWITCHER_STATE_LABELS\n ? switcher.state\n : null\n const mode = configuration !== undefined && configuration.fetchProvider in FETCH_MODE_LABELS\n ? configuration.fetchProvider\n : undefined\n const maxBodyChars = fetchLimit(configuration?.fetchMaxBodyChars)\n const maxResponseBytes = fetchLimit(configuration?.fetchMaxResponseBytes)\n return <div className=\"dsha-context-settings\" data-fetch-status={state ?? 'none'}>\n <div>\n <strong>{t('fetchStatus')}</strong>\n <p className=\"dsha-muted\">{t('fetchStatusHint')}</p>\n </div>\n {switcher !== null && switcher !== undefined ? <InfoRow\n label={t('fetchConfiguredProvider')}\n value={switcher.configuredFetchProvider || t('fetchProviderDshDefault')}\n /> : null}\n {state !== null ? <InfoRow label={t('switcherState')} value={t(SWITCHER_STATE_LABELS[state])} /> : null}\n {mode !== undefined ? <InfoRow label={t('fetchMode')} value={t(FETCH_MODE_LABELS[mode])} /> : null}\n {maxBodyChars !== null ? <InfoRow label={t('fetchMaxBodyChars')} value={`${maxBodyChars} ${t('characters')}`} /> : null}\n {maxResponseBytes !== null ? <InfoRow label={t('fetchMaxResponseBytes')} value={`${maxResponseBytes} ${t('bytes')}`} /> : null}\n {mode !== undefined && mode !== 'plugin' ? <p className=\"dsha-muted\">{t('fetchLimitsInactive')}</p> : null}\n <p className=\"dsha-muted\">{t('fetchConfigSource')}</p>\n </div>\n}\n\n/** A limit is shown only once it is the positive safe integer the Config promises. */\nfunction fetchLimit(value: number | undefined): number | null {\n return value !== undefined && Number.isSafeInteger(value) && value >= 1 ? value : null\n}\n\nfunction QuotaFact({ label, value }: { label: string; value: string }): React.JSX.Element {\n return <div className=\"dsh-codex-quota-fact\"><span>{label}</span><strong>{value}</strong></div>\n}\n\nexport function ResetCreditsFact({ resetCredits, busy, onUse, t }: { resetCredits: NonNullable<PluginStatusDto['quota']['resetCredits']>; busy: BusyAction; onUse: () => Promise<void>; t: Translate }): React.JSX.Element {\n const available = resetCredits.availableCount > 0\n return <div className=\"dsh-codex-reset-credits\">\n <div className=\"dsh-codex-reset-credits-info\">\n <span>{t('resetCredits')}</span>\n <strong>{resetCredits.availableCount}</strong>\n <small>{t('resetCreditExpires')}: {resetCredits.expiresAt == null ? t('unknown') : formatReset(resetCredits.expiresAt)}</small>\n </div>\n <Button primary disabled={!available || busy !== null} onClick={onUse}>{busy === 'reset-credit' ? t('usingResetCredit') : t('useResetCredit')}</Button>\n </div>\n}\n\nexport function QuotaBar({ label, window, t }: { label: string; window: QuotaWindowDto; t: Translate }): React.JSX.Element {\n const percent = typeof window?.usedPercent === 'number' && Number.isFinite(window.usedPercent) ? window.usedPercent : 0\n const level = percent >= 95 ? 'danger' : percent >= 80 ? 'warning' : 'normal'\n const remaining = Math.max(0, 100 - percent)\n return <div className=\"dsh-codex-meter-wrap\">\n <div className=\"dsh-codex-meter-label\"><span>{label}</span><strong>{formatPercent(percent)}</strong></div>\n <div className={`dsh-codex-meter dsh-codex-meter-${level}`} role=\"progressbar\" aria-label={`${label}: ${formatPercent(percent)} ${t('used')}`} aria-valuemin={0} aria-valuemax={100} aria-valuenow={percent}>\n <span style={{ width: `${Math.min(100, Math.max(0, percent))}%` }} />\n </div>\n <div className=\"dsh-codex-meter-meta\">\n <span>{percent >= 100 ? `${t('exhausted')} · ${formatPercent(remaining)} ${t('remaining')}` : `${formatPercent(percent)} ${t('used')} · ${formatPercent(remaining)} ${t('remaining')}`}</span>\n <span>{window?.resetsAt == null ? '—' : `${t('resets')}: ${formatReset(window.resetsAt)}`}</span>\n </div>\n </div>\n}\n\nfunction Skeleton({ label }: { label: string }): React.JSX.Element {\n return <div className=\"dsh-codex-skeleton\" role=\"status\" aria-label={label}><span /><span /></div>\n}\n\nexport function windowLabel(minutes: number | null | undefined, t: Translate): string {\n if (minutes === null || minutes === undefined || typeof minutes !== 'number' || !Number.isFinite(minutes) || minutes <= 0) return t('limitWindow')\n const [value, unit]: [number, Intl.NumberFormatOptions['unit']] = minutes >= 1440 && minutes % 1440 === 0\n ? [minutes / 1440, 'day']\n : minutes >= 60 && minutes % 60 === 0\n ? [minutes / 60, 'hour']\n : [Math.round(minutes), 'minute']\n try {\n return `${new Intl.NumberFormat(undefined, { style: 'unit', unit, unitDisplay: 'long' }).format(value)} ${t('limitWindow')}`\n } catch {\n return `${value} ${t('limitWindow')}`\n }\n}\n\nexport function parsePositiveCapacity(value: string): number | null {\n const normalized = value.trim().toLowerCase().replace(/[,_\\s]/g, '')\n const matched = normalized.match(/^(\\d+(?:\\.\\d+)?)(k|m)?$/)\n if (matched === null) return null\n const multiplier = matched[2] === 'm' ? 1_000_000 : matched[2] === 'k' ? 1_000 : 1\n const parsed = Number(matched[1]) * multiplier\n return Number.isSafeInteger(parsed) && parsed >= 1 ? parsed : null\n}\n\nexport function parseCapacity(value: string, maxContextWindow = GPT_56_MAX_CONTEXT_WINDOW): number | null {\n const parsed = parsePositiveCapacity(value)\n return parsed !== null && parsed <= maxContextWindow ? parsed : null\n}\n\nfunction formatCapacity(value: number): string {\n if (value % 1_000 === 0) return `${value / 1_000}K`\n return String(value)\n}\n\nfunction formatPercent(value: number | undefined | null): string {\n if (value === undefined || value === null || typeof value !== 'number' || !Number.isFinite(value)) return '0%'\n try {\n return `${new Intl.NumberFormat(undefined, { maximumFractionDigits: 1 }).format(value)}%`\n } catch {\n return `${value}%`\n }\n}\n\nfunction individualLimitLabel(limit: NonNullable<PluginStatusDto['quota']['individualLimit']>, t: Translate): string {\n const parts = [\n limit.remainingPercent !== null && limit.remainingPercent !== undefined ? `${formatPercent(limit.remainingPercent)} ${t('remaining')}` : null,\n limit.limit !== null && limit.limit !== undefined ? `${t('limit')}: ${limit.limit}` : null,\n limit.used !== null && limit.used !== undefined ? `${t('used')}: ${limit.used}` : null,\n limit.resetsAt !== null && limit.resetsAt !== undefined ? `${t('resets')}: ${formatReset(limit.resetsAt)}` : null,\n ].filter((part): part is string => part !== null)\n return parts.length > 0 ? parts.join(' · ') : t('unknown')\n}\n\nfunction formatDate(seconds: number | undefined | null): string {\n if (seconds === undefined || seconds === null || typeof seconds !== 'number' || !Number.isFinite(seconds) || seconds <= 0) return '—'\n const ms = seconds > 10_000_000_000 ? seconds : seconds * 1000\n try {\n return new Intl.DateTimeFormat(undefined, { dateStyle: 'medium', timeStyle: 'short' }).format(ms)\n } catch {\n return '—'\n }\n}\n\nexport function formatReset(seconds: number | undefined | null): string {\n if (seconds === undefined || seconds === null || typeof seconds !== 'number' || !Number.isFinite(seconds) || seconds <= 0) return '—'\n const ms = seconds > 10_000_000_000 ? seconds : seconds * 1000\n const absolute = formatDate(seconds)\n const diff = ms - Date.now()\n const abs = Math.abs(diff)\n const [amount, unit]: [number, Intl.RelativeTimeFormatUnit] = abs >= 86_400_000\n ? [Math.round(diff / 86_400_000), 'day']\n : abs >= 3_600_000\n ? [Math.round(diff / 3_600_000), 'hour']\n : [Math.round(diff / 60_000), 'minute']\n try {\n return `${absolute} (${new Intl.RelativeTimeFormat(undefined, { numeric: 'auto' }).format(amount, unit)})`\n } catch {\n return absolute\n }\n}\n\nfunction messageOf(error: unknown): string {\n return error instanceof Error ? error.message : String(error)\n}\n","/**\n * The capacity, date and countdown formatting every provider settings card shares.\n *\n * Each card used to carry its own copy of the capacity pair. The five copies\n * were byte-identical except Antigravity's `formatCapacity`, which had lost the\n * 1K floor and so rendered a zero as \"0K\" while its siblings rendered \"0\". The\n * parse has to mean the same thing on every line — it takes free-text user input\n * that feeds the overflow judgement — so this is the one place it lives. The\n * date helpers were copied the same way; WorkBuddy's countdown is here for the\n * same reason.\n */\n\n/**\n * Parse \"1M\", \"512K\", \"200000\" into a positive integer token count.\n *\n * Anything that is not a plain capacity — including `0`, which no model has —\n * returns null rather than a coerced number, so the caller can leave the draft\n * uncommitted instead of storing a length that would silently break compaction.\n */\nexport function parsePositiveCapacity(value: string): number | null {\n const normalized = value.trim().toLowerCase().replace(/[,_\\s]/g, '')\n const matched = normalized.match(/^(\\d+(?:\\.\\d+)?)(k|m)?$/)\n if (matched === null) return null\n const multiplier = matched[2] === 'm' ? 1_000_000 : matched[2] === 'k' ? 1_000 : 1\n const parsed = Number(matched[1]) * multiplier\n return Number.isSafeInteger(parsed) && parsed >= 1 ? parsed : null\n}\n\n/** Render a token capacity the way the capacity field seeds itself. */\nexport function formatCapacity(value: number): string {\n if (value >= 1_000_000 && value % 100_000 === 0) return `${value / 1_000_000}M`\n if (value >= 1_000 && value % 1_000 === 0) return `${value / 1_000}K`\n return String(value)\n}\n\n/** A stamp in the reader's own locale, or an em dash when there is none. */\nexport function formatDate(ms?: number | null): string {\n if (ms === undefined || ms === null || !Number.isFinite(ms) || ms <= 0) return '—'\n try {\n return new Intl.DateTimeFormat(undefined, { dateStyle: 'medium', timeStyle: 'short' }).format(ms)\n } catch {\n return '—'\n }\n}\n\n/**\n * Countdown to a reset instant (\"3d 4h\"), empty when there is nothing to count\n * down to. Empty rather than \"—\" because callers append it to a date they have\n * already rendered, and a dash there would read as a second missing value.\n */\nexport function formatReset(resetsAt?: number | null): string {\n if (resetsAt === undefined || resetsAt === null || resetsAt <= 0) return ''\n const diff = resetsAt - Date.now()\n if (diff <= 0) return 'now'\n const mins = Math.floor(diff / 60000)\n const hours = Math.floor(mins / 60)\n const days = Math.floor(hours / 24)\n if (days > 0) return `${days}d ${hours % 24}h`\n if (hours > 0) return `${hours}h ${mins % 60}m`\n return `${mins}m`\n}\n","/**\n * The shared \"model context windows\" block every provider settings card renders.\n *\n * Six cards had grown near-identical copies of this markup: one row per enabled\n * model, a free-text capacity input, a save button, a restore button, and a\n * batch restore. Only these things ever differed between them —\n *\n * - the words (each card's dictionary, plus WorkBuddy's hardcoded `tokens`\n * and the hardcoded English `context window` input label four of them carry);\n * - whether a row shows the model's effective window beside the name when it\n * exceeds the model's default, and which stylesheet class that figure wears;\n * - whether the capacity input carries an `aria-label` at all (Antigravity's\n * does not);\n * - how a save or a restore is carried out, which stays in each card because\n * WorkBuddy normalizes its status payload and Antigravity confirms the batch\n * restore first.\n *\n * Everything the rows and callbacks need is therefore the whole interface: the\n * editor parses, seeds and stores nothing.\n */\nimport { formatCapacity } from './format.ts'\n\nexport interface ContextWindowRow {\n /** Model id: the row key, the name's tooltip, and what the callbacks receive. */\n id: string\n name: string\n /**\n * The free-text draft the card owns. The editor never parses it and never\n * falls back to a default, because a half-typed value has to survive a render.\n */\n draft: string\n /** Window figure shown beside the name; the cards that show one format it themselves. */\n meta?: string\n /** `aria-label` of this row's input; the one card that labels it with nothing omits it. */\n inputLabel?: string\n /**\n * Whether the host stores an override for this model. A model with none has\n * nothing to drop, so its restore button stays disabled.\n */\n hasOverride: boolean\n /** True while this row's save or restore request is in flight. */\n saving: boolean\n}\n\nexport interface ContextWindowLabels {\n /** Unit rendered after every capacity input. */\n tokens: string\n save: string\n saving: string\n reset: string\n resetAll: string\n /** Sentence shown while no enabled model has a row. */\n empty: string\n}\n\n/** The slice of a line's status payload the draft seeding reads. */\nexport interface ContextWindowStatus {\n models: readonly { id: string; defaultContextWindow: number }[]\n contextWindowOverrides: Record<string, number>\n}\n\n/**\n * Seed one draft per model from a status payload, so the input shows the stored\n * override and falls back to the catalog length.\n *\n * Run after a model toggle too: a model that was just enabled has no draft yet,\n * and only enabled models get a row — without this, its row would render an\n * empty input that a save would then reject as unparsable.\n */\nexport function contextDraftsFor(status: ContextWindowStatus): Record<string, string> {\n const drafts: Record<string, string> = {}\n for (const model of status.models) {\n drafts[model.id] = formatCapacity(status.contextWindowOverrides[model.id] || model.defaultContextWindow)\n }\n return drafts\n}\n\ninterface Props {\n rows: ContextWindowRow[]\n labels: ContextWindowLabels\n /** Disables the batch restore while any other request is in flight. */\n busy: boolean\n /**\n * Counts every stored override, including keys left by models the picker no\n * longer lists — which is why the batch button can be live while no visible\n * row offers a restore.\n */\n overrideCount: number\n /** Class the meta figure wears; each line draws it from its own stylesheet. */\n metaClassName?: string\n onDraftChange(id: string, draft: string): void\n onCommit(id: string): void\n onReset(id: string): void\n onResetAll(): void\n}\n\nexport function ContextWindowEditor({\n rows,\n labels,\n busy,\n overrideCount,\n metaClassName,\n onDraftChange,\n onCommit,\n onReset,\n onResetAll,\n}: Props): React.JSX.Element {\n return <div className=\"dsha-context-settings\">\n {rows.length === 0 ? <p className=\"dsha-muted\">{labels.empty}</p> : null}\n {rows.map((row) => (\n <div key={row.id} className=\"dsha-context-row\">\n <span title={row.id}>\n {row.name}\n {row.meta !== undefined ? <span className={metaClassName}>{row.meta}</span> : null}\n </span>\n <div className=\"dsha-capacity-control\">\n <input\n type=\"text\"\n aria-label={row.inputLabel}\n value={row.draft}\n onChange={(event) => onDraftChange(row.id, event.currentTarget.value)}\n onKeyDown={(event) => {\n if (event.key === 'Enter') onCommit(row.id)\n }}\n />\n <small>{labels.tokens}</small>\n <button\n type=\"button\"\n className=\"dsha-context-save\"\n disabled={row.saving}\n onClick={() => onCommit(row.id)}\n >\n {row.saving ? labels.saving : labels.save}\n </button>\n <button\n type=\"button\"\n className=\"dsha-context-save dsha-context-reset\"\n aria-label={`${row.name} ${labels.reset}`}\n disabled={row.saving || !row.hasOverride}\n onClick={() => onReset(row.id)}\n >\n {labels.reset}\n </button>\n </div>\n </div>\n ))}\n <div className=\"dsha-actions\">\n <button type=\"button\" className=\"dsha-btn\" disabled={busy || overrideCount === 0} onClick={onResetAll}>\n {labels.resetAll}\n </button>\n </div>\n </div>\n}\n","/**\n * One line's host routes, behind one reader.\n *\n * Ten copies of this reader had drifted into ten slightly different ones, and\n * the differences were all failure handling — the part nobody looks at until it\n * fires:\n *\n * - nine of them read `json.error` as a string. That is the sibling lines'\n * shape, but the ChatGPT routes answer `{ ok: false, error: { code, message } }`,\n * so a structured refusal rendered as \"[object Object]\";\n * - one of them tolerated an empty body and a non-JSON body, which is exactly\n * what a stale host half produces (the browser reads client assets from disk\n * on demand; the host loads them only at startup). The other nine turned it\n * into a bare parse crash with no way to tell what happened.\n *\n * This is the union: both error shapes, both degenerate bodies, and the same\n * sentence for the same failure on every line.\n */\nimport type { PublicErrorDto } from '../../shared/contracts.ts'\n\nexport interface LineApi {\n /** Any route under the line's prefix, unwrapping whichever envelope arrives. */\n request<T>(path: string, init?: RequestInit): Promise<T>\n get<T>(path: string): Promise<T>\n post<T>(path: string, body?: object): Promise<T>\n}\n\ninterface Envelope {\n ok?: unknown\n value?: unknown\n error?: unknown\n}\n\n/**\n * A route's error field is a plain string on some routes and a structured\n * `PublicErrorDto` on others; the card must not care which one arrived.\n */\nfunction errorMessage(value: unknown, fallback: string): string {\n if (typeof value === 'string' && value !== '') return value\n if (value !== null && typeof value === 'object') {\n const message = (value as Partial<PublicErrorDto>).message\n if (typeof message === 'string' && message !== '') return message\n }\n return fallback\n}\n\nexport function createLineApi(prefix: string, label: string): LineApi {\n async function request<T>(path: string, init?: RequestInit): Promise<T> {\n const response = await fetch(`${prefix}${path}`, {\n ...init,\n credentials: 'same-origin',\n headers: {\n 'Content-Type': 'application/json',\n ...init?.headers,\n },\n })\n\n const raw = await response.text()\n if (raw.trim() === '') {\n throw new Error(\n `${label} settings route did not answer (HTTP ${response.status} ${response.statusText || 'no body'}). `\n + 'The plugin loaded in the browser may be newer than the one running in the host — '\n + 'restart DSH so both halves come from the same build.',\n )\n }\n\n let body: unknown = null\n try {\n body = JSON.parse(raw) as unknown\n } catch {\n throw new Error(`${label} settings route returned a non-JSON body (HTTP ${response.status}): ${raw.slice(0, 200)}`)\n }\n\n const envelope = body as Envelope | null\n // A boolean `ok` is what declares the envelope — not the presence of\n // `value`: a refusal carries `error` and no `value` at all, and demanding\n // both made a 200-with-`ok:false` answer look like a successful payload.\n const isEnvelope = envelope !== null && typeof envelope === 'object' && typeof envelope.ok === 'boolean'\n if (isEnvelope) {\n if (!response.ok || envelope.ok === false) {\n throw new Error(errorMessage(envelope.error, `HTTP ${response.status}`))\n }\n return envelope.value as T\n }\n // Some routes document their payload directly instead of wrapping it.\n if (!response.ok) throw new Error(errorMessage(envelope?.error, `HTTP ${response.status}`))\n return body as T\n }\n\n return {\n request,\n get: <T>(path: string): Promise<T> => request<T>(path),\n post: <T>(path: string, body: object = {}): Promise<T> => request<T>(path, { method: 'POST', body: JSON.stringify(body) }),\n }\n}\n","export const NS_ANTIGRAVITY = 'dsh-antigravity'\n\nimport { accountPoolEn, accountPoolZh } from '../common/account-pool-labels.ts'\n\nexport const zh = {\n // The account-management card is shared with every other provider tab.\n ...accountPoolZh,\n title: 'Antigravity',\n pageDesc: '登录 Google Antigravity / Cloud Code Assist,并查看当前账号的共享额度。',\n account: '已登录',\n signedIn: '已登录',\n signedOut: '未登录',\n accountPool: '账号管理',\n addAccount: '添加账号',\n primaryAccount: '主账号',\n activeAccount: '当前使用',\n setPrimary: '设为主账号',\n deleteAccount: '删除',\n cooling: '冷却中',\n clearCooldown: '重置冷却',\n rotationStrategy: '调度策略',\n strategySequential: '顺序耗尽(当前优先,遇限流自动切号)',\n strategyRoundRobin: '轮询调度(按账号循环均匀分摊)',\n strategySticky: '会话粘性(保持当前账号直到被限流)',\n noAccounts: '暂无账号,点击「添加账号」完成登录授权。',\n plan: '套餐',\n accountId: '账号 ID',\n expires: '令牌到期',\n signInAgain: '重新登录',\n refreshToken: '刷新凭据',\n signOut: '注销',\n signIn: '登录',\n signingIn: '登录中...',\n connection: '连接',\n modelsHint: '勾选后模型才会显示在对话页的模型选择列表中;全部取消勾选或关闭概览卡片上的开关可在列表中隐藏该供应商。',\n modelsSection: '模型',\n selectAll: '全选',\n unselectAll: '全不选',\n enhanced: '增强功能',\n defaultReasoningEffort: '默认思考深度',\n defaultReasoningEffortHint: '控制支持推理的模型在未单独指定时的思考强度。',\n defaultEffortAuto: '使用 Provider 默认值',\n contextWindowSection: '模型上下文窗口',\n contextWindowHint: '默认按模型标准;可选应用最高容量,该值用于 DSH 的压缩与溢出判断,可输入 1M、512K、200K 等容量。',\n contextWindowReset: '恢复默认',\n contextWindowResetAll: '全部恢复默认',\n contextWindowResetAllConfirm: '确定把已改过的模型上下文窗口全部恢复为默认值吗?',\n contextWindowNoneEnabled: '还没有勾选任何模型。在上方勾选后,这里会出现该模型的上下文窗口设置。',\n save: '保存',\n saved: '已保存',\n saving: '保存中...',\n quotaSection: '用量与配额',\n quotaDesc: '数据来自 Google Cloud Code Assist 配额服务,页面可见时最多每 60 秒刷新一次。',\n refreshQuota: '刷新用量',\n refreshingQuota: '刷新中...',\n quotaEmpty: '暂无配额数据,点击「刷新用量」重试。',\n googleValidation: '前往 Google 完成账号验证',\n resetPrefix: '重置: {time}',\n resetUnavailable: '重置: n/a',\n resetNow: '现在',\n timeDayHour: '{days}天 {hours}时',\n timeHourMin: '{hours}h {minutes}m',\n timeMin: '{minutes}m',\n updatedAt: '更新时间:{time}',\n loading: '加载中...',\n loginFailed: '登录失败',\n tokens: 'tokens',\n}\n\nexport const en: Record<keyof typeof zh, string> = {\n ...accountPoolEn,\n title: 'Antigravity',\n pageDesc: 'Sign in to Google Antigravity / Cloud Code Assist and view shared quotas.',\n account: 'Signed in',\n signedIn: 'Signed in',\n signedOut: 'Not signed in',\n accountPool: 'Account Management',\n addAccount: 'Add Account',\n primaryAccount: 'Primary',\n activeAccount: 'In Use',\n setPrimary: 'Set as Primary',\n deleteAccount: 'Delete',\n cooling: 'In Cooldown',\n clearCooldown: 'Clear Cooldown',\n rotationStrategy: 'Scheduling Strategy',\n strategySequential: 'Sequential Drain (Primary first, failover on 429)',\n strategyRoundRobin: 'Round-Robin (Evenly rotate across accounts)',\n strategySticky: 'Sticky session (hold the current account until it is limited)',\n noAccounts: 'No accounts yet. Click \"Add Account\" to authorize.',\n plan: 'Plan',\n accountId: 'Account ID',\n expires: 'Token expires',\n signInAgain: 'Sign in again',\n refreshToken: 'Refresh token',\n signOut: 'Sign out',\n signIn: 'Sign in',\n signingIn: 'Signing in...',\n connection: 'Connection',\n modelsHint: 'Checked models will appear in DSH conversation model list; unchecking all or turning off the switch on the overview card hides this provider.',\n modelsSection: 'Models',\n selectAll: 'Select all',\n unselectAll: 'Deselect all',\n enhanced: 'Enhanced Features',\n defaultReasoningEffort: 'Default reasoning effort',\n defaultReasoningEffortHint: 'Controls reasoning effort for reasoning models when not explicitly specified in conversation.',\n defaultEffortAuto: 'Use Provider default',\n contextWindowSection: 'Model Context Window',\n contextWindowHint: 'Defaults to model specification; configure custom capacity used by DSH for compaction and overflow judgments (e.g., 1M, 512K, 200K).',\n contextWindowReset: 'Restore default',\n contextWindowResetAll: 'Restore all defaults',\n contextWindowResetAllConfirm: 'Restore every changed model context window to its default?',\n contextWindowNoneEnabled: 'No model is checked yet. Check one above and its context window setting appears here.',\n save: 'Save',\n saved: 'Saved',\n saving: 'Saving...',\n quotaSection: 'Usage & Quota',\n quotaDesc: 'Data from Google Cloud Code Assist quota service; refreshes up to once every 60 seconds when visible.',\n refreshQuota: 'Refresh quota',\n refreshingQuota: 'Refreshing...',\n quotaEmpty: 'No quota data yet — use “Refresh quota” to retry.',\n googleValidation: 'Verify the account with Google',\n resetPrefix: 'Reset: {time}',\n resetUnavailable: 'Reset: n/a',\n resetNow: 'now',\n timeDayHour: '{days}d {hours}h',\n timeHourMin: '{hours}h {minutes}m',\n timeMin: '{minutes}m',\n updatedAt: 'Updated at: {time}',\n loading: 'Loading...',\n loginFailed: 'Login failed',\n tokens: 'tokens',\n}\n\nexport const dictionaries = {\n zh,\n 'zh-CN': zh,\n en,\n 'en-US': en,\n}\n\nexport type AntigravityLocaleKey = keyof typeof zh\n","import React, { useCallback, useEffect, useRef, useState } from 'react'\nimport type {\n AccountRotationStrategy,\n AntigravityWebStatus,\n} from '../../shared/antigravity-contracts.ts'\nimport { AccountPoolSection } from '../common/AccountPoolSection.tsx'\nimport { ContextWindowEditor, contextDraftsFor } from '../common/ContextWindowEditor.tsx'\nimport { ModelChecklist } from '../common/ModelChecklist.tsx'\nimport { createLineApi } from '../common/line-api.ts'\nimport { createQuotaFollowUp, type QuotaFollowUp } from '../common/quota-follow-up.ts'\nimport { formatCapacity, parsePositiveCapacity } from '../common/format.ts'\nimport { zh } from './locales.ts'\n\nconst API = '/antigravity/api'\nconst api = createLineApi(API, 'Antigravity')\n\ninterface Props {\n onModelChange?: () => void\n loadModelDirectory?: () => void\n}\n\nexport function AntigravitySection({ onModelChange, loadModelDirectory }: Props): React.ReactElement {\n const [status, setStatus] = useState<AntigravityWebStatus | null>(null)\n const [loading, setLoading] = useState(true)\n const [busy, setBusy] = useState<string | null>(null)\n const [error, setError] = useState<string | null>(null)\n const [validationUrl, setValidationUrl] = useState<string | null>(null)\n const [loginProgress, setLoginProgress] = useState<string | null>(null)\n const [contextDrafts, setContextDrafts] = useState<Record<string, string>>({})\n const [savingModel, setSavingModel] = useState<string | null>(null)\n\n /** Follow-up poll owed while the host refreshes the quota behind an answer. */\n const quotaFollowUp = useRef<QuotaFollowUp | null>(null)\n\n const t = zh\n\n const notifyChange = useCallback(() => {\n onModelChange?.()\n loadModelDirectory?.()\n }, [onModelChange, loadModelDirectory])\n\n const loadStatus = useCallback(async (quiet = false) => {\n if (!quiet) {\n setError(null)\n setValidationUrl(null)\n }\n try {\n // The host refreshes a stale quota cache while serving /status, so a second\n // client-side POST /quota here would double every upstream fetch.\n const data = await api.request<AntigravityWebStatus>('/status')\n setStatus(data)\n setContextDrafts(contextDraftsFor(data))\n // An answer that refreshed the quota behind itself is followed up shortly,\n // so the fresh numbers land without waiting for the next poll.\n quotaFollowUp.current ??= createQuotaFollowUp()\n quotaFollowUp.current.observe(data.quotaRefreshing === true, () => { void loadStatus(true) })\n } catch (err) {\n if (!quiet) setError(err instanceof Error ? err.message : String(err))\n } finally {\n setLoading(false)\n }\n }, [])\n\n useEffect(() => {\n void loadStatus()\n const refreshWhenVisible = () => {\n if (document.visibilityState === 'visible') void loadStatus(true)\n }\n document.addEventListener('visibilitychange', refreshWhenVisible)\n const timer = window.setInterval(refreshWhenVisible, 60_000)\n return () => {\n window.clearInterval(timer)\n document.removeEventListener('visibilitychange', refreshWhenVisible)\n quotaFollowUp.current?.cancel()\n }\n }, [loadStatus])\n\n const handleLogin = async () => {\n try {\n setBusy('login')\n setError(null)\n setValidationUrl(null)\n setLoginProgress(null)\n const flow = await api.request<{ authUrl?: string; status?: string }>('/login', { method: 'POST' })\n if (flow.authUrl) {\n window.open(flow.authUrl, '_blank')\n }\n const pollTimer = setInterval(async () => {\n try {\n const pollStatus = await api.request<{\n status: string\n error?: string\n validationUrl?: string\n progress?: string\n }>('/login/status')\n if (pollStatus.progress) {\n setLoginProgress(pollStatus.progress)\n }\n if (pollStatus.status === 'complete') {\n clearInterval(pollTimer)\n setBusy(null)\n setLoginProgress(null)\n await loadStatus()\n notifyChange()\n } else if (pollStatus.status === 'error') {\n clearInterval(pollTimer)\n setBusy(null)\n setLoginProgress(null)\n setError(pollStatus.error || t.loginFailed)\n if (pollStatus.validationUrl) {\n setValidationUrl(pollStatus.validationUrl)\n }\n }\n } catch {\n // ignore\n }\n }, 1500)\n\n setTimeout(() => {\n clearInterval(pollTimer)\n setBusy(null)\n setLoginProgress(null)\n }, 5 * 60 * 1000)\n } catch (err) {\n setBusy(null)\n setLoginProgress(null)\n setError(err instanceof Error ? err.message : String(err))\n }\n }\n\n const handleRefreshQuota = async () => {\n try {\n setBusy('quota')\n setError(null)\n const updated = await api.request<AntigravityWebStatus>('/quota', { method: 'POST' })\n setStatus(updated)\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n } finally {\n setBusy(null)\n }\n }\n\n const handleLogout = async () => {\n try {\n setBusy('logout')\n setError(null)\n const updated = await api.request<AntigravityWebStatus>('/logout', { method: 'POST' })\n setStatus(updated)\n notifyChange()\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n } finally {\n setBusy(null)\n }\n }\n\n const handleSetPrimary = async (accountId: string) => {\n try {\n setBusy(`primary-${accountId}`)\n setError(null)\n const updated = await api.request<AntigravityWebStatus>('/accounts', {\n method: 'POST',\n body: JSON.stringify({ action: 'set-primary', accountId }),\n })\n setStatus(updated)\n notifyChange()\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n } finally {\n setBusy(null)\n }\n }\n\n const handleDeleteAccount = async (accountId: string) => {\n try {\n setBusy(`delete-${accountId}`)\n setError(null)\n const updated = await api.request<AntigravityWebStatus>('/accounts', {\n method: 'POST',\n body: JSON.stringify({ action: 'delete', accountId }),\n })\n setStatus(updated)\n notifyChange()\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n } finally {\n setBusy(null)\n }\n }\n\n const handleClearCooldown = async (accountId: string) => {\n try {\n setBusy(`cooldown-${accountId}`)\n setError(null)\n const updated = await api.request<AntigravityWebStatus>('/accounts', {\n method: 'POST',\n body: JSON.stringify({ action: 'clear-cooldown', accountId }),\n })\n setStatus(updated)\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n } finally {\n setBusy(null)\n }\n }\n\n const handleSetStrategy = async (strategy: AccountRotationStrategy) => {\n try {\n setBusy('strategy')\n setError(null)\n const updated = await api.request<AntigravityWebStatus>('/accounts', {\n method: 'POST',\n body: JSON.stringify({ action: 'strategy', strategy }),\n })\n setStatus(updated)\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n } finally {\n setBusy(null)\n }\n }\n\n const toggleModel = async (modelId: string, checked: boolean) => {\n if (!status) return\n const currentEnabled = status.models.filter((m) => m.enabled).map((m) => m.id)\n const nextEnabled = checked\n ? [...new Set([...currentEnabled, modelId])]\n : currentEnabled.filter((id) => id !== modelId)\n\n try {\n const updated = await api.request<AntigravityWebStatus>('/models', {\n method: 'POST',\n body: JSON.stringify({ enabledModelIds: nextEnabled }),\n })\n setStatus(updated)\n // A model that was just checked has no draft yet; the context window\n // section only renders enabled models.\n setContextDrafts(contextDraftsFor(updated))\n notifyChange()\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n }\n }\n\n const setAllModels = async (selectAll: boolean) => {\n if (!status) return\n const nextEnabled = selectAll ? status.models.map((m) => m.id) : []\n try {\n const updated = await api.request<AntigravityWebStatus>('/models', {\n method: 'POST',\n body: JSON.stringify({ enabledModelIds: nextEnabled }),\n })\n setStatus(updated)\n setContextDrafts(contextDraftsFor(updated))\n notifyChange()\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n }\n }\n\n const handleUpdateEffort = async (effort: 'low' | 'medium' | 'high' | null) => {\n try {\n const updated = await api.request<AntigravityWebStatus>('/settings', {\n method: 'POST',\n body: JSON.stringify({ defaultReasoningEffort: effort }),\n })\n setStatus(updated)\n notifyChange()\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n }\n }\n\n const handleSaveContextWindow = async (modelId: string) => {\n const raw = contextDrafts[modelId] || ''\n const parsed = parsePositiveCapacity(raw)\n if (parsed === null) {\n setError(`无效的上下文容量值: ${raw}`)\n return\n }\n\n try {\n setSavingModel(modelId)\n setError(null)\n const updated = await api.request<AntigravityWebStatus>('/settings', {\n method: 'POST',\n body: JSON.stringify({\n contextWindowOverrides: {\n [modelId]: parsed,\n },\n }),\n })\n setStatus(updated)\n setContextDrafts((prev) => ({ ...prev, [modelId]: formatCapacity(parsed) }))\n notifyChange()\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n } finally {\n setSavingModel(null)\n }\n }\n\n /** Clear one override; the row falls back to the catalog length. */\n const handleResetContextWindow = async (modelId: string) => {\n try {\n setSavingModel(modelId)\n setError(null)\n const updated = await api.request<AntigravityWebStatus>('/settings', {\n method: 'POST',\n body: JSON.stringify({ contextWindowOverrides: { [modelId]: null } }),\n })\n setStatus(updated)\n setContextDrafts((prev) => {\n const model = updated.models.find((candidate) => candidate.id === modelId)\n return model === undefined ? prev : { ...prev, [modelId]: formatCapacity(model.defaultContextWindow) }\n })\n notifyChange()\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n } finally {\n setSavingModel(null)\n }\n }\n\n /** Clear every stored override, including models the picker no longer shows. */\n const handleResetAllContextWindows = async () => {\n const models = Object.keys(status?.contextWindowOverrides ?? {})\n if (models.length === 0) return\n if (typeof window !== 'undefined' && !window.confirm(t.contextWindowResetAllConfirm)) return\n try {\n setBusy('context')\n setError(null)\n const updated = await api.request<AntigravityWebStatus>('/settings', {\n method: 'POST',\n body: JSON.stringify({ contextWindowOverrides: Object.fromEntries(models.map((model) => [model, null])) }),\n })\n setStatus(updated)\n setContextDrafts(contextDraftsFor(updated))\n notifyChange()\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n } finally {\n setBusy(null)\n }\n }\n\n // Only checked models get a context row; the batch restore still covers every\n // stored override, including one left behind by a model the user unchecked.\n const contextModels = status?.models.filter((model) => model.enabled) ?? []\n const overrideCount = Object.keys(status?.contextWindowOverrides ?? {}).length\n\n if (loading) {\n return (\n <div className=\"dsha-page\">\n <div className=\"dsha-empty\">{t.loading}</div>\n </div>\n )\n }\n\n const quota = status?.quota\n const groups = quota?.groups || []\n const visibleCount = status?.models.filter((m) => m.enabled).length || 0\n\n return (\n <div className=\"dsha-page\">\n {/* 1. 账号管理分组:与其余三条线路共用同一张账号卡片 */}\n <AccountPoolSection\n accounts={status?.accounts ?? []}\n activeAccountId={status?.activeAccountId}\n rotationStrategy={status?.rotationStrategy ?? 'sequential'}\n busy={busy}\n labels={t}\n loginBusyLabel={busy === 'login' ? (loginProgress || t.signingIn) : undefined}\n onLogin={() => void handleLogin()}\n onSetPrimary={(accountId) => void handleSetPrimary(accountId)}\n onDelete={(accountId) => void handleDeleteAccount(accountId)}\n onClearCooldown={(accountId) => void handleClearCooldown(accountId)}\n onSetStrategy={(strategy) => void handleSetStrategy(strategy)}\n // Quota follows the account, so a row draws the snapshot the host holds\n // for that account rather than one line-level figure.\n showQuota\n // Only what the shared card cannot know: the line's own project id.\n // E-mail, expiry and last-used are the shared card's rows, and rendering\n // them here printed each of them twice.\n renderDetails={(account) => (\n <span>{t.accountId}: {account.projectId || 'antigravity-default'}</span>\n )}\n />\n\n {/* 2. 模型选择:这一组现在只做模型,连接事实(开关 / Provider / 连接状态)\n 已删——开关在概览卡片上,Provider 与「已连接」是内部细节。 */}\n <section className=\"dsha-group\">\n <div className=\"dsha-grouphead\">\n <h3>{t.modelsSection}</h3>\n </div>\n <p className=\"dsha-muted dsha-models-hint\">{t.modelsHint}</p>\n\n <ModelChecklist\n items={(status?.models ?? []).map((model) => ({\n id: model.id,\n name: model.name,\n hint: model.defaultContextWindow ? formatCapacity(model.defaultContextWindow) : undefined,\n enabled: model.enabled,\n }))}\n busy={busy !== null}\n onToggle={(id, enabled) => void toggleModel(id, enabled)}\n onToggleAll={setAllModels}\n labels={{ selectAll: t.selectAll, clearAll: t.unselectAll, list: t.modelsSection }}\n />\n </section>\n\n {/* 3. 增强功能(思考深度设置) */}\n <section className=\"dsha-group\">\n <div className=\"dsha-grouphead\">\n <h3>{t.enhanced}</h3>\n </div>\n <div className=\"dsha-pref-row\">\n <div>\n <strong>{t.defaultReasoningEffort}</strong>\n <p className=\"dsha-muted\">{t.defaultReasoningEffortHint}</p>\n </div>\n <select\n className=\"dsha-select\"\n aria-label={t.defaultReasoningEffort}\n value={status?.defaultReasoningEffort ?? ''}\n disabled={busy !== null}\n onChange={(e) => {\n const val = e.currentTarget.value\n void handleUpdateEffort(val === '' ? null : (val as 'low' | 'medium' | 'high'))\n }}\n >\n <option value=\"\">{t.defaultEffortAuto}</option>\n <option value=\"low\">Low</option>\n <option value=\"medium\">Medium</option>\n <option value=\"high\">High</option>\n </select>\n </div>\n </section>\n\n {/* 4. 模型上下文窗口设置(按模型独立配置) */}\n <section className=\"dsha-group\">\n <div className=\"dsha-grouphead\">\n <h3>{t.contextWindowSection}</h3>\n </div>\n <p className=\"dsha-muted\">{t.contextWindowHint}</p>\n\n <ContextWindowEditor\n rows={contextModels.map((model) => ({\n id: model.id,\n name: model.name,\n draft: contextDrafts[model.id] ?? '',\n hasOverride: status?.contextWindowOverrides[model.id] !== undefined,\n saving: savingModel === model.id,\n }))}\n labels={{\n tokens: t.tokens,\n save: t.save,\n saving: t.saving,\n reset: t.contextWindowReset,\n resetAll: t.contextWindowResetAll,\n empty: t.contextWindowNoneEnabled,\n }}\n busy={busy !== null}\n overrideCount={overrideCount}\n onDraftChange={(id, draft) => setContextDrafts((prev) => ({ ...prev, [id]: draft }))}\n onCommit={(id) => void handleSaveContextWindow(id)}\n onReset={(id) => void handleResetContextWindow(id)}\n onResetAll={() => void handleResetAllContextWindows()}\n />\n </section>\n\n {/* 5. 用量与配额卡片 */}\n <section className=\"dsha-group\">\n <div className=\"dsha-grouphead\">\n <h3>{t.quotaSection}</h3>\n <button\n className=\"dsha-btn\"\n disabled={busy !== null || !status?.authenticated}\n onClick={handleRefreshQuota}\n >\n {busy === 'quota' ? t.refreshingQuota : t.refreshQuota}\n </button>\n </div>\n <p className=\"dsha-muted\">{t.quotaDesc}</p>\n {/* The per-group/bucket rows went with the bars: every one of them — the\n remaining share, the reset countdown, the group and bucket names —\n is drawn on the account card now, where the snapshot actually\n belongs. What stays is what has no account-row home: the refresh\n action, the reading's freshness and the states below. */}\n <p className=\"dsha-muted\">{t.quotaFactsScope}</p>\n\n {!status?.authenticated\n ? <div className=\"dsha-empty\">{t.signedOut}</div>\n : groups.length === 0\n ? <div className=\"dsha-empty\">{busy === 'quota' ? t.refreshingQuota : t.quotaEmpty}</div>\n : null}\n\n {quota?.fetchedAt && (\n <div className=\"dsha-timestamp\">\n 更新时间: {new Date(quota.fetchedAt).toLocaleString()}\n </div>\n )}\n </section>\n\n {error && (\n <div className=\"dsha-error\">\n <div>{error}</div>\n {validationUrl && (\n <div style={{ marginTop: '8px' }}>\n <a\n href={validationUrl}\n target=\"_blank\"\n rel=\"noreferrer\"\n className=\"dsha-btn dsha-btn-primary\"\n style={{ display: 'inline-block', textDecoration: 'none', padding: '4px 10px', fontSize: '12px' }}\n >\n {t.googleValidation}\n </a>\n </div>\n )}\n </div>\n )}\n </div>\n )\n}\n","/**\n * Wire contracts between the Command Code host routes and the browser settings\n * card. Everything here is public: no credential ever crosses this boundary.\n */\n\nimport type {\n AccountRotationStrategy,\n PoolAccountSummaryDto,\n} from './account-pool-contracts.ts'\n\n/** Deployment of the Command Code API a credential was issued against. */\nexport type CommandCodeApiEnv = 'prod' | 'staging' | 'local'\n\n/**\n * Reasoning levels this route can expose. The exact set is per model —\n * `minimal` is the cheapest budget, `xhigh` sits between `high` and `max`, and\n * most models declare only a subset.\n *\n * `none` means \"do not think\". Command Code declares that level as `off` in its\n * own registry; the host translates it on the way out (the wire expresses it by\n * OMITTING the reasoning field entirely), so this vocabulary — and therefore\n * the settings card and DSH's picker — uses the name DSH already knows, the\n * same one the Kimi and Claude lines use.\n */\nexport type CommandCodeReasoningEffort = 'none' | 'minimal' | 'low' | 'medium' | 'high' | 'xhigh' | 'max'\n\n/** Every level, in escalating order; the settings card renders exactly these. */\nexport const COMMAND_CODE_REASONING_EFFORTS: readonly CommandCodeReasoningEffort[] =\n ['none', 'minimal', 'low', 'medium', 'high', 'xhigh', 'max']\n\n/** One model offered by the Command Code provider API. */\nexport interface CommandCodeModelOption {\n id: string\n name: string\n /** Enabled models are the ones DSH offers in the conversation model picker. */\n enabled: boolean\n /** Context window the live catalog reports for this model. */\n defaultContextWindow: number\n /** Effective context window: the override when one is saved, else the default. */\n contextWindow: number\n /** Maximum output tokens this route requests when a caller omits one. */\n defaultMaxTokens: number\n /** Reasoning levels this route exposes; absent for non-reasoning models. */\n reasoningEfforts?: string[]\n /** Reasoning dialect the adapter uses on the wire. */\n wire: CommandCodeWire\n}\n\n/**\n * Request/response dialect a model id is served over.\n *\n * The provider serves each model on exactly one route and answers 400 on the\n * wrong one, so this is a routing fact rather than a presentation choice.\n * `responses` is the OpenAI Responses API, which several GPT models require:\n * sending them to Chat Completions is a rejected request, not a degraded one.\n */\nexport type CommandCodeWire = 'openai' | 'anthropic' | 'responses'\n\n/** One credit / spend meter reported by the billing service. */\nexport interface CommandCodeMeter {\n id: string\n label: string\n /** Used fraction in [0, 1] when the service reports a bounded allowance. */\n usedFraction: number | null\n /** Remaining fraction in [0, 1], when the service reports one. */\n remainingFraction: number | null\n used: string | null\n limit: string | null\n /** Unix milliseconds the meter resets, when reported. */\n resetsAt: number | null\n description: string | null\n}\n\n/** Windowed request/token allowance reported by the usage service. */\nexport interface CommandCodeUsageWindow {\n id: string\n label: string\n usedPercent: number\n windowDurationMins: number | null\n resetsAt: number | null\n}\n\n/** Account identity returned by `/alpha/whoami`. */\nexport interface CommandCodeAccount {\n userId: string | null\n userName: string | null\n email: string | null\n organizationName: string | null\n keyName: string | null\n planLabel: string | null\n planId: string | null\n authenticatedAt: number | null\n}\n\n/** One point-in-time quota snapshot for the signed-in Command Code account. */\nexport interface CommandCodeAccountQuota {\n account: CommandCodeAccount\n /** Credit balance in the provider's own unit, when reported. */\n creditBalance: string | null\n /** True when the plan bills against an unlimited allowance. */\n unlimited: boolean\n /** Machine id the service reports, e.g. `individual-goat`. */\n planId: string | null\n /** Display name for {@link planId}, e.g. `GOAT`. */\n planName: string | null\n /** Monthly credits the plan grants, when the id is recognized. */\n planMonthlyCredits: number | null\n /** Subscription state the service reports, e.g. `active`. */\n subscriptionStatus: string | null\n /** End of the current billing period, as Unix milliseconds. */\n periodEndsAt: number | null\n meters: CommandCodeMeter[]\n windows: CommandCodeUsageWindow[]\n /** Raw service payloads, kept for diagnostics in the settings card. */\n fetchedAt: number\n sources: string[]\n}\n\n/** Everything the settings card and the composer badge render. */\nexport interface CommandCodeWebStatus {\n enabled?: boolean\n authenticated: boolean\n hasCredentials: boolean\n storagePath: string\n apiEnv: CommandCodeApiEnv\n account: CommandCodeAccount | null\n quota: CommandCodeAccountQuota | null\n lastFetchedAt: number | null\n /**\n * Whether a quota refresh is running behind this answer.\n *\n * The card renders the snapshot it already had instead of waiting on the\n * upstream request; when this is true the client asks again shortly so the\n * refreshed snapshot reaches the UI.\n */\n quotaRefreshing?: boolean\n /** Unix milliseconds the model catalog was fetched, when known. */\n catalogFetchedAt?: number | null\n /** True when the catalog in memory or storage is stale and awaiting revalidation. */\n catalogStale?: boolean\n /** Whether Zero Data Retention (ZDR) routing is active for Command Code requests. */\n zeroDataRetention?: boolean\n models: CommandCodeModelOption[]\n contextWindowOverrides: Record<string, number>\n defaultReasoningEffort: CommandCodeReasoningEffort | null\n /** Signed-in keys; empty or absent when no pool is installed. */\n accounts?: CommandCodeAccountSummaryDto[]\n /** Account the next request would use. */\n activeAccountId?: string\n rotationStrategy?: AccountRotationStrategy\n /** Route the plugin currently serves; false when another plugin owns it. */\n serving: boolean\n /** Diagnostic when the route is owned by a different adapter family. */\n conflict: string | null\n}\n\n/** One pooled key as the settings card renders it; never carries the key itself. */\nexport interface CommandCodeAccountSummaryDto extends PoolAccountSummaryDto {\n userName?: string\n keyName?: string\n organizationName?: string\n planId?: string\n userId?: string\n}\n\n/** Patch accepted by the models/settings routes. */\nexport interface CommandCodeSettingsUpdateDto {\n enabled?: boolean\n enabledModelIds?: string[]\n /** A number sets an override for that model; `null` restores the catalog default. */\n contextWindowOverrides?: Record<string, number | null>\n defaultReasoningEffort?: CommandCodeReasoningEffort | null\n}\n\n/** Result of a manual API-key submission or a compatibility probe. */\nexport interface CommandCodeConnectionDto {\n connected: boolean\n account: CommandCodeAccount | null\n checkedAt: number\n}\n","import { accountPoolEn, accountPoolZh } from '../common/account-pool-labels.ts'\n\nexport const NS_COMMAND_CODE = 'dsh-command-code'\n\nexport const zh = {\n // The account-management card is shared with every other provider tab, so its\n // labels come from one place instead of drifting per provider.\n ...accountPoolZh,\n title: 'Command Code',\n pageDesc: '登录 Command Code,管理可用模型、上下文窗口与额度。',\n account: '账号',\n signedIn: '已登录',\n signedOut: '未登录',\n keyName: '密钥名称',\n organization: '组织',\n plan: '套餐',\n planUnknown: '—',\n subscription: '订阅状态',\n renews: '续费于',\n authenticatedAt: '登录时间',\n signIn: '浏览器登录',\n signInAgain: '重新登录',\n signingIn: '登录中...',\n signOut: '注销',\n cancelSignIn: '取消登录',\n openSignInPage: '打开登录页面',\n apiKeySection: '手动填写 API Key',\n apiKeyHint: '在 Command Code Studio 创建 API Key 后粘贴到此处;浏览器登录不可用时使用。',\n apiKeyPlaceholder: '粘贴 Command Code API Key',\n apiKeySave: '保存并验证',\n apiKeySaving: '验证中...',\n apiKeySaved: '已保存',\n connection: '连接',\n testConnection: '测试连接',\n testingConnection: '测试中...',\n routeOwned: '模型路由由本插件提供',\n routeConflict: '模型路由已被其他 Provider 占用:{detail}。请在 DSH 设置中移除重复的 Provider 配置后重试。',\n modelsSection: '模型',\n modelsHint: '勾选后模型才会出现在对话页的模型选择列表中;全部取消勾选或关闭概览卡片上的开关可在列表中隐藏该供应商。',\n refreshCatalog: '刷新模型目录',\n refreshingCatalog: '刷新中...',\n catalogStale: '目录来自缓存,可能过期;可手动刷新',\n catalogFresh: '目录已同步',\n zdrEnabled: '已请求零数据保留(ZDR);服务端无符合条件的路由时将拒绝请求,不自动降低隐私要求。',\n selectAll: '全选',\n unselectAll: '全不选',\n wireAnthropic: 'Anthropic',\n wireOpenai: 'OpenAI',\n wireResponses: 'OpenAI Responses',\n enhanced: '增强功能',\n defaultReasoningEffort: '默认思考深度',\n defaultReasoningEffortHint: '控制支持推理的模型在未单独指定时的思考强度。Anthropic 模型会映射为 thinking 预算。',\n defaultEffortAuto: '使用 Provider 默认值',\n contextWindowSection: '模型上下文窗口',\n contextWindowHint: '默认取 Command Code 模型目录的 context length;可覆盖为自定义容量,该值用于 DSH 的压缩与溢出判断,可输入 1M、512K、200K 等容量。',\n contextWindowReset: '恢复默认',\n contextWindowResetAll: '全部恢复默认',\n contextWindowResetAllConfirm: '确定把已改过的模型上下文窗口全部恢复为默认值吗?',\n contextWindowNoneEnabled: '还没有勾选任何模型。在上方勾选后,这里会出现该模型的上下文窗口设置。',\n save: '保存',\n saved: '已保存',\n saving: '保存中...',\n quotaSection: '用量与配额',\n quotaDesc: '数据来自 Command Code 账户接口,页面可见时最多每 60 秒刷新一次。',\n refreshQuota: '刷新用量',\n refreshingQuota: '刷新中...',\n quotaEmpty: '暂无配额数据,点击「刷新用量」重试。',\n quotaCredits: '剩余额度',\n quotaUnlimited: '不限量',\n updatedAt: '更新时间:{time}',\n loading: '加载中...',\n loginFailed: '登录失败',\n tokens: 'tokens',\n} as const\n\nexport const en: Record<keyof typeof zh, string> = {\n ...accountPoolEn,\n title: 'Command Code',\n pageDesc: 'Sign in to Command Code and manage models, context windows, and quota.',\n account: 'Account',\n signedIn: 'Signed in',\n signedOut: 'Not signed in',\n keyName: 'Key name',\n organization: 'Organization',\n plan: 'Plan',\n planUnknown: '—',\n subscription: 'Subscription',\n renews: 'renews',\n authenticatedAt: 'Signed in at',\n signIn: 'Sign in with browser',\n signInAgain: 'Sign in again',\n signingIn: 'Signing in...',\n signOut: 'Sign out',\n cancelSignIn: 'Cancel',\n openSignInPage: 'Open the sign-in page',\n apiKeySection: 'Paste an API key',\n apiKeyHint: 'Create a key in Command Code Studio and paste it here; use this when the browser flow is unavailable.',\n apiKeyPlaceholder: 'Command Code API key',\n apiKeySave: 'Save and verify',\n apiKeySaving: 'Verifying...',\n apiKeySaved: 'Saved',\n connection: 'Connection',\n testConnection: 'Test connection',\n testingConnection: 'Testing...',\n routeOwned: 'This plugin serves the model route',\n routeConflict: 'Another provider already owns the model route: {detail}. Remove the duplicate provider configuration in DSH settings and reload.',\n modelsSection: 'Models',\n modelsHint: 'Checked models appear in the DSH conversation model list; unchecking all or turning off the switch on the overview card hides this provider.',\n refreshCatalog: 'Refresh catalog',\n refreshingCatalog: 'Refreshing...',\n catalogStale: 'Cached catalog may be stale; refresh to revalidate',\n catalogFresh: 'Catalog synchronized',\n zdrEnabled: 'Zero Data Retention requested; requests fail closed if no compliant route is available.',\n selectAll: 'Select all',\n unselectAll: 'Deselect all',\n wireAnthropic: 'Anthropic',\n wireOpenai: 'OpenAI',\n wireResponses: 'OpenAI Responses',\n enhanced: 'Enhanced features',\n defaultReasoningEffort: 'Default reasoning effort',\n defaultReasoningEffortHint: 'Reasoning effort for models that support it when the conversation does not specify one. Anthropic models map it to a thinking budget.',\n defaultEffortAuto: 'Use provider default',\n contextWindowSection: 'Model context window',\n contextWindowHint: 'Defaults to the context length in the Command Code catalog; override it with the capacity DSH should use for compaction and overflow decisions (e.g., 1M, 512K, 200K).',\n contextWindowReset: 'Restore default',\n contextWindowResetAll: 'Restore all defaults',\n contextWindowResetAllConfirm: 'Restore every changed model context window to its default?',\n contextWindowNoneEnabled: 'No model is checked yet. Check one above and its context window setting appears here.',\n save: 'Save',\n saved: 'Saved',\n saving: 'Saving...',\n quotaSection: 'Usage & quota',\n quotaDesc: 'Read from the Command Code account endpoints; refreshes at most once every 60 seconds while visible.',\n refreshQuota: 'Refresh quota',\n refreshingQuota: 'Refreshing...',\n quotaEmpty: 'No quota data yet — use “Refresh quota” to retry.',\n quotaCredits: 'Remaining credits',\n quotaUnlimited: 'Unlimited',\n updatedAt: 'Updated at: {time}',\n loading: 'Loading...',\n loginFailed: 'Sign-in failed',\n tokens: 'tokens',\n} as const\n\nexport const dictionaries = {\n zh,\n 'zh-CN': zh,\n en,\n 'en-US': en,\n}\n\nexport type CommandCodeLocaleKey = keyof typeof zh\n","import React, { useCallback, useEffect, useRef, useState } from 'react'\nimport type {\n CommandCodeModelOption,\n CommandCodeReasoningEffort,\n CommandCodeWebStatus,\n CommandCodeWire,\n} from '../../shared/command-code-contracts.ts'\nimport { COMMAND_CODE_REASONING_EFFORTS } from '../../shared/command-code-contracts.ts'\nimport { createQuotaFollowUp, type QuotaFollowUp } from '../common/quota-follow-up.ts'\n\n/**\n * Display label per reasoning level. The locale dictionary only accepts flat\n * string values, so this nested table lives with the control that renders it.\n */\nconst EFFORT_LABELS: Record<CommandCodeReasoningEffort, string> = {\n none: 'Off',\n minimal: 'Minimal',\n low: 'Low',\n medium: 'Medium',\n high: 'High',\n xhigh: 'X-High',\n max: 'Max',\n}\nimport { AccountPoolSection } from '../common/AccountPoolSection.tsx'\nimport { ContextWindowEditor, contextDraftsFor } from '../common/ContextWindowEditor.tsx'\nimport { ModelChecklist } from '../common/ModelChecklist.tsx'\nimport { createLineApi } from '../common/line-api.ts'\nimport { formatCapacity, formatDate, parsePositiveCapacity } from '../common/format.ts'\nimport type { AccountRotationStrategy } from '../../shared/account-pool-contracts.ts'\nimport { zh } from './locales.ts'\n\nconst API = '/command-code/api'\nconst api = createLineApi(API, 'Command Code')\n\ninterface Props {\n onModelChange?: () => void\n loadModelDirectory?: () => void\n}\n\ninterface LoginPollStatus {\n status: string\n authUrl?: string\n error?: string\n progress?: string\n}\n\n/**\n * Route name shown next to a model.\n *\n * The three routes are not interchangeable: the provider serves each model on\n * exactly one and rejects the others, so the label states which one this model\n * actually uses.\n */\nfunction wireLabel(wire: CommandCodeWire, t: { wireAnthropic: string; wireOpenai: string; wireResponses: string }): string {\n if (wire === 'anthropic') return t.wireAnthropic\n if (wire === 'responses') return t.wireResponses\n return t.wireOpenai\n}\n\nexport function CommandCodeSection({ onModelChange, loadModelDirectory }: Props): React.ReactElement {\n const [status, setStatus] = useState<CommandCodeWebStatus | null>(null)\n const [loading, setLoading] = useState(true)\n const [busy, setBusy] = useState<string | null>(null)\n const [error, setError] = useState<string | null>(null)\n const [loginProgress, setLoginProgress] = useState<string | null>(null)\n const [contextDrafts, setContextDrafts] = useState<Record<string, string>>({})\n const [savingModel, setSavingModel] = useState<string | null>(null)\n const [apiKey, setApiKey] = useState('')\n\n /** Follow-up poll owed while the host refreshes the quota behind an answer. */\n const quotaFollowUp = useRef<QuotaFollowUp | null>(null)\n\n const t = zh\n\n const notifyChange = useCallback(() => {\n onModelChange?.()\n loadModelDirectory?.()\n }, [onModelChange, loadModelDirectory])\n\n const loadStatus = useCallback(async (quiet = false) => {\n if (!quiet) {\n setError(null)\n }\n try {\n const data = await api.request<CommandCodeWebStatus>('/status')\n setStatus(data)\n setContextDrafts(contextDraftsFor(data))\n // An answer that refreshed the quota behind itself is followed up shortly,\n // so the fresh numbers land without waiting for the next poll.\n quotaFollowUp.current ??= createQuotaFollowUp()\n quotaFollowUp.current.observe(data.quotaRefreshing === true, () => { void loadStatus(true) })\n } catch (err) {\n if (!quiet) setError(err instanceof Error ? err.message : String(err))\n } finally {\n setLoading(false)\n }\n }, [])\n\n useEffect(() => {\n void loadStatus()\n const refreshWhenVisible = () => {\n if (document.visibilityState === 'visible') void loadStatus(true)\n }\n document.addEventListener('visibilitychange', refreshWhenVisible)\n const timer = window.setInterval(refreshWhenVisible, 60_000)\n return () => {\n window.clearInterval(timer)\n document.removeEventListener('visibilitychange', refreshWhenVisible)\n quotaFollowUp.current?.cancel()\n }\n }, [loadStatus])\n\n const handleLogin = async () => {\n try {\n setBusy('login')\n setError(null)\n setLoginProgress(null)\n const flow = await api.request<LoginPollStatus>('/login', { method: 'POST' })\n if (flow.authUrl) {\n window.open(flow.authUrl, '_blank')\n }\n const pollTimer = window.setInterval(() => {\n void (async () => {\n try {\n const poll = await api.request<LoginPollStatus>('/login/status')\n if (poll.progress) setLoginProgress(poll.progress)\n if (poll.status === 'complete') {\n window.clearInterval(pollTimer)\n setBusy(null)\n setLoginProgress(null)\n await loadStatus()\n notifyChange()\n } else if (poll.status === 'error') {\n window.clearInterval(pollTimer)\n setBusy(null)\n setLoginProgress(null)\n setError(poll.error || t.loginFailed)\n }\n } catch {\n // A failed poll is transient; the next tick retries.\n }\n })()\n }, 1500)\n window.setTimeout(() => {\n window.clearInterval(pollTimer)\n setBusy(null)\n setLoginProgress(null)\n }, 5 * 60 * 1000)\n } catch (err) {\n setBusy(null)\n setLoginProgress(null)\n setError(err instanceof Error ? err.message : String(err))\n }\n }\n\n const handleApiKey = async () => {\n try {\n setBusy('apikey')\n setError(null)\n const updated = await api.request<CommandCodeWebStatus>('/login/apikey', {\n method: 'POST',\n body: JSON.stringify({ apiKey }),\n })\n setStatus(updated)\n setApiKey('')\n notifyChange()\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n } finally {\n setBusy(null)\n }\n }\n\n /** One account-level action on the shared pool card. */\n const handleAccountAction = async (\n action: 'set-primary' | 'delete' | 'clear-cooldown',\n accountId: string,\n ) => {\n try {\n setBusy(`${action}-${accountId}`)\n setError(null)\n const updated = await api.request<CommandCodeWebStatus>('/accounts', {\n method: 'POST',\n body: JSON.stringify({ action, accountId }),\n })\n setStatus(updated)\n notifyChange()\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n } finally {\n setBusy(null)\n }\n }\n\n const handleSetStrategy = async (strategy: AccountRotationStrategy) => {\n try {\n setBusy('strategy')\n setError(null)\n const updated = await api.request<CommandCodeWebStatus>('/accounts', {\n method: 'POST',\n body: JSON.stringify({ action: 'strategy', strategy }),\n })\n setStatus(updated)\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n } finally {\n setBusy(null)\n }\n }\n\n /**\n * Re-authorize one key.\n *\n * Nothing is deleted: the failure marker is cleared and the ordinary sign-in\n * flow runs again, so the account keeps its alias and place in the rotation.\n */\n const handleRelogin = (accountId: string) => {\n void (async () => {\n try {\n const updated = await api.request<CommandCodeWebStatus>('/accounts', {\n method: 'POST',\n body: JSON.stringify({ action: 'relogin', accountId }),\n })\n setStatus(updated)\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n return\n }\n await handleLogin()\n })()\n }\n\n const handleRefreshQuota = async () => {\n try {\n setBusy('quota')\n setError(null)\n const updated = await api.request<CommandCodeWebStatus>('/quota', { method: 'POST' })\n setStatus(updated)\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n } finally {\n setBusy(null)\n }\n }\n\n const handleRefreshCatalog = async () => {\n try {\n setBusy('catalog')\n setError(null)\n const updated = await api.request<CommandCodeWebStatus>('/catalog/refresh', { method: 'POST' })\n setStatus(updated)\n setContextDrafts(contextDraftsFor(updated))\n notifyChange()\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n } finally {\n setBusy(null)\n }\n }\n\n const handleTestConnection = async () => {\n try {\n setBusy('connection')\n setError(null)\n await api.post('/connection/test')\n await loadStatus(true)\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n } finally {\n setBusy(null)\n }\n }\n\n const applyEnabled = async (enabledModelIds: string[]) => {\n try {\n const updated = await api.request<CommandCodeWebStatus>('/models', {\n method: 'POST',\n body: JSON.stringify({ enabledModelIds }),\n })\n setStatus(updated)\n // A model that was just checked has no draft yet; the context window\n // section only renders enabled models.\n setContextDrafts(contextDraftsFor(updated))\n notifyChange()\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n }\n }\n\n const toggleModel = (modelId: string, checked: boolean) => {\n if (!status) return\n const current = status.models.filter((model) => model.enabled).map((model) => model.id)\n const next = checked ? [...new Set([...current, modelId])] : current.filter((id) => id !== modelId)\n void applyEnabled(next)\n }\n\n const setAllModels = (selectAll: boolean) => {\n if (!status || status.models.length === 0) return\n void applyEnabled(selectAll ? status.models.map((model) => model.id) : [])\n }\n\n const handleUpdateEffort = async (effort: CommandCodeReasoningEffort | null) => {\n try {\n const updated = await api.request<CommandCodeWebStatus>('/settings', {\n method: 'POST',\n body: JSON.stringify({ defaultReasoningEffort: effort }),\n })\n setStatus(updated)\n notifyChange()\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n }\n }\n\n const handleSaveContextWindow = async (modelId: string) => {\n const raw = contextDrafts[modelId] || ''\n const parsed = parsePositiveCapacity(raw)\n if (parsed === null) {\n setError(`Invalid context capacity: ${raw}`)\n return\n }\n try {\n setSavingModel(modelId)\n setError(null)\n const updated = await api.request<CommandCodeWebStatus>('/settings', {\n method: 'POST',\n body: JSON.stringify({ contextWindowOverrides: { [modelId]: parsed } }),\n })\n setStatus(updated)\n setContextDrafts((prev) => ({ ...prev, [modelId]: formatCapacity(parsed) }))\n notifyChange()\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n } finally {\n setSavingModel(null)\n }\n }\n\n /** Clear one override; the row falls back to the catalog length. */\n const handleResetContextWindow = async (modelId: string) => {\n try {\n setSavingModel(modelId)\n setError(null)\n const updated = await api.request<CommandCodeWebStatus>('/settings', {\n method: 'POST',\n body: JSON.stringify({ contextWindowOverrides: { [modelId]: null } }),\n })\n setStatus(updated)\n setContextDrafts((prev) => {\n const model = updated.models.find((candidate) => candidate.id === modelId)\n return model === undefined ? prev : { ...prev, [modelId]: formatCapacity(model.defaultContextWindow) }\n })\n notifyChange()\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n } finally {\n setSavingModel(null)\n }\n }\n\n /** Clear every stored override, including models the picker no longer shows. */\n const handleResetAllContextWindows = async () => {\n const models = Object.keys(status?.contextWindowOverrides ?? {})\n if (models.length === 0) return\n if (typeof window !== 'undefined' && !window.confirm(t.contextWindowResetAllConfirm)) return\n try {\n setBusy('context')\n setError(null)\n const updated = await api.request<CommandCodeWebStatus>('/settings', {\n method: 'POST',\n body: JSON.stringify({ contextWindowOverrides: Object.fromEntries(models.map((model) => [model, null])) }),\n })\n setStatus(updated)\n setContextDrafts(contextDraftsFor(updated))\n notifyChange()\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n } finally {\n setBusy(null)\n }\n }\n\n // Only checked models get a context row; the batch restore still covers every\n // stored override, including one left behind by a model the user unchecked.\n const contextModels = status?.models.filter((model) => model.enabled) ?? []\n const overrideCount = Object.keys(status?.contextWindowOverrides ?? {}).length\n\n if (loading) {\n return (\n <div className=\"dsha-page\">\n <div className=\"dsha-empty\">{t.loading}</div>\n </div>\n )\n }\n\n const quota = status?.quota\n const account = status?.account\n const visibleCount = status?.models.filter((model) => model.enabled).length || 0\n\n return (\n <div className=\"dsha-page\">\n <AccountPoolSection\n accounts={status?.accounts ?? []}\n activeAccountId={status?.activeAccountId}\n rotationStrategy={status?.rotationStrategy ?? 'sequential'}\n busy={busy}\n labels={t}\n loginBusyLabel={busy === 'login' ? (loginProgress || t.signingIn) : undefined}\n onLogin={() => void handleLogin()}\n onSetPrimary={(accountId) => void handleAccountAction('set-primary', accountId)}\n onDelete={(accountId) => void handleAccountAction('delete', accountId)}\n onClearCooldown={(accountId) => void handleAccountAction('clear-cooldown', accountId)}\n onRelogin={(accountId) => handleRelogin(accountId)}\n onSetStrategy={(strategy) => void handleSetStrategy(strategy)}\n showQuota\n renderDetails={(entry) => (\n <>\n {entry.keyName && <span>{t.keyName}: {entry.keyName}</span>}\n {entry.planLabel && <span>{t.plan}: {entry.planLabel}</span>}\n </>\n )}\n >\n <p className=\"dsha-muted\" style={{ paddingTop: 12 }}>{t.apiKeyHint}</p>\n <div className=\"dsha-capacity-control\">\n <input\n type=\"password\"\n aria-label={t.apiKeySection}\n placeholder={t.apiKeyPlaceholder}\n value={apiKey}\n onChange={(event) => setApiKey(event.currentTarget.value)}\n onKeyDown={(event) => {\n if (event.key === 'Enter' && apiKey.trim() !== '') void handleApiKey()\n }}\n />\n <button\n type=\"button\"\n className=\"dsha-context-save\"\n disabled={busy !== null || apiKey.trim() === ''}\n onClick={() => void handleApiKey()}\n >\n {busy === 'apikey' ? t.apiKeySaving : t.apiKeySave}\n </button>\n </div>\n </AccountPoolSection>\n\n <section className=\"dsha-group\">\n <div className=\"dsha-grouphead\">\n <h3>{t.connection}</h3>\n </div>\n <p className=\"dsha-notice\">{status?.serving === false && status.conflict ? t.routeConflict.replace('{detail}', status.conflict) : t.routeOwned}</p>\n <div className=\"dsha-actions\">\n <button className=\"dsha-btn\" disabled={busy !== null || !status?.authenticated} onClick={() => void handleTestConnection()}>\n {busy === 'connection' ? t.testingConnection : t.testConnection}\n </button>\n </div>\n </section>\n\n <section className=\"dsha-group\">\n <div className=\"dsha-grouphead\">\n <h3>{t.modelsSection}</h3>\n <button className=\"dsha-btn\" disabled={busy !== null} onClick={() => void handleRefreshCatalog()}>\n {busy === 'catalog' ? t.refreshingCatalog : t.refreshCatalog}\n </button>\n </div>\n <p className=\"dsha-muted dsha-models-hint\">{t.modelsHint}</p>\n {status?.catalogStale !== undefined && (\n <p className=\"dsha-muted\" data-testid=\"command-code-catalog-freshness\">\n {status.catalogStale ? t.catalogStale : t.catalogFresh} · {formatDate(status.catalogFetchedAt)}\n </p>\n )}\n {status?.zeroDataRetention === true && <p className=\"dsha-notice\" data-testid=\"command-code-zdr\">{t.zdrEnabled}</p>}\n <ModelChecklist\n items={(status?.models ?? []).map((model: CommandCodeModelOption) => ({\n id: model.id,\n name: model.name,\n hint: wireLabel(model.wire, t),\n enabled: model.enabled,\n }))}\n busy={busy !== null}\n onToggle={toggleModel}\n onToggleAll={setAllModels}\n labels={{ selectAll: t.selectAll, clearAll: t.unselectAll, list: t.modelsSection }}\n />\n </section>\n\n <section className=\"dsha-group\">\n <div className=\"dsha-grouphead\">\n <h3>{t.enhanced}</h3>\n </div>\n <div className=\"dsha-pref-row\">\n <div>\n <strong>{t.defaultReasoningEffort}</strong>\n <p className=\"dsha-muted\">{t.defaultReasoningEffortHint}</p>\n </div>\n <select\n className=\"dsha-select\"\n aria-label={t.defaultReasoningEffort}\n value={status?.defaultReasoningEffort ?? ''}\n disabled={busy !== null}\n onChange={(event) => {\n const value = event.currentTarget.value\n void handleUpdateEffort(value === '' ? null : (value as CommandCodeReasoningEffort))\n }}\n >\n <option value=\"\">{t.defaultEffortAuto}</option>\n {COMMAND_CODE_REASONING_EFFORTS.map((effort) => (\n <option key={effort} value={effort}>{EFFORT_LABELS[effort]}</option>\n ))}\n </select>\n </div>\n </section>\n\n <section className=\"dsha-group\">\n <div className=\"dsha-grouphead\">\n <h3>{t.contextWindowSection}</h3>\n </div>\n <p className=\"dsha-muted\">{t.contextWindowHint}</p>\n <ContextWindowEditor\n rows={contextModels.map((model: CommandCodeModelOption) => ({\n id: model.id,\n name: model.name,\n draft: contextDrafts[model.id] ?? '',\n inputLabel: `${model.name} context window`,\n hasOverride: status?.contextWindowOverrides[model.id] !== undefined,\n saving: savingModel === model.id,\n }))}\n labels={{\n tokens: t.tokens,\n save: t.save,\n saving: t.saving,\n reset: t.contextWindowReset,\n resetAll: t.contextWindowResetAll,\n empty: t.contextWindowNoneEnabled,\n }}\n busy={busy !== null}\n overrideCount={overrideCount}\n onDraftChange={(id, draft) => setContextDrafts((prev) => ({ ...prev, [id]: draft }))}\n onCommit={(id) => void handleSaveContextWindow(id)}\n onReset={(id) => void handleResetContextWindow(id)}\n onResetAll={() => void handleResetAllContextWindows()}\n />\n </section>\n\n <section className=\"dsha-group\">\n <div className=\"dsha-grouphead\">\n <h3>{t.quotaSection}</h3>\n <button className=\"dsha-btn\" disabled={busy !== null || !status?.authenticated} onClick={() => void handleRefreshQuota()}>\n {busy === 'quota' ? t.refreshingQuota : t.refreshQuota}\n </button>\n </div>\n <p className=\"dsha-muted\">{t.quotaDesc}</p>\n {/* The progress bars moved into each account card: quota follows the\n account, so a bar here could only ever describe whichever account\n happened to be active when the snapshot was read. What stays is what\n has no per-account bar to live in — the credits, the meters that\n state no share, and the freshness of this reading. */}\n <p className=\"dsha-muted\">{t.quotaFactsScope}</p>\n\n {!status?.authenticated ? (\n <div className=\"dsha-empty\">{t.signedOut}</div>\n ) : quota === null || quota === undefined ? (\n <div className=\"dsha-empty\">{busy === 'quota' ? t.refreshingQuota : t.quotaEmpty}</div>\n ) : (\n <div className=\"dsha-quota-card\">\n <div className=\"dsha-quota-title\">\n <strong>{t.quotaCredits}</strong>\n <span>\n {quota.unlimited\n ? t.quotaUnlimited\n : quota.creditBalance !== null\n ? quota.creditBalance\n : '—'}\n </span>\n </div>\n\n {quota.meters.filter((meter) => meter.remainingFraction === null).map((meter) => (\n <div key={meter.id} className=\"dsha-meter-wrap\">\n <div className=\"dsha-meter-label\">\n <span>{meter.label}</span>\n <strong>{meter.limit ?? '—'}</strong>\n </div>\n {meter.used !== null && (\n <div className=\"dsha-meter-meta\"><span>{meter.used} / {meter.limit ?? '—'}</span></div>\n )}\n {meter.description !== null && (\n <div className=\"dsha-meter-meta\"><span>{meter.description}</span></div>\n )}\n </div>\n ))}\n\n {quota.meters.length === 0 && quota.windows.length === 0 && (\n <div className=\"dsha-empty\">{t.quotaEmpty}</div>\n )}\n\n <div className=\"dsha-timestamp\">\n {t.updatedAt.replace('{time}', new Date(quota.fetchedAt).toLocaleString())}\n </div>\n </div>\n )}\n </section>\n\n {error && (\n <div className=\"dsha-error\">\n <div>{error}</div>\n </div>\n )}\n </div>\n )\n}\n","/**\n * Wire contracts between the Kimi Code host routes and the browser settings\n * card. Everything here is public: no credential ever crosses this boundary.\n *\n * Kimi Code (https://www.kimi.com/code) is a Moonshot AI coding subscription,\n * distinct from the pay-as-you-go Moonshot Open Platform: its credentials come\n * from an OAuth device flow against auth.kimi.com and its inference lives at\n * https://api.kimi.com/coding/v1.\n */\n\nimport type { AccountRotationStrategy, PoolAccountSummaryDto } from './account-pool-contracts.ts'\n\n/** Region a Kimi Code account belongs to; decides which hosts the client uses. */\nexport type KimiCodeRegion = 'mainland-cn' | 'global'\n\n/**\n * Request/response dialect used for the model calls.\n *\n * The official Kimi Code CLI configures its managed provider as `type = \"kimi\"`,\n * an OpenAI-compatible chat-completions client, so that is the default here.\n * The Anthropic Messages dialect is offered too because the service documents\n * `https://api.kimi.com/coding/` as an Anthropic-compatible base URL for\n * third-party tools, and some models behave better with a thinking budget.\n */\nexport type KimiCodeWire = 'openai' | 'anthropic'\n\n/**\n * Thinking level a Kimi Code model accepts.\n *\n * Kimi Code maps a tool's effort onto exactly three K3 levels plus a thinking-off\n * switch. The documented mapping is authoritative and deliberately narrower than\n * the generic level set other providers use:\n *\n * - `low` <- `low` / `minimum` / `light`\n * - `high` <- `high` / `medium`\n * - `max` <- `ultra` / `max` / `xhigh`\n * - `none` -> thinking disabled (`thinking.type = \"disabled\"`)\n *\n * Anything else the client sends is rejected by the service with HTTP 400, so\n * no other level is ever put on the wire.\n */\nexport type KimiCodeReasoningEffort = 'low' | 'high' | 'max' | 'none'\n\n/**\n * Prompt-cache TTL the Kimi subscription accepts.\n *\n * The two wires spell the request differently (`prompt_cache_options` on the\n * OpenAI one, a TOP-LEVEL `cache_control` on the Anthropic one), but the tier\n * names are the same. `null` in the settings means \"send neither\", which is\n * the service's own default behaviour.\n */\nexport type KimiCodeCacheTtl = '5m' | '1h'\n\n/**\n * How the service says a model handles thinking, when it says so at all.\n *\n * The three-state declaration is strictly more informative than a boolean:\n * `only` distinguishes \"always reasons\" from \"no reasoning support\", which\n * a single boolean cannot express, and the two demand opposite treatment —\n * the first must not be offered a `none` effort, the second must be offered\n * nothing at all.\n */\nexport type KimiCodeThinkingType = 'only' | 'no' | 'both'\n\n/** Every level, in escalating order; the settings card renders exactly these. */\nexport const KIMI_CODE_REASONING_EFFORTS: readonly KimiCodeReasoningEffort[] =\n ['low', 'high', 'max', 'none']\n\n/** One model offered by the Kimi Code coding endpoint. */\nexport interface KimiCodeModelOption {\n id: string\n name: string\n /** Enabled models are the ones DSH offers in the conversation model picker. */\n enabled: boolean\n /** Context window the catalog reports for this model. */\n defaultContextWindow: number\n /** Effective context window: the override when one is saved, else the default. */\n contextWindow: number\n /**\n * Largest prompt the endpoint accepts, when the service states a cap below\n * the context window.\n *\n * A model can have a 1M window and a lower input limit. The window still\n * bounds the completion budget, but a prompt sized against it overshoots into\n * a rejected request instead of a compaction, so the two are reported\n * separately.\n */\n maxInputTokens?: number\n /**\n * Ceiling for the prompt of one turn.\n *\n * The smaller of the effective window and {@link maxInputTokens}; always a\n * number, so a caller never has to decide which of the two applies.\n */\n promptBudget: number\n /** Maximum output tokens this route requests when a caller omits one. */\n defaultMaxTokens: number\n /** Thinking levels this model accepts; absent for a model that cannot reason. */\n reasoningEfforts?: string[]\n /** Thinking level used when the conversation does not pick one. */\n defaultReasoningEffort?: string\n /** Request/response dialect the adapter uses on the wire. */\n wire: KimiCodeWire\n /** Human description from the official model table. */\n description: string | null\n /** Whether the model accepts video input as well as images. */\n supportsVideo: boolean\n /**\n * Whether the model accepts message-level tool declarations\n * (`messages[].tools`), Kimi's `dynamically_loaded_tools` capability.\n *\n * The card shows it because it is the one K3 feature that changes how a\n * client should be shaped rather than what it may send: a session that\n * progressively discloses tools keeps its top-level list stable, which is\n * what protects the prefix cache.\n */\n supportsDynamicTools: boolean\n /**\n * Whether the model accepts tool declarations at all.\n *\n * Wider than {@link supportsDynamicTools}, which asks only about message-level\n * declarations: a model may take tools at the top level and not per message.\n * The card shows both because a false here is the one that breaks every\n * coding session on the model.\n */\n supportsToolUse: boolean\n /** Subscription tier the model needs, when it is not open to every member. */\n minimumPlan: string | null\n}\n\n/** One quota window reported for the signed-in account. */\nexport interface KimiCodeUsageWindow {\n id: string\n label: string\n /** Used fraction in [0, 1]. */\n usedFraction: number\n /** Convenience integer for the card and badge. */\n usedPercent: number\n /** Nominal window length in minutes, when the service states one. */\n windowDurationMins: number | null\n /** Unix milliseconds the window resets, when reported. */\n resetsAt: number | null\n /** Allowance as the service reports it (request counts), when reported. */\n limit: string | null\n used: string | null\n remaining: string | null\n}\n\n/** Pay-as-you-go wallet the account can fall back on once a window is spent. */\nexport interface KimiCodeExtraUsage {\n /** Remaining wallet balance in the currency's minor unit. */\n balanceCents: number | null\n totalCents: number | null\n monthlyChargeLimitEnabled: boolean\n monthlyChargeLimitCents: number | null\n monthlyUsedCents: number | null\n currency: string | null\n}\n\n/** Account identity, resolved from the token and the usage response. */\nexport interface KimiCodeAccount {\n userId: string | null\n nickname: string | null\n email: string | null\n /** Subscription tier display name, for example Moderato. */\n planName: string | null\n /** Machine tier level when the service reports one. */\n planLevel: string | null\n region: KimiCodeRegion | null\n authenticatedAt: number | null\n}\n\n/** One point-in-time quota snapshot for the signed-in Kimi Code account. */\nexport interface KimiCodeAccountQuota {\n account: KimiCodeAccount\n /** Subscription tier display name, when the service reports one. */\n planName: string | null\n /** Every quota window the account currently has. */\n windows: KimiCodeUsageWindow[]\n /** Pay-as-you-go booster wallet, when the account has one. */\n extraUsage: KimiCodeExtraUsage | null\n /** Unix milliseconds this snapshot was fetched. */\n fetchedAt: number\n /** Endpoint paths that answered, kept for diagnostics in the card. */\n sources: string[]\n}\n\n/** Everything the settings card and the composer badge render. */\nexport interface KimiCodeWebStatus {\n enabled?: boolean\n authenticated: boolean\n hasCredentials: boolean\n storagePath: string\n region: KimiCodeRegion\n oauthHost: string\n codingBaseUrl: string\n account: KimiCodeAccount | null\n quota: KimiCodeAccountQuota | null\n lastFetchedAt: number | null\n /**\n * Whether a quota refresh is running behind this answer.\n *\n * The card renders the snapshot it already had instead of waiting on the\n * upstream request; when this is true the client asks again shortly so the\n * refreshed snapshot reaches the UI.\n */\n quotaRefreshing?: boolean\n /** When true the stored refresh token was rejected and sign-in is required. */\n credentialsRejected: boolean\n /**\n * Why the quota could not be read, when the last attempt failed.\n *\n * Reported beside the snapshot rather than in place of it: a transient\n * failure should explain itself without hiding the account that is signed in.\n */\n quotaError?: string | null\n /** Rolling prefix-cache effectiveness for this process, when requests ran. */\n cache: KimiCodeCacheStatsDto | null\n /**\n * Warning that this conversation's prompt cache has expired, when it has and\n * the context is large enough for reprocessing to be worth mentioning.\n */\n cacheHint?: KimiCodeCacheHintDto | null\n /** Whether Preserved Thinking is currently requested on the wire. */\n preserveThinking: boolean\n models: KimiCodeModelOption[]\n contextWindowOverrides: Record<string, number>\n defaultReasoningEffort: KimiCodeReasoningEffort | null\n /**\n * Prompt-cache tier this line asks for. `null` means \"send no cache field\",\n * which is Kimi's own default behaviour.\n */\n cacheTtl: KimiCodeCacheTtl | null\n /** Signed-in accounts; empty or absent when no pool is installed. */\n accounts?: KimiCodeAccountSummaryDto[]\n /** Account the next request would use. */\n activeAccountId?: string\n rotationStrategy?: AccountRotationStrategy\n /** Region used for the next login flow. */\n loginRegion: KimiCodeRegion\n /** Route the plugin currently serves; false when another plugin owns it. */\n serving: boolean\n /** Diagnostic when the route is owned by a different adapter family. */\n conflict: string | null\n}\n\n/**\n * How well Kimi's automatic prefix cache is working for this process.\n *\n * Reported because the cache is invisible otherwise: it is content-hash based\n * with no marker to set, so the read ratio is the only evidence a session is\n * actually reusing its prefix.\n */\nexport interface KimiCodeCacheStatsDto {\n requests: number\n cachedTokens: number\n freshTokens: number\n outputTokens: number\n /** Cached / (cached + fresh); null until a request reports usage. */\n hitRatio: number | null\n /**\n * Why the most recent request's prefix broke, when it did.\n *\n * Surfaces the diagnostic half of the hit ratio: `'stable'` means the prefix\n * should have held (so a miss implicates content below the head or the\n * service), while the other values name the input that invalidated the cache.\n */\n lastDrift?: 'first-request' | 'stable' | 'system-prompt' | 'tools' | 'cache-key' | 'cold-key'\n /**\n * Always 0 on this route: the endpoint writes cache entries without counting\n * them, so there is no write cost to track.\n *\n * Reported rather than dropped so the shape stays aligned with the sibling\n * providers that DO report writes, and so a route that starts counting them\n * needs no contract change.\n */\n cacheWriteTokensNote?: 'always-zero-on-this-route'\n}\n\n/**\n * A warning that the conversation's prompt cache has expired.\n *\n * Kimi's cache is content-hash based with no marker to set, so a client that\n * says nothing leaves the user paying a full reprocessing pass with no idea\n * why the next turn was slow. Absent means \"nothing to say\" — which is most\n * of the time, since the hint needs an idle period AND a context large enough\n * for reprocessing to matter.\n */\nexport interface KimiCodeCacheHintDto {\n /** How long the conversation has been idle, epoch ms. */\n idleMs: number\n /** Context that will be reprocessed on the next turn. */\n totalTokens: number\n}\n\n/** Patch accepted by the models/settings routes. */\nexport interface KimiCodeSettingsUpdateDto {\n enabled?: boolean\n enabledModelIds?: string[]\n /** A number sets an override for that model; `null` restores the catalog default. */\n contextWindowOverrides?: Record<string, number | null>\n defaultReasoningEffort?: KimiCodeReasoningEffort | null\n /** `null` clears the tier, returning to \"send no cache field\". */\n cacheTtl?: KimiCodeCacheTtl | null\n}\n\n/** One pooled Kimi Code account as the settings card renders it; never carries a token. */\nexport interface KimiCodeAccountSummaryDto extends PoolAccountSummaryDto {\n nickname?: string\n userId?: string\n planName?: string\n /** Region the credential was issued in; a pool may hold several. */\n region?: KimiCodeRegion\n}\n\n/** Live state of the device-code login flow the card polls. */\nexport interface KimiCodeLoginFlowStatus {\n status: 'idle' | 'pending' | 'complete' | 'error'\n /** Page the user must open, including the pre-filled user code. */\n verificationUriComplete?: string\n verificationUri?: string\n userCode?: string\n startedAt?: number\n completedAt?: number\n /** Unix milliseconds the device code stops being valid. */\n expiresAt?: number\n progress?: string\n error?: string\n}\n\n/** Result of an explicit connection test. */\nexport interface KimiCodeConnectionDto {\n connected: boolean\n latencyMs: number\n account: KimiCodeAccount | null\n}\n","import { accountPoolEn, accountPoolZh } from '../common/account-pool-labels.ts'\n\nexport const NS_KIMI_CODE = 'dsh-kimi-code'\n\nexport const zh = {\n // The account-management card is shared with every other provider tab.\n ...accountPoolZh,\n title: 'Kimi Code',\n pageDesc: '登录 Kimi Code 订阅,管理模型、思考档位、上下文窗口与额度。',\n account: '账号',\n signedIn: '已登录',\n signedOut: '未登录',\n nickname: '昵称',\n email: '邮箱',\n plan: '套餐',\n planUnknown: '—',\n region: '区域',\n regionMainland: '中国大陆 (kimi.com)',\n regionGlobal: '国际 (kimi.ai)',\n authenticatedAt: '登录时间',\n refreshRejected: '刷新令牌已被拒绝,请重新登录。',\n signIn: '设备码登录',\n signInAgain: '重新登录',\n signingIn: '登录中...',\n signOut: '注销',\n cancelSignIn: '取消登录',\n deviceCodeSection: '设备码授权',\n deviceCodeHint: '在浏览器中打开下方链接(已自动填充用户码),确认后用同一账号授权。',\n openSignInPage: '打开授权页面',\n copyCode: '复制用户码',\n copied: '已复制',\n userCode: '用户码',\n codeExpires: '有效期至',\n waitingAuthorization: '等待浏览器授权...',\n requestingCode: '正在申请设备码...',\n connection: '连接',\n oauthHost: 'OAuth 主机',\n codingEndpoint: '模型接口',\n testConnection: '测试连接',\n testingConnection: '测试中...',\n testSuccess: '连接正常',\n testFailed: '连接失败:Kimi Code 未接受当前凭据',\n routeOwned: '模型路由由本插件提供',\n routeConflict: '模型路由已被其他 Provider 占用:{detail}。请在 DSH 设置中移除重复的 Provider 配置后重试。',\n modelsSection: '模型',\n modelsHint: '勾选后模型才会出现在对话页的模型选择列表中;全部取消勾选或关闭概览卡片上的开关可在列表中隐藏该供应商。',\n refreshCatalog: '刷新模型目录',\n refreshingCatalog: '刷新中...',\n selectAll: '全选',\n unselectAll: '全不选',\n wireAnthropic: 'Anthropic',\n wireOpenai: 'OpenAI',\n capVideo: '视频*',\n capDynamicTools: '动态工具',\n capImageOnly: '仅图片',\n capNone: '—',\n capVideoFootnote: '* 视频输入需先由 kimi_attach_video 工具挂载(本地绝对路径或 http(s) 链接);直接粘贴的上传路径仍只支持图片。',\n capabilitiesTitle: '模型能力',\n capColMedia: '多模态',\n capColTools: '动态工具',\n capColNotes: '说明',\n capPlan: '需要套餐:{plan}',\n capInputCap: '输入上限 {tokens}',\n capNoTools: '不支持工具',\n speedRegular: '标准',\n speedHighspeed: '高速 (约 6×)',\n quotaCost: '额度倍率',\n minimumPlan: '所需套餐',\n enhanced: '思考设置',\n defaultReasoningEffort: '默认思考档位',\n defaultReasoningEffortHint: 'Kimi Code 只接受 low / high / max 三档;none 表示关闭思考。切换档位会使上下文缓存失效,建议在同一会话中保持一致。',\n cacheTtl: '上下文缓存时长',\n cacheTtlHint: 'Kimi 按前缀自动缓存,这里选择写入时长。1h 写入更贵,只有当同一前缀会在一小时内被反复读取才划算;档位在首次写入时锁定,之后无法改写。留空表示不指定,由 Kimi 自己决定。',\n cacheTtlDefault: '不指定(Kimi 默认)',\n cacheTtl5m: '5 分钟',\n cacheTtl1h: '1 小时',\n defaultEffortAuto: '使用模型默认值',\n effortLow: '低 (low)',\n effortHigh: '高 (high)',\n effortMax: '最高 (max)',\n effortNone: '关闭思考',\n contextWindowSection: '模型上下文窗口',\n contextWindowHint: '默认取模型目录的上下文长度。k3 的 1M 上下文需要 Allegretto 及以上套餐,因此默认按 256K 计算;如已升级可在此覆盖为 1M。',\n contextWindowPlan: '完整上下文需要 {plan} 套餐',\n contextWindowReset: '恢复默认',\n contextWindowResetAll: '全部恢复默认',\n contextWindowResetAllConfirm: '确定把已改过的模型上下文窗口全部恢复为默认值吗?',\n contextWindowNoneEnabled: '还没有勾选任何模型。在上方勾选后,这里会出现该模型的上下文窗口设置。',\n save: '保存',\n saved: '已保存',\n saving: '保存中...',\n cacheSection: '缓存与 K3 调优',\n cacheDesc: 'Kimi 的前缀缓存按请求内容自动命中,无需也无法手动声明,因此这里用读缓存比例反映实际效果。',\n cacheEmpty: '本进程还没有带用量回报的请求。',\n cacheHitRatio: '缓存命中率',\n cacheCached: '命中 tokens',\n cacheFresh: '新处理 tokens',\n cacheOutput: '输出 tokens',\n cacheRequests: '请求数',\n cacheHint: '同一会话内:系统提示与工具列表一旦变化会使缓存整体失效,因此保持工具集合稳定、把新增内容追加在末尾,命中率最高。',\n cacheExpired: '本会话已空闲超过缓存有效期,下一轮将重新处理约 {tokens} 个 token。',\n cacheDrift: '最近前缀状态',\n cacheDriftFirst: '首个请求(缓存为空)',\n cacheDriftStable: '稳定(前缀未变)',\n cacheDriftSystemPrompt: '系统提示已变化(缓存失效)',\n cacheDriftTools: '工具列表已变化(缓存失效)',\n cacheDriftCacheKey: '缓存键已变化(会话切换)',\n cacheDriftColdKey: '未发送缓存键(无法命中)',\n preserveThinking: '保留思考 (Preserved Thinking)',\n preserveOn: '已开启(官方默认):跨轮保留 reasoning_content,多轮工具调用更连贯,但思考 token 也计入输出。',\n preserveOff: '已关闭:不要求服务回传推理内容。可设置 DSH_KIMI_CODE_PRESERVE_THINKING=0 关闭。',\n outputCap: '输出上限跟随上下文窗口,长思考不会被 32K 截断',\n quotaSection: '用量与额度',\n quotaDesc: '数据来自 Kimi Code 账户接口,页面可见时最多每 60 秒刷新一次。',\n refreshQuota: '刷新用量',\n refreshingQuota: '刷新中...',\n quotaEmpty: '暂无配额数据,点击「刷新用量」重试。',\n quotaPlan: '当前套餐',\n quotaWallet: '加油包余额',\n quotaWalletLimit: '月度上限',\n quotaWalletUsed: '本月已用',\n updatedAt: '更新时间:{time}',\n resetAt: '重置:{time}',\n loading: '加载中...',\n loginFailed: '登录失败',\n requests: '次请求',\n tokens: 'tokens',\n} as const\n\nexport const en: Record<keyof typeof zh, string> = {\n ...accountPoolEn,\n title: 'Kimi Code',\n pageDesc: 'Sign in to the Kimi Code subscription and manage models, thinking level, context windows, and quota.',\n account: 'Account',\n signedIn: 'Signed in',\n signedOut: 'Not signed in',\n nickname: 'Nickname',\n email: 'Email',\n plan: 'Plan',\n planUnknown: '—',\n region: 'Region',\n regionMainland: 'Mainland China (kimi.com)',\n regionGlobal: 'Global (kimi.ai)',\n authenticatedAt: 'Signed in at',\n refreshRejected: 'The refresh token was rejected — sign in again.',\n signIn: 'Sign in with device code',\n signInAgain: 'Sign in again',\n signingIn: 'Signing in...',\n signOut: 'Sign out',\n cancelSignIn: 'Cancel',\n deviceCodeSection: 'Device authorization',\n deviceCodeHint: 'Open the link below in a browser (the user code is pre-filled) and approve it with the same account.',\n openSignInPage: 'Open the sign-in page',\n copyCode: 'Copy user code',\n copied: 'Copied',\n userCode: 'User code',\n codeExpires: 'Expires at',\n waitingAuthorization: 'Waiting for browser authorization...',\n requestingCode: 'Requesting a device code...',\n connection: 'Connection',\n oauthHost: 'OAuth host',\n codingEndpoint: 'Model endpoint',\n testConnection: 'Test connection',\n testingConnection: 'Testing...',\n testSuccess: 'Connection OK',\n testFailed: 'Connection failed: Kimi Code did not accept the stored credential',\n routeOwned: 'This plugin serves the model route',\n routeConflict: 'Another provider already owns the model route: {detail}. Remove the duplicate provider configuration in DSH settings and reload.',\n modelsSection: 'Models',\n modelsHint: 'Checked models appear in the DSH conversation model list; unchecking all or turning off the switch on the overview card hides this provider.',\n refreshCatalog: 'Refresh catalog',\n refreshingCatalog: 'Refreshing...',\n selectAll: 'Select all',\n unselectAll: 'Deselect all',\n wireAnthropic: 'Anthropic',\n wireOpenai: 'OpenAI',\n capVideo: 'Video*',\n capDynamicTools: 'Dynamic tools',\n capImageOnly: 'Images',\n capNone: '—',\n capVideoFootnote: '* Video input is attached with the kimi_attach_video tool (an absolute local path or an http(s) URL); the paste/upload path still accepts images only.',\n capabilitiesTitle: 'Capabilities',\n capColMedia: 'Multimodal',\n capColTools: 'Dynamic tools',\n capColNotes: 'Notes',\n capPlan: 'Requires plan: {plan}',\n capInputCap: 'Input cap {tokens}',\n capNoTools: 'No tools',\n speedRegular: 'Regular',\n speedHighspeed: 'HighSpeed (~6x)',\n quotaCost: 'Quota cost',\n minimumPlan: 'Required plan',\n enhanced: 'Thinking',\n defaultReasoningEffort: 'Default thinking level',\n defaultReasoningEffortHint: 'Kimi Code accepts only low / high / max; none disables thinking. Switching the level invalidates the context cache, so keep it steady within a session.',\n cacheTtl: 'Context cache duration',\n cacheTtlHint: 'Kimi caches prefixes automatically; this chooses the write duration. A 1h write costs more and only pays off when the same prefix is re-read within the hour. The tier is locked when first written and cannot be changed afterwards. Leave unset to send no cache field and let Kimi decide.',\n cacheTtlDefault: 'Unset (Kimi default)',\n cacheTtl5m: '5 minutes',\n cacheTtl1h: '1 hour',\n defaultEffortAuto: 'Use the model default',\n effortLow: 'Low',\n effortHigh: 'High',\n effortMax: 'Max',\n effortNone: 'Thinking off',\n contextWindowSection: 'Model context window',\n contextWindowHint: 'Defaults to the catalog context length. k3 reaches 1M only on Allegretto and above, so it defaults to 256K; raise the override here after upgrading.',\n contextWindowPlan: 'Full context requires the {plan} plan',\n contextWindowReset: 'Restore default',\n contextWindowResetAll: 'Restore all defaults',\n contextWindowResetAllConfirm: 'Restore every changed model context window to its default?',\n contextWindowNoneEnabled: 'No model is checked yet. Check one above and its context window setting appears here.',\n save: 'Save',\n saved: 'Saved',\n saving: 'Saving...',\n cacheSection: 'Cache & K3 tuning',\n cacheDesc: \"Kimi's prefix cache is automatic and content-hash based — there is no marker to set — so the cache-read ratio is the only evidence it is working.\",\n cacheEmpty: 'No request in this process has reported usage yet.',\n cacheExpired: 'This conversation sat idle past the cache lifetime, so the next turn reprocesses about {tokens} tokens.',\n cacheHitRatio: 'Cache hit ratio',\n cacheCached: 'Cached tokens',\n cacheFresh: 'Fresh tokens',\n cacheOutput: 'Output tokens',\n cacheRequests: 'Requests',\n cacheHint: 'Within one session: any change to the system prompt or the tool list invalidates the whole prefix cache, so keep the tool set stable and append new material at the tail for the best hit rate.',\n cacheDrift: 'Last prefix state',\n cacheDriftFirst: 'First request (cache cold)',\n cacheDriftStable: 'Stable (prefix unchanged)',\n cacheDriftSystemPrompt: 'System prompt changed (cache invalidated)',\n cacheDriftTools: 'Tool list changed (cache invalidated)',\n cacheDriftCacheKey: 'Cache key changed (session switch)',\n cacheDriftColdKey: 'No cache key sent (cannot hit)',\n preserveThinking: 'Preserved Thinking',\n preserveOn: 'On (the official default): reasoning_content is retained across turns, which keeps multi-step tool use coherent — its tokens are billed as output.',\n preserveOff: 'Off: the service is not asked to return reasoning. Set DSH_KIMI_CODE_PRESERVE_THINKING=0 to disable.',\n outputCap: 'Output cap follows the context window, so long reasoning is not cut off at 32K',\n quotaSection: 'Usage & quota',\n quotaDesc: 'Read from the Kimi Code account endpoints; refreshes at most once every 60 seconds while visible.',\n refreshQuota: 'Refresh quota',\n refreshingQuota: 'Refreshing...',\n quotaEmpty: 'No quota data yet — use \"Refresh quota\" to retry.',\n quotaPlan: 'Current plan',\n quotaWallet: 'Booster wallet',\n quotaWalletLimit: 'Monthly cap',\n quotaWalletUsed: 'Used this month',\n updatedAt: 'Updated at: {time}',\n resetAt: 'Reset: {time}',\n loading: 'Loading...',\n loginFailed: 'Sign-in failed',\n requests: 'requests',\n tokens: 'tokens',\n} as const\n\nexport const dictionaries = {\n zh,\n 'zh-CN': zh,\n en,\n 'en-US': en,\n}\n\nexport type KimiCodeLocaleKey = keyof typeof zh\n","/**\n * Capability table for the Kimi model list.\n *\n * Extracted from the settings card so the layout is testable: an earlier\n * revision inlined each capability as prose beside the model name, which\n * stretched the name column and pushed the descriptions out of alignment.\n * Capabilities are now short tags in their own columns, with the per-model\n * detail kept in a hover title.\n */\nimport React from 'react'\nimport type { KimiCodeModelOption } from '../../shared/kimi-code-contracts.ts'\nimport { zh } from './locales.ts'\n\nconst t = zh\n\nexport interface KimiModelCapabilitiesProps {\n models: KimiCodeModelOption[]\n}\n\nexport function KimiModelCapabilities({ models }: KimiModelCapabilitiesProps): React.ReactElement {\n return (\n <div className=\"dsha-cap-table\">\n <table>\n <thead>\n <tr>\n <th>{t.capabilitiesTitle}</th>\n <th>{t.capColMedia}</th>\n <th>{t.capColTools}</th>\n <th>{t.capColNotes}</th>\n </tr>\n </thead>\n <tbody>\n {models.map((model) => {\n // Hover text keeps the per-model facts that would otherwise bloat\n // the table: wire, default effort, input cap and required plan.\n const facts = [\n model.id,\n model.wire === 'anthropic' ? t.wireAnthropic : t.wireOpenai,\n ...(model.defaultReasoningEffort ? [t.defaultReasoningEffort + ': ' + model.defaultReasoningEffort] : []),\n ...(model.maxInputTokens === undefined\n ? []\n : [t.capInputCap.replace('{tokens}', String(model.maxInputTokens))]),\n ...(model.minimumPlan ? [t.capPlan.replace('{plan}', model.minimumPlan)] : []),\n ]\n return (\n <tr key={model.id}>\n <td title={facts.join(' · ')}>{model.name}</td>\n <td>\n <span className={model.supportsVideo ? 'dsha-cap-on' : 'dsha-cap-off'}>\n {model.supportsVideo ? t.capVideo : t.capImageOnly}\n </span>\n </td>\n <td>\n {model.supportsDynamicTools\n ? <span className=\"dsha-cap-on\">{t.capDynamicTools}</span>\n // Tools work but per-message disclosure does not: a dash.\n : model.supportsToolUse\n ? <span className=\"dsha-cap-off\">{t.capNone}</span>\n // No tools at all, which breaks every coding session on\n // the model — worth naming rather than another dash.\n : <span className=\"dsha-cap-off\">{t.capNoTools}</span>}\n </td>\n <td className=\"dsha-cap-notes\">{model.description ?? ''}</td>\n </tr>\n )\n })}\n </tbody>\n </table>\n {models.some((model) => model.supportsVideo) && (\n <p className=\"dsha-muted dsha-cap-footnote\">{t.capVideoFootnote}</p>\n )}\n </div>\n )\n}\n","import React, { useCallback, useEffect, useRef, useState } from 'react'\nimport type {\n KimiCodeCacheTtl,\n KimiCodeLoginFlowStatus,\n KimiCodeModelOption,\n KimiCodeReasoningEffort,\n KimiCodeWebStatus,\n} from '../../shared/kimi-code-contracts.ts'\nimport { KIMI_CODE_REASONING_EFFORTS } from '../../shared/kimi-code-contracts.ts'\nimport { AccountPoolSection } from '../common/AccountPoolSection.tsx'\nimport { ContextWindowEditor, contextDraftsFor } from '../common/ContextWindowEditor.tsx'\nimport { ModelChecklist } from '../common/ModelChecklist.tsx'\nimport { createLineApi } from '../common/line-api.ts'\nimport { createQuotaFollowUp, type QuotaFollowUp } from '../common/quota-follow-up.ts'\nimport { formatCapacity, formatDate, parsePositiveCapacity } from '../common/format.ts'\nimport type { AccountRotationStrategy } from '../../shared/account-pool-contracts.ts'\nimport { zh } from './locales.ts'\nimport { KimiModelCapabilities } from './KimiModelCapabilities.tsx'\n\nconst API = '/kimi-code/api'\nconst api = createLineApi(API, 'Kimi Code')\n\ninterface Props {\n onModelChange?: () => void\n loadModelDirectory?: () => void\n}\n\n/** Money the service reports in minor units, rendered in its own currency. */\nfunction formatMoney(cents: number | null, currency: string | null): string {\n if (cents === null) return '—'\n const code = currency ?? 'USD'\n try {\n return new Intl.NumberFormat(undefined, { style: 'currency', currency: code }).format(cents / 100)\n } catch {\n return `${(cents / 100).toFixed(2)} ${code}`\n }\n}\n\nconst EFFORT_LABEL: Record<KimiCodeReasoningEffort, string> = {\n low: zh.effortLow,\n high: zh.effortHigh,\n max: zh.effortMax,\n none: zh.effortNone,\n}\n\n/** Human label for the last request's prefix-drift cause. */\nfunction driftLabel(\n cause: NonNullable<NonNullable<KimiCodeWebStatus['cache']>['lastDrift']>,\n t: typeof zh,\n): string {\n switch (cause) {\n case 'first-request': return t.cacheDriftFirst\n case 'stable': return t.cacheDriftStable\n case 'system-prompt': return t.cacheDriftSystemPrompt\n case 'tools': return t.cacheDriftTools\n case 'cache-key': return t.cacheDriftCacheKey\n case 'cold-key': return t.cacheDriftColdKey\n default: return String(cause)\n }\n}\n\nexport function KimiCodeSection({ onModelChange, loadModelDirectory }: Props): React.ReactElement {\n const [status, setStatus] = useState<KimiCodeWebStatus | null>(null)\n const [loading, setLoading] = useState(true)\n const [busy, setBusy] = useState<string | null>(null)\n const [error, setError] = useState<string | null>(null)\n const [flow, setFlow] = useState<KimiCodeLoginFlowStatus | null>(null)\n const [contextDrafts, setContextDrafts] = useState<Record<string, string>>({})\n const [savingModel, setSavingModel] = useState<string | null>(null)\n const [copied, setCopied] = useState(false)\n // Result of an explicit connection test. The button used to end silently on\n // success, which is indistinguishable from a click that never registered.\n const [connectionNotice, setConnectionNotice] = useState<string | null>(null)\n\n /** Follow-up poll owed while the host refreshes the quota behind an answer. */\n const quotaFollowUp = useRef<QuotaFollowUp | null>(null)\n\n const t = zh\n\n const notifyChange = useCallback(() => {\n onModelChange?.()\n loadModelDirectory?.()\n }, [onModelChange, loadModelDirectory])\n\n const loadStatus = useCallback(async (quiet = false) => {\n if (!quiet) setError(null)\n try {\n const data = await api.request<KimiCodeWebStatus>('/status')\n setStatus(data)\n setContextDrafts(contextDraftsFor(data))\n // An answer that refreshed the quota behind itself is followed up shortly,\n // so the fresh numbers land without waiting for the next poll.\n quotaFollowUp.current ??= createQuotaFollowUp()\n quotaFollowUp.current.observe(data.quotaRefreshing === true, () => { void loadStatus(true) })\n } catch (err) {\n if (!quiet) setError(err instanceof Error ? err.message : String(err))\n } finally {\n setLoading(false)\n }\n }, [])\n\n useEffect(() => {\n void loadStatus()\n const refreshWhenVisible = () => {\n if (document.visibilityState === 'visible') void loadStatus(true)\n }\n document.addEventListener('visibilitychange', refreshWhenVisible)\n const timer = window.setInterval(refreshWhenVisible, 60_000)\n return () => {\n window.clearInterval(timer)\n document.removeEventListener('visibilitychange', refreshWhenVisible)\n quotaFollowUp.current?.cancel()\n }\n }, [loadStatus])\n\n // The login flow runs on the host and is polled here, because authorization\n // happens in a browser the card does not control.\n useEffect(() => {\n if (flow?.status !== 'pending') return\n const timer = window.setInterval(() => {\n void (async () => {\n try {\n const poll = await api.request<KimiCodeLoginFlowStatus>('/login/status')\n setFlow(poll)\n if (poll.status === 'complete') {\n await loadStatus()\n notifyChange()\n } else if (poll.status === 'error') {\n setError(poll.error || t.loginFailed)\n }\n } catch {\n // A failed poll is transient; the next tick retries.\n }\n })()\n }, 2000)\n return () => window.clearInterval(timer)\n }, [flow?.status, loadStatus, notifyChange, t.loginFailed])\n\n const handleLogin = async () => {\n try {\n setBusy('login')\n setError(null)\n setCopied(false)\n const next = await api.request<KimiCodeLoginFlowStatus>('/login', {\n method: 'POST',\n body: JSON.stringify({}),\n })\n setFlow(next)\n // The host already opened the browser; a failed launch is recoverable\n // because the card always renders the URL and the user code.\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n } finally {\n setBusy(null)\n }\n }\n\n const handleCancelLogin = async () => {\n try {\n await api.request<KimiCodeLoginFlowStatus>('/login/cancel', { method: 'POST' })\n setFlow({ status: 'idle' })\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n }\n }\n\n const handleCopyCode = async () => {\n const code = flow?.userCode\n if (!code) return\n try {\n await navigator.clipboard.writeText(code)\n setCopied(true)\n window.setTimeout(() => setCopied(false), 2000)\n } catch {\n // Clipboard access can be denied; the code stays visible to copy by hand.\n }\n }\n\n /** One account-level action on the shared pool card. */\n const handleAccountAction = async (\n action: 'set-primary' | 'delete' | 'clear-cooldown',\n accountId: string,\n ) => {\n try {\n setBusy(`${action}-${accountId}`)\n setError(null)\n const updated = await api.request<KimiCodeWebStatus>('/accounts', {\n method: 'POST',\n body: JSON.stringify({ action, accountId }),\n })\n setStatus(updated)\n setFlow({ status: 'idle' })\n notifyChange()\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n } finally {\n setBusy(null)\n }\n }\n\n const handleSetStrategy = async (strategy: AccountRotationStrategy) => {\n try {\n setBusy('strategy')\n setError(null)\n const updated = await api.request<KimiCodeWebStatus>('/accounts', {\n method: 'POST',\n body: JSON.stringify({ action: 'strategy', strategy }),\n })\n setStatus(updated)\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n } finally {\n setBusy(null)\n }\n }\n\n /**\n * Re-authorize one account.\n *\n * Nothing is deleted: the failure marker is cleared and the device-code flow\n * runs again, so the account keeps its alias and place in the rotation.\n */\n const handleRelogin = (accountId: string) => {\n void (async () => {\n try {\n const updated = await api.request<KimiCodeWebStatus>('/accounts', {\n method: 'POST',\n body: JSON.stringify({ action: 'relogin', accountId }),\n })\n setStatus(updated)\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n return\n }\n await handleLogin()\n })()\n }\n\n const handleRefreshQuota = async () => {\n try {\n setBusy('quota')\n setError(null)\n // The host reports the real outcome; a failure arrives as a thrown error\n // carrying the upstream reason rather than an indistinguishable 200.\n const updated = await api.request<KimiCodeWebStatus>('/quota', { method: 'POST' })\n setStatus(updated)\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n // Re-read so the card still shows the account and any recorded reason.\n await loadStatus(true)\n } finally {\n setBusy(null)\n }\n }\n\n const handleRefreshCatalog = async () => {\n try {\n setBusy('catalog')\n setError(null)\n const updated = await api.request<KimiCodeWebStatus>('/catalog/refresh', { method: 'POST' })\n setStatus(updated)\n setContextDrafts(contextDraftsFor(updated))\n notifyChange()\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n } finally {\n setBusy(null)\n }\n }\n\n const handleTestConnection = async () => {\n try {\n setBusy('connection')\n setError(null)\n setConnectionNotice(null)\n const result = await api.request<{ connected: boolean; latencyMs: number }>('/connection/test', {\n method: 'POST',\n })\n setConnectionNotice(result.connected ? `${t.testSuccess} · ${result.latencyMs} ms` : t.testFailed)\n // The probe is a real usage call, so the quota shown is now current.\n await loadStatus(true)\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n } finally {\n setBusy(null)\n }\n }\n\n const applyEnabled = async (enabledModelIds: string[]) => {\n try {\n const updated = await api.request<KimiCodeWebStatus>('/models', {\n method: 'POST',\n body: JSON.stringify({ enabledModelIds }),\n })\n setStatus(updated)\n // A model that was just checked has no draft yet; the context window\n // section only renders enabled models.\n setContextDrafts(contextDraftsFor(updated))\n notifyChange()\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n }\n }\n\n const toggleModel = (modelId: string, checked: boolean) => {\n if (!status) return\n const current = status.models.filter((model) => model.enabled).map((model) => model.id)\n const next = checked ? [...new Set([...current, modelId])] : current.filter((id) => id !== modelId)\n void applyEnabled(next)\n }\n\n const setAllModels = (selectAll: boolean) => {\n if (!status || status.models.length === 0) return\n void applyEnabled(selectAll ? status.models.map((model) => model.id) : [])\n }\n\n const handleUpdateEffort = async (effort: KimiCodeReasoningEffort | null) => {\n try {\n const updated = await api.request<KimiCodeWebStatus>('/settings', {\n method: 'POST',\n body: JSON.stringify({ defaultReasoningEffort: effort }),\n })\n setStatus(updated)\n notifyChange()\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n }\n }\n\n const handleUpdateCacheTtl = async (ttl: KimiCodeCacheTtl | null) => {\n try {\n const updated = await api.request<KimiCodeWebStatus>('/settings', {\n method: 'POST',\n body: JSON.stringify({ cacheTtl: ttl }),\n })\n setStatus(updated)\n notifyChange()\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n }\n }\n\n const handleSaveContextWindow = async (modelId: string) => {\n const raw = contextDrafts[modelId] || ''\n const parsed = parsePositiveCapacity(raw)\n if (parsed === null) {\n setError(`Invalid context capacity: ${raw}`)\n return\n }\n try {\n setSavingModel(modelId)\n setError(null)\n const updated = await api.request<KimiCodeWebStatus>('/settings', {\n method: 'POST',\n body: JSON.stringify({ contextWindowOverrides: { [modelId]: parsed } }),\n })\n setStatus(updated)\n setContextDrafts((prev) => ({ ...prev, [modelId]: formatCapacity(parsed) }))\n notifyChange()\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n } finally {\n setSavingModel(null)\n }\n }\n\n /** Clear one override; the row falls back to the catalog length. */\n const handleResetContextWindow = async (modelId: string) => {\n try {\n setSavingModel(modelId)\n setError(null)\n const updated = await api.request<KimiCodeWebStatus>('/settings', {\n method: 'POST',\n body: JSON.stringify({ contextWindowOverrides: { [modelId]: null } }),\n })\n setStatus(updated)\n setContextDrafts((prev) => {\n const model = updated.models.find((candidate) => candidate.id === modelId)\n return model === undefined ? prev : { ...prev, [modelId]: formatCapacity(model.defaultContextWindow) }\n })\n notifyChange()\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n } finally {\n setSavingModel(null)\n }\n }\n\n /** Clear every stored override, including models the picker no longer shows. */\n const handleResetAllContextWindows = async () => {\n const models = Object.keys(status?.contextWindowOverrides ?? {})\n if (models.length === 0) return\n if (typeof window !== 'undefined' && !window.confirm(t.contextWindowResetAllConfirm)) return\n try {\n setBusy('context')\n setError(null)\n const updated = await api.request<KimiCodeWebStatus>('/settings', {\n method: 'POST',\n body: JSON.stringify({ contextWindowOverrides: Object.fromEntries(models.map((model) => [model, null])) }),\n })\n setStatus(updated)\n setContextDrafts(contextDraftsFor(updated))\n notifyChange()\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n } finally {\n setBusy(null)\n }\n }\n\n // Only checked models get a context row; the batch restore still covers every\n // stored override, including one left behind by a model the user unchecked.\n const contextModels = status?.models.filter((model) => model.enabled) ?? []\n const overrideCount = Object.keys(status?.contextWindowOverrides ?? {}).length\n\n if (loading) {\n return (\n <div className=\"dsha-page\">\n <div className=\"dsha-empty\">{t.loading}</div>\n </div>\n )\n }\n\n const quota = status?.quota\n const account = status?.account\n const visibleCount = status?.models.filter((model) => model.enabled).length || 0\n const loginPending = flow?.status === 'pending'\n\n return (\n <div className=\"dsha-page\">\n <AccountPoolSection\n accounts={status?.accounts ?? []}\n activeAccountId={status?.activeAccountId}\n rotationStrategy={status?.rotationStrategy ?? 'sequential'}\n busy={busy}\n labels={t}\n loginBusyLabel={loginPending ? t.waitingAuthorization : busy === 'login' ? t.requestingCode : undefined}\n onLogin={() => void handleLogin()}\n onSetPrimary={(accountId) => void handleAccountAction('set-primary', accountId)}\n onDelete={(accountId) => void handleAccountAction('delete', accountId)}\n onClearCooldown={(accountId) => void handleAccountAction('clear-cooldown', accountId)}\n onRelogin={(accountId) => handleRelogin(accountId)}\n onSetStrategy={(strategy) => void handleSetStrategy(strategy)}\n showQuota\n renderDetails={(entry) => (\n <>\n {entry.planName && <span>{t.plan}: {entry.planName}</span>}\n {entry.region && (\n <span>{t.region}: {entry.region === 'global' ? t.regionGlobal : t.regionMainland}</span>\n )}\n </>\n )}\n >\n {loginPending && (\n <div className=\"dsha-device-box\">\n <strong>{t.deviceCodeSection}</strong>\n <p className=\"dsha-muted\">{t.deviceCodeHint}</p>\n {flow?.userCode && (\n <div className=\"dsha-code-row\">\n <span className=\"dsha-code\">{flow.userCode}</span>\n <button className=\"dsha-btn\" onClick={() => void handleCopyCode()}>\n {copied ? t.copied : t.copyCode}\n </button>\n </div>\n )}\n {flow?.verificationUriComplete && (\n <a\n className=\"dsha-link\"\n href={flow.verificationUriComplete}\n target=\"_blank\"\n rel=\"noreferrer noopener\"\n >\n {flow.verificationUriComplete}\n </a>\n )}\n <div className=\"dsha-row\">\n <span className=\"dsha-label\">{t.codeExpires}</span>\n <span className=\"dsha-value\">{formatDate(flow?.expiresAt)}</span>\n </div>\n <div className=\"dsha-actions\">\n {flow?.verificationUriComplete && (\n <a\n className=\"dsha-btn\"\n href={flow.verificationUriComplete}\n target=\"_blank\"\n rel=\"noreferrer noopener\"\n >\n {t.openSignInPage}\n </a>\n )}\n <button className=\"dsha-btn\" disabled={busy !== null} onClick={() => void handleCancelLogin()}>\n {t.cancelSignIn}\n </button>\n </div>\n </div>\n )}\n </AccountPoolSection>\n\n <section className=\"dsha-group\">\n <div className=\"dsha-grouphead\">\n <h3>{t.connection}</h3>\n </div>\n <div className=\"dsha-row\">\n <span className=\"dsha-label\">{t.oauthHost}</span>\n <span className=\"dsha-value\">{status?.oauthHost || '—'}</span>\n </div>\n <div className=\"dsha-row\">\n <span className=\"dsha-label\">{t.codingEndpoint}</span>\n <span className=\"dsha-value\">{status?.codingBaseUrl || '—'}</span>\n </div>\n <p className=\"dsha-notice\">\n {status?.serving === false && status.conflict\n ? t.routeConflict.replace('{detail}', status.conflict)\n : t.routeOwned}\n </p>\n {connectionNotice && <p className=\"dsha-muted\">{connectionNotice}</p>}\n <div className=\"dsha-actions\">\n <button\n className=\"dsha-btn\"\n disabled={busy !== null || !status?.authenticated}\n onClick={() => void handleTestConnection()}\n >\n {busy === 'connection' ? t.testingConnection : t.testConnection}\n </button>\n </div>\n </section>\n\n <section className=\"dsha-group\">\n <div className=\"dsha-grouphead\">\n <h3>{t.cacheSection}</h3>\n </div>\n <p className=\"dsha-muted\">{t.cacheDesc}</p>\n {status?.cacheHint != null && (\n // Shown above the card rather than inside it: the card is about how\n // well the cache worked, and this says the next turn will not.\n <div className=\"dsha-warn\">{t.cacheExpired.replace('{tokens}', status.cacheHint.totalTokens.toLocaleString())}</div>\n )}\n {status?.cache == null ? (\n <div className=\"dsha-empty\">{t.cacheEmpty}</div>\n ) : (\n <div className=\"dsha-quota-card\">\n <div className=\"dsha-meter-wrap\">\n <div className=\"dsha-meter-label\">\n <span>{t.cacheHitRatio}</span>\n <strong>\n {status.cache.hitRatio === null ? '—' : `${(status.cache.hitRatio * 100).toFixed(1)}%`}\n </strong>\n </div>\n <div className={`dsha-meter ${(status.cache.hitRatio ?? 0) >= 0.9 ? 'dsha-meter-green' : 'dsha-meter-cyan'}`}>\n <span style={{ width: `${Math.round((status.cache.hitRatio ?? 0) * 100)}%` }} />\n </div>\n <div className=\"dsha-meter-meta\">\n <span>{t.cacheCached}: {status.cache.cachedTokens.toLocaleString()}</span>\n <span>{t.cacheFresh}: {status.cache.freshTokens.toLocaleString()}</span>\n <span>{t.cacheOutput}: {status.cache.outputTokens.toLocaleString()}</span>\n <span>{t.cacheRequests}: {status.cache.requests}</span>\n </div>\n </div>\n {status.cache.lastDrift !== undefined && (\n <div className=\"dsha-row\">\n <span className=\"dsha-label\">{t.cacheDrift}</span>\n <span className=\"dsha-value\">{driftLabel(status.cache.lastDrift, t)}</span>\n </div>\n )}\n <p className=\"dsha-muted\">{t.cacheHint}</p>\n </div>\n )}\n </section>\n\n <section className=\"dsha-group\">\n <div className=\"dsha-grouphead\">\n <h3>{t.modelsSection}</h3>\n <button className=\"dsha-btn\" disabled={busy !== null} onClick={() => void handleRefreshCatalog()}>\n {busy === 'catalog' ? t.refreshingCatalog : t.refreshCatalog}\n </button>\n </div>\n <p className=\"dsha-muted dsha-models-hint\">{t.modelsHint}</p>\n <ModelChecklist\n items={(status?.models ?? []).map((model: KimiCodeModelOption) => ({\n id: model.id,\n name: model.name,\n hint: [\n model.wire === 'anthropic' ? t.wireAnthropic : t.wireOpenai,\n ...(model.supportsVideo ? [t.capVideo] : []),\n ...(model.supportsDynamicTools ? [t.capDynamicTools] : []),\n ...(model.minimumPlan ? [t.capPlan.replace('{plan}', model.minimumPlan)] : []),\n ].join(' · '),\n enabled: model.enabled,\n }))}\n busy={busy !== null}\n onToggle={toggleModel}\n onToggleAll={setAllModels}\n labels={{ selectAll: t.selectAll, clearAll: t.unselectAll, list: t.modelsSection }}\n />\n {status !== null && status.models.length > 0 && <KimiModelCapabilities models={status.models} />}\n </section>\n\n <section className=\"dsha-group\">\n <div className=\"dsha-grouphead\">\n <h3>{t.enhanced}</h3>\n </div>\n <div className=\"dsha-pref-row\">\n <div>\n <strong>{t.defaultReasoningEffort}</strong>\n <p className=\"dsha-muted\">{t.defaultReasoningEffortHint}</p>\n </div>\n <select\n className=\"dsha-select\"\n aria-label={t.defaultReasoningEffort}\n value={status?.defaultReasoningEffort ?? ''}\n disabled={busy !== null}\n onChange={(event) => {\n const value = event.currentTarget.value\n void handleUpdateEffort(value === '' ? null : (value as KimiCodeReasoningEffort))\n }}\n >\n <option value=\"\">{t.defaultEffortAuto}</option>\n {KIMI_CODE_REASONING_EFFORTS.map((effort) => (\n <option key={effort} value={effort}>{EFFORT_LABEL[effort]}</option>\n ))}\n </select>\n </div>\n <div className=\"dsha-pref-row\">\n <div>\n <strong>{t.cacheTtl}</strong>\n <p className=\"dsha-muted\">{t.cacheTtlHint}</p>\n </div>\n <select\n className=\"dsha-select\"\n aria-label={t.cacheTtl}\n value={status?.cacheTtl ?? ''}\n disabled={busy !== null}\n onChange={(event) => {\n const value = event.currentTarget.value\n void handleUpdateCacheTtl(value === '' ? null : (value as KimiCodeCacheTtl))\n }}\n >\n <option value=\"\">{t.cacheTtlDefault}</option>\n <option value=\"5m\">{t.cacheTtl5m}</option>\n <option value=\"1h\">{t.cacheTtl1h}</option>\n </select>\n </div>\n </section>\n\n <section className=\"dsha-group\">\n <div className=\"dsha-grouphead\">\n <h3>{t.contextWindowSection}</h3>\n </div>\n <p className=\"dsha-muted\">{t.contextWindowHint}</p>\n <ContextWindowEditor\n rows={contextModels.map((model: KimiCodeModelOption) => ({\n id: model.id,\n name: model.name,\n draft: contextDrafts[model.id] ?? '',\n meta: model.defaultContextWindow < model.contextWindow\n ? formatCapacity(model.contextWindow)\n : undefined,\n inputLabel: `${model.name} context window`,\n hasOverride: status?.contextWindowOverrides[model.id] !== undefined,\n saving: savingModel === model.id,\n }))}\n labels={{\n tokens: t.tokens,\n save: t.save,\n saving: t.saving,\n reset: t.contextWindowReset,\n resetAll: t.contextWindowResetAll,\n empty: t.contextWindowNoneEnabled,\n }}\n busy={busy !== null}\n overrideCount={overrideCount}\n metaClassName=\"dsha-model-meta\"\n onDraftChange={(id, draft) => setContextDrafts((prev) => ({ ...prev, [id]: draft }))}\n onCommit={(id) => void handleSaveContextWindow(id)}\n onReset={(id) => void handleResetContextWindow(id)}\n onResetAll={() => void handleResetAllContextWindows()}\n />\n </section>\n\n <section className=\"dsha-group\">\n <div className=\"dsha-grouphead\">\n <h3>{t.quotaSection}</h3>\n <button\n className=\"dsha-btn\"\n disabled={busy !== null || !status?.authenticated}\n onClick={() => void handleRefreshQuota()}\n >\n {busy === 'quota' ? t.refreshingQuota : t.refreshQuota}\n </button>\n </div>\n <p className=\"dsha-muted\">{t.quotaDesc}</p>\n {/* The progress bars moved into each account card: quota follows the\n account, so a bar here could only ever describe whichever account\n happened to be active when the snapshot was read. What stays is what\n has no per-account bar to live in — the plan, the pay-as-you-go\n wallet, the errors and the freshness of this reading. */}\n <p className=\"dsha-muted\">{t.quotaFactsScope}</p>\n\n {status?.quotaError && <p className=\"dsha-notice\">{status.quotaError}</p>}\n\n {!status?.authenticated ? (\n <div className=\"dsha-empty\">{t.signedOut}</div>\n ) : quota === null || quota === undefined ? (\n <div className=\"dsha-empty\">{busy === 'quota' ? t.refreshingQuota : t.quotaEmpty}</div>\n ) : (\n <div className=\"dsha-quota-card\">\n <div className=\"dsha-quota-title\">\n <strong>{t.quotaPlan}</strong>\n <span>{quota.planName || t.planUnknown}</span>\n </div>\n\n {quota.extraUsage !== null && (\n <div className=\"dsha-meter-wrap\">\n <div className=\"dsha-meter-label\">\n <span>{t.quotaWallet}</span>\n <strong>{formatMoney(quota.extraUsage.balanceCents, quota.extraUsage.currency)}</strong>\n </div>\n <div className=\"dsha-meter-meta\">\n <span>{formatMoney(quota.extraUsage.totalCents, quota.extraUsage.currency)}</span>\n {quota.extraUsage.monthlyChargeLimitEnabled && quota.extraUsage.monthlyChargeLimitCents !== null && (\n <span>\n {t.quotaWalletLimit}: {formatMoney(quota.extraUsage.monthlyChargeLimitCents, quota.extraUsage.currency)}\n </span>\n )}\n </div>\n </div>\n )}\n\n {quota.windows.length === 0 && quota.extraUsage === null && (\n <div className=\"dsha-empty\">{t.quotaEmpty}</div>\n )}\n\n <div className=\"dsha-timestamp\">\n {t.updatedAt.replace('{time}', new Date(quota.fetchedAt).toLocaleString())}\n </div>\n </div>\n )}\n </section>\n\n {error && (\n <div className=\"dsha-error\">\n <div>{error}</div>\n </div>\n )}\n </div>\n )\n}\n","/**\n * Wire contracts between the WorkBuddy host routes and the browser settings\n * card. Everything here is public: no credential ever crosses this boundary.\n */\n\nimport type { AccountPoolStatusDto, PoolAccountSummaryDto } from './account-pool-contracts.ts'\n\n/**\n * Which deployment region an account belongs to.\n *\n * The two regions are separate backends serving overlapping-but-different model\n * catalogs, and a model asked of the wrong region answers 400 `code 11102`\n * (\"service info not found\") rather than failing over. The region is therefore\n * a property of the credential, not of the request.\n */\nexport type WorkBuddyRegion = 'cn' | 'intl'\n\n/**\n * Consumption multiplier of one model, per region.\n *\n * The subscription publishes a \\`credits\\` string per model in its own\n * \\`/v3/config\\` catalog — \\`x0.79 credits\\`, \\`x6.67\\` — which is the relative rate at\n * which that model consumes the package allowance. The official CodeBuddy\n * client renders it as \\`6.67x\\` beside the model in its picker; this route\n * carries the same fact to the settings card, so a model's cost is visible at\n * the moment it is chosen rather than only on the bill.\n *\n * Keyed by region because the two backends do not always agree: measured\n * 2026-10-09, \\`deepseek-v4.1-flash\\` is \\`0.11\\` on cn against \\`0.00\\` on intl. A\n * region the catalog did not name for this model is absent rather than guessed,\n * and a model whose publisher declares no usable rate (\\`default-model\\` ships an\n * empty string) carries no entry at all.\n *\n * Values are the bare numeric form (\\`'0.79'\\`), never the wire spelling: the\n * label and the \\`x\\` suffix belong to whichever surface renders it.\n */\nexport type WorkBuddyModelCredits = Partial<Record<WorkBuddyRegion, string>>\n\n/**\n * Parse one gateway \\`credits\\` string into the bare multiplier it names.\n *\n * Measured shapes: \\`x6.67\\` (intl), \\`x0.79 credits\\` (cn), and \\`''\\` for a model\n * whose publisher declares no rate. \\`x0.00\\` is deliberately kept — it is a real\n * declaration (\"this model does not consume allowance\"), not a missing value,\n * so it must not be confused with the empty string that means nothing is known.\n *\n * The return is \\`null\\` rather than \\`0\\` for anything unparseable, so a caller can\n * tell \"no rate published\" from \"a rate of zero\".\n */\nexport function parseWorkBuddyCreditMultiplier(raw: unknown): string | null {\n if (typeof raw !== 'string') return null\n const stripped = raw.replace(/\\s*credits\\s*$/i, '').trim().replace(/^[x×]/i, '').trim()\n if (stripped === '') return null\n const value = Number(stripped)\n if (!Number.isFinite(value) || value < 0) return null\n return stripped\n}\n\n/**\n * Reasoning levels this route can name.\n *\n * Deliberately the widest set any model declares, so a saved default is not\n * discarded merely because the model that suggested it is no longer selected.\n * The settings card renders the subset the account's models actually declare.\n */\nexport type WorkBuddyReasoningEffort = 'minimal' | 'low' | 'medium' | 'high' | 'xhigh' | 'max'\n\n/** Every level this route can name, in escalating order (the card's sort key). */\nexport const WORKBUDDY_REASONING_EFFORTS: readonly WorkBuddyReasoningEffort[] =\n ['minimal', 'low', 'medium', 'high', 'xhigh', 'max']\n\n/**\n * Ladder of a WorkBuddy model that leaves the level choice to the gateway.\n *\n * `/v3/config` publishes a model's ladder in two shapes: an explicit\n * `supportedEfforts` list, or a lone `{ effort }` field that names only the\n * DEFAULT. Conflating them was a real bug — the lone field first became a\n * one-entry ladder, which rejected an explicit `low`; widening it to every\n * level this route can name then advertised `minimal`/`xhigh` on a model that\n * has three. Measured against the live gateway, such a model accepts exactly\n * `low`/`high`/`max` — the same three `glm-5.3-flash` and\n * `kimi-k2.8-preview` declare explicitly — and every other value is routed\n * into the nearest of them rather than honoured as a level of its own.\n */\nexport const WORKBUDDY_STANDARD_EFFORTS: readonly WorkBuddyReasoningEffort[] =\n ['low', 'high', 'max']\n\n/**\n * Snap a level onto the nearest rung a model's ladder actually exposes.\n *\n * The gateway names a default from a wider vocabulary than the ladder it\n * publishes for the same model: an effort-only entry (minimax-m3, kimi-k3,\n * `glm-5.3` in the cn region) reports `effort: 'medium'` while exposing only\n * `low`/`high`/`max`. Letting that value through is not cosmetic — a default\n * outside the ladder is discarded by the level-resolution step, the request\n * then carries no `reasoning_effort`, and the model returns an EMPTY\n * `reasoning_content` (measured on minimax-m3: 0 characters across three\n * samples, versus 282-659 with the field). Ties resolve upward, which is the\n * mapping the sibling Kimi line documents for `medium`. A ladder that names\n * no level (a text-only model) yields nothing to converge to.\n */\nexport function convergeWorkBuddyEffort(\n effort: string,\n ladder: readonly string[],\n): WorkBuddyReasoningEffort | null {\n if (ladder.length === 0) return null\n const rank = (value: string): number => {\n const index = WORKBUDDY_REASONING_EFFORTS.indexOf(value.trim().toLowerCase() as WorkBuddyReasoningEffort)\n // An unrecognised level is placed at the middle rung rather than at an\n // extreme, so it can never silently pick the cheapest or the most costly.\n return index === -1 ? WORKBUDDY_REASONING_EFFORTS.indexOf('high') : index\n }\n const target = rank(effort)\n let best = ladder[0]!\n for (const candidate of ladder) {\n const distance = Math.abs(rank(candidate) - target)\n const bestDistance = Math.abs(rank(best) - target)\n if (distance < bestDistance || (distance === bestDistance && rank(candidate) > rank(best))) {\n best = candidate\n }\n }\n // The ladder is the model's own declaration, so a hit is always a nameable\n // level; the cast only records what the caller's data already guarantees.\n return best as WorkBuddyReasoningEffort\n}\n\n/** One model offered by the WorkBuddy subscription. */\nexport interface WorkBuddyModelOption {\n id: string\n name: string\n /** Enabled models are the ones DSH offers in the conversation model picker. */\n enabled: boolean\n /** Context window this route assumes when the caller saves no override. */\n defaultContextWindow: number\n /** Effective context window: the override when one is saved, else the default. */\n contextWindow: number\n /** Maximum output tokens this route requests when a caller omits one. */\n defaultMaxTokens: number\n /** Reasoning levels this route exposes; absent for non-reasoning models. */\n reasoningEfforts?: string[]\n /** Whether the model accepts image input on this route. */\n supportsImage: boolean\n /** Regions that serve this model; the account's own region must be listed. */\n regions: WorkBuddyRegion[]\n /**\n * Consumption multiplier per region, as the gateway declares it.\n *\n * Absent when nothing usable was published for this model — an unreachable\n * gateway served by the shipped fallback for a model it does not rate, or an\n * account whose region is not among the keys. The card must then show no\n * multiplier rather than a placeholder: a guessed rate on a spend figure is\n * worse than a missing one.\n */\n credits?: WorkBuddyModelCredits\n /** One-line description shown beside the model in the settings card. */\n description?: string\n}\n\n/**\n * Daily check-in preference for the CN-region billing activity.\n *\n * The activity is CN-only: the international deployment answers no check-in\n * surface, so the scheduler skips those accounts outright. There is no window\n * to configure: the first tick after the host starts is the daily run.\n */\nexport interface WorkBuddyCheckinSettings {\n /** Whether the in-process scheduler signs eligible accounts in. */\n enabled: boolean\n}\n\n/**\n * Aggregate check-in state the settings card renders.\n *\n * Deliberately account-less: the card shows one line (\"checked in x/y today\"),\n * not a per-account breakdown, so no account identity crosses here either.\n */\nexport interface WorkBuddyCheckinSummary {\n enabled: boolean\n /** CN-region accounts eligible for the check-in activity. */\n totalAccounts: number\n /** Accounts confirmed signed in today (already signed, or signed by a run). */\n doneToday: number\n /**\n * Accounts whose activity reported no entitlement today.\n *\n * Kept apart from {@link doneToday} because \"the activity is inactive\" is not\n * \"you are checked in\": counting them together let the card claim a sign-in\n * that never happened.\n */\n skippedToday: number\n /** Accounts that exhausted today's retry cap without signing in. */\n failedToday: number\n /** Unix milliseconds the scheduler last ran, automatic or manual. */\n lastRunAt: number | null\n}\n\n/** One credit allowance reported by the billing service. */\nexport interface WorkBuddyMeter {\n id: string\n label: string\n /** Used fraction in [0, 1] when the service reports a bounded allowance. */\n usedFraction: number | null\n /** Remaining fraction in [0, 1], when the service reports one. */\n remainingFraction: number | null\n used: string | null\n limit: string | null\n /** Unix milliseconds the meter resets, when reported. */\n resetsAt: number | null\n description: string | null\n}\n\n/** Account identity read from the local CodeBuddy credential file. */\nexport interface WorkBuddyAccount {\n /** Stable, non-secret selection key derived from region + account identity. */\n id: string\n uid: string | null\n nickname: string | null\n /** Tencent UIN, masked by the card rather than sent in full. */\n uin: string | null\n /** Account kind the client reports, e.g. `personal`. */\n accountType: string | null\n /** Enterprise/tenant id when the account is an enterprise one. */\n enterpriseId: string | null\n region: WorkBuddyRegion\n /** Backend base URL this account's region resolves to. */\n backend: string\n /** Auth domain recorded in the credential, e.g. `copilot.tencent.com`. */\n domain: string\n /** Unix milliseconds the access token expires. */\n expiresAt: number | null\n /** File the credential was read from; null for plugin-managed accounts. */\n sourceFile: string | null\n /** Desktop credentials are external; managed credentials belong to this plugin. */\n source: 'desktop' | 'managed'\n /** Managed credentials may be deleted; desktop credentials may only be hidden. */\n removable: boolean\n /** Hidden desktop accounts do not participate in automatic selection. */\n hidden: boolean\n}\n\n/** One WorkBuddy account as the shared pool card renders it. Never carries a token. */\nexport interface WorkBuddyAccountSummaryDto extends PoolAccountSummaryDto {\n region: WorkBuddyRegion\n /** Which store owns the credential; only managed accounts may be deleted. */\n source: 'desktop' | 'managed'\n /** Whether the card may offer Delete for this account. */\n removable: boolean\n nickname?: string\n /** Tencent UIN, masked by the card rather than shown in full. */\n uin?: string\n /** IDE file a desktop account was adopted from. */\n sourceFile?: string\n /** Auth domain recorded in the credential, e.g. `copilot.tencent.com`. */\n domain?: string\n /** Backend base URL the account's region resolves to. */\n backend?: string\n /** Account kind the client reports, e.g. `personal`. */\n accountType?: string\n /**\n * Whether the plugin currently routes to this account.\n *\n * Distinct from the pool's `activeAccountId`: a hidden account keeps its\n * place in the pool but is not offered for routing while hidden.\n */\n hidden?: boolean\n}\n\n/** One point-in-time quota snapshot for the signed-in WorkBuddy account. */\nexport interface WorkBuddyAccountQuota {\n account: WorkBuddyAccount\n /** Package name the billing service reports, e.g. `Free Plan Subscription`. */\n packageName: string | null\n /** Total credits the package grants, as reported. */\n totalCredits: number | null\n /** Credits remaining in the current cycle. */\n remainingCredits: number | null\n /** Credits consumed in the current cycle. */\n cycleUsedCredits: number | null\n /** Cycle allowance, when the service reports a per-cycle cap. */\n cycleCredits: number | null\n /** Start of the current billing cycle, as Unix milliseconds. */\n cycleStartsAt: number | null\n /** End of the current billing cycle, as Unix milliseconds. */\n cycleEndsAt: number | null\n meters: WorkBuddyMeter[]\n /** When this snapshot was read. */\n fetchedAt: number\n /** Billing routes that answered, for diagnostics in the settings card. */\n sources: string[]\n}\n\n/** Everything the settings card and the composer badge render. */\nexport interface WorkBuddyWebStatus extends Partial<AccountPoolStatusDto> {\n enabled?: boolean\n authenticated: boolean\n hasCredentials: boolean\n /** Where credentials are read from; the local CodeBuddy auth directory. */\n authDirectory: string\n /** Storage description for the plugin's own settings file. */\n storagePath: string\n account: WorkBuddyAccount | null\n quota: WorkBuddyAccountQuota | null\n lastFetchedAt: number | null\n /**\n * Whether a quota refresh is running behind this answer.\n *\n * The card renders the snapshot it already had instead of waiting on the\n * upstream request; when this is true the client asks again shortly so the\n * refreshed snapshot reaches the UI.\n */\n quotaRefreshing?: boolean\n models: WorkBuddyModelOption[]\n contextWindowOverrides: Record<string, number>\n defaultReasoningEffort: WorkBuddyReasoningEffort | null\n /** Account selected for model discovery and all requests; null means automatic. */\n selectedAccountId: string | null\n /** Encrypted storage used for accounts added from this plugin. */\n managedStoragePath: string\n /** Route the plugin currently serves; false when another plugin owns it. */\n serving: boolean\n /** Diagnostic when the route is owned by a different adapter family. */\n conflict: string | null\n /** Pool summaries the shared account card renders; empty without a pool. */\n accounts?: WorkBuddyAccountSummaryDto[]\n /** Aggregate daily check-in state; absent when the host predates check-in. */\n checkin?: WorkBuddyCheckinSummary | null\n}\n\n/** Patch accepted by the models/settings route. */\nexport interface WorkBuddySettingsUpdateDto {\n enabled?: boolean\n enabledModelIds?: string[]\n /** A number sets an override for that model; `null` restores the catalog default. */\n contextWindowOverrides?: Record<string, number | null>\n defaultReasoningEffort?: WorkBuddyReasoningEffort | null\n selectedAccountId?: string | null\n /** Partial check-in update; omitted fields keep their stored value. */\n checkin?: Partial<WorkBuddyCheckinSettings>\n}\n\n/** Result of a connection test against the upstream chat endpoint. */\nexport interface WorkBuddyConnectionDto {\n connected: boolean\n account: WorkBuddyAccount | null\n /** Round-trip time of the probe request. */\n latencyMs: number\n /** Model the probe asked for. */\n model: string\n checkedAt: number\n}\n","export const NS_WORKBUDDY = 'dsh-workbuddy'\n\nexport const zh = {\n title: 'WorkBuddy',\n pageDesc: '复用本机 CodeBuddy 桌面端登录态,管理 WorkBuddy(CodeBuddy 订阅)模型、上下文窗口与额度。',\n account: '账号',\n noAccounts: '暂无账号。点击右上角「添加账号」完成浏览器授权,或登录 CodeBuddy 桌面端后重新扫描;桌面账号只能从本插件隐藏,绝不删除 CodeBuddy 的原凭据。',\n signedOut: '未找到凭据',\n nickname: '昵称',\n uin: 'UIN',\n region: '区域',\n regionCn: '国区',\n regionIntl: '国际区',\n accountType: '账号类型',\n routeUnreachable: '无法读取 WorkBuddy 设置路由',\n routeUnreachableHint: '浏览器里加载的插件版本可能比 Host 进程里运行的新(客户端资源是现读磁盘的,Host 只在启动时加载)。请重启 DSH,让两端来自同一份构建。',\n rescan: '重新扫描',\n rescanning: '扫描中...',\n accounts: '账号管理',\n addCnAccount: '添加国区账号',\n addIntlAccount: '添加国际区账号',\n authorizing: '授权中…',\n loginWaiting: '请在新打开的浏览器页面完成登录与授权。',\n loginFailed: '账号授权失败',\n hiddenAccount: '已隐藏',\n hideAccount: '从插件隐藏',\n restoreAccount: '恢复显示',\n deleteAccount: '删除账号',\n deleteConfirm: '确定删除这个插件托管的账号吗?加密存储中的登录凭据会被移除。',\n connection: '连接',\n testConnection: '测试连接',\n testingConnection: '测试中...',\n latency: '延迟',\n routeOwned: '模型路由由本插件提供',\n routeConflict: '模型路由已被其他 Provider 占用:{detail}。请在 DSH 设置中移除重复的 Provider 配置后重试。',\n modelsSection: '模型',\n modelsHint: '勾选后模型才会出现在对话页的模型选择列表中;未勾选或关闭上方开关可在列表中隐藏该供应商。目录与上下文窗口来自订阅网关的模型目录,并按账号所在区域过滤——跨区调用会被上游拒绝。',\n refreshCatalog: '刷新模型目录',\n refreshingCatalog: '刷新中...',\n selectAll: '全选',\n unselectAll: '全不选',\n imageSupport: '图片',\n textOnly: '纯文本',\n creditMultiplier: '倍率',\n creditMultiplierRegion: '{value}({region})',\n creditMultiplierPair: '{first} / {second}',\n regionBadge: '区域',\n unavailableHere: '当前区域不可用',\n enhanced: '增强功能',\n defaultReasoningEffort: '默认思考深度',\n defaultReasoningEffortHint: '控制支持推理的模型在未单独指定时的思考强度。',\n defaultEffortAuto: '使用模型默认值',\n effortUnsupported: '当前模型不支持',\n noReasoningModels: '当前账号的模型都没有声明可用的思考档位,因此没有可选的默认档位。',\n defaultEffortKept: '已保存的档位不被当前任何模型支持,已保留但不会生效。',\n contextWindowSection: '模型上下文窗口',\n contextWindowHint: '默认值来自订阅网关的模型目录(每个模型的真实上下文上限);可覆盖为自定义容量,该值用于 DSH 的压缩与溢出判断,可输入 1M、512K、200K 等容量。',\n contextWindowReset: '恢复默认',\n contextWindowResetAll: '全部恢复默认',\n contextWindowResetAllConfirm: '确定把已改过的模型上下文窗口全部恢复为默认值吗?',\n contextWindowNoneEnabled: '还没有勾选任何模型。在上方勾选后,这里会出现该模型的上下文窗口设置。',\n save: '保存',\n saved: '已保存',\n saving: '保存中...',\n quotaSection: '用量与配额',\n quotaDesc: '数据来自订阅的计费接口,页面可见时最多每 60 秒刷新一次。',\n refreshQuota: '刷新用量',\n refreshingQuota: '刷新中...',\n quotaEmpty: '暂无配额数据,点击「刷新用量」重试。',\n quotaPackage: '套餐',\n quotaRemaining: '剩余额度',\n quotaCycle: '本周期已用',\n quotaReset: '重置时间',\n updatedAt: '更新时间:{time}',\n loading: '加载中...',\n credits: 'credits',\n composerLabel: '额度',\n dailyCheckin: '每日签到',\n checkinHint: '仅国区账号参与;DSH 启动时自动签到一次,运行期间每 10 分钟补检,进程关闭的当天不会签到。',\n checkinAuto: '自动签到',\n checkinToday: '今日已签 {done}/{total}',\n checkinSkipped: '{count} 个无签到活动',\n checkinFailed: '{count} 个失败',\n checkinLastRun: '上次运行:{time}',\n checkinNever: '尚未运行',\n checkinNow: '立即签到',\n checkinRunning: '签到中…',\n} as const\n\nexport const en = {\n title: 'WorkBuddy',\n pageDesc: 'Reuse the local CodeBuddy desktop sign-in to manage WorkBuddy (CodeBuddy subscription) models, context windows, and quota.',\n account: 'Account',\n noAccounts: 'No accounts yet. Use “Add account” above to authorize, or sign in with the CodeBuddy desktop client and rescan; desktop accounts can only be hidden here, never removed from CodeBuddy.',\n signedOut: 'No credential found',\n nickname: 'Nickname',\n uin: 'UIN',\n region: 'Region',\n regionCn: 'China',\n regionIntl: 'International',\n accountType: 'Account type',\n routeUnreachable: 'The WorkBuddy settings route could not be read',\n routeUnreachableHint: 'The plugin loaded in the browser may be newer than the one running in the Host: client assets are read from disk on demand, while the Host loads them only at startup. Restart DSH so both halves come from the same build.',\n rescan: 'Rescan',\n rescanning: 'Scanning...',\n accounts: 'Account Management',\n addCnAccount: 'Add China account',\n addIntlAccount: 'Add international account',\n authorizing: 'Authorizing…',\n loginWaiting: 'Complete sign-in and authorization in the newly opened browser page.',\n loginFailed: 'Account authorization failed',\n hiddenAccount: 'Hidden',\n hideAccount: 'Hide from plugin',\n restoreAccount: 'Restore',\n deleteAccount: 'Delete account',\n deleteConfirm: 'Delete this plugin-managed account? Its encrypted credential will be removed.',\n connection: 'Connection',\n testConnection: 'Test connection',\n testingConnection: 'Testing...',\n latency: 'Latency',\n routeOwned: 'This plugin serves the model route',\n routeConflict: 'Another provider already owns the model route: {detail}. Remove the duplicate provider configuration in DSH settings and reload.',\n modelsSection: 'Models',\n modelsHint: 'Checked models appear in the DSH conversation model list. The catalog and its context windows come from the subscription gateway and are filtered by the account’s region — the upstream rejects a model asked of the wrong region.',\n refreshCatalog: 'Refresh catalog',\n refreshingCatalog: 'Refreshing...',\n selectAll: 'Select all',\n unselectAll: 'Deselect all',\n imageSupport: 'Images',\n textOnly: 'Text only',\n creditMultiplier: 'Multiplier',\n creditMultiplierRegion: '{value} ({region})',\n creditMultiplierPair: '{first} / {second}',\n regionBadge: 'Regions',\n unavailableHere: 'Unavailable in this region',\n enhanced: 'Enhanced features',\n defaultReasoningEffort: 'Default reasoning effort',\n defaultReasoningEffortHint: 'Reasoning effort for models that support it when the conversation does not specify one.',\n defaultEffortAuto: 'Use the model default',\n effortUnsupported: 'unsupported by the current models',\n noReasoningModels: 'None of this account\\u2019s models declare a reasoning level, so there is no default to choose.',\n defaultEffortKept: 'The saved level is not supported by any current model; it is kept but has no effect.',\n contextWindowSection: 'Model context window',\n contextWindowHint: 'Defaults come from the subscription gateway’s own catalog (each model’s real context cap); override one with the capacity DSH should use for compaction and overflow decisions (e.g., 1M, 512K, 200K).',\n contextWindowReset: 'Restore default',\n contextWindowResetAll: 'Restore all defaults',\n contextWindowResetAllConfirm: 'Restore every changed model context window to its default?',\n contextWindowNoneEnabled: 'No model is checked yet. Check one above and its context window setting appears here.',\n save: 'Save',\n saved: 'Saved',\n saving: 'Saving...',\n quotaSection: 'Usage & quota',\n quotaDesc: 'Read from the subscription billing endpoint; refreshes at most once every 60 seconds while visible.',\n refreshQuota: 'Refresh quota',\n refreshingQuota: 'Refreshing...',\n quotaEmpty: 'No quota data yet — use “Refresh quota” to retry.',\n quotaPackage: 'Package',\n quotaRemaining: 'Remaining credits',\n quotaCycle: 'Used this cycle',\n quotaReset: 'Resets',\n updatedAt: 'Updated at: {time}',\n loading: 'Loading...',\n credits: 'credits',\n composerLabel: 'Quota',\n dailyCheckin: 'Daily check-in',\n checkinHint: 'CN-region accounts only. The host signs in once at startup and re-checks every 10 minutes while running; a day the process never runs is not signed.',\n checkinAuto: 'Auto check-in',\n checkinToday: 'Checked in today {done}/{total}',\n checkinSkipped: '{count} with no activity',\n checkinFailed: '{count} failed',\n checkinLastRun: 'Last run: {time}',\n checkinNever: 'Never run',\n checkinNow: 'Check in now',\n checkinRunning: 'Checking in…',\n} as const\n\nexport const dictionaries = {\n zh,\n 'zh-CN': zh,\n en,\n 'en-US': en,\n}\n\nexport type WorkBuddyLocaleKey = keyof typeof zh\n","/**\n * The WorkBuddy card's state, effects and actions.\n *\n * Split out of 'WorkBuddySection.tsx' so that file is markup and this one is\n * behaviour: what the card tracks, what it derives from a status answer, and\n * every request a control can make. The view reads one named shape — see\n * `WorkBuddySectionView` — so the contract between the two is visible here\n * rather than inferred from the JSX.\n */\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react'\nimport type { AccountRotationStrategy } from '../../shared/account-pool-contracts.ts'\nimport type {\n WorkBuddyAccount,\n WorkBuddyAccountQuota,\n WorkBuddyAccountSummaryDto,\n WorkBuddyCheckinSettings,\n WorkBuddyModelOption,\n WorkBuddyReasoningEffort,\n WorkBuddyWebStatus,\n} from '../../shared/workbuddy-contracts.ts'\nimport { WORKBUDDY_REASONING_EFFORTS } from '../../shared/workbuddy-contracts.ts'\nimport { accountPoolZh, type AccountPoolLabels } from '../common/account-pool-labels.ts'\nimport { contextDraftsFor } from '../common/ContextWindowEditor.tsx'\nimport { formatCapacity, parsePositiveCapacity } from '../common/format.ts'\nimport { createLineApi } from '../common/line-api.ts'\nimport { createQuotaFollowUp, type QuotaFollowUp } from '../common/quota-follow-up.ts'\nimport { zh } from './locales.ts'\n\nconst API = '/workbuddy/api'\n\n/** The seats the settings hub hands the card; both optional, so a bare render works. */\nexport interface WorkBuddySectionProps {\n onModelChange?: () => void\n loadModelDirectory?: () => void\n}\n\n/**\n * The shared card's label set.\n *\n * Only the three labels WorkBuddy genuinely words differently are taken from\n * this tab's dictionary; everything else is the shared set, so the five\n * provider tabs cannot drift apart in wording.\n */\nfunction accountPoolLabels(t: typeof zh): AccountPoolLabels {\n return {\n ...accountPoolZh,\n noAccounts: t.noAccounts,\n // A WorkBuddy identity reads as a nickname, not an e-mail address.\n email: t.nickname,\n }\n}\n\ninterface LoginPollStatus {\n status: 'idle' | 'pending' | 'complete' | 'error'\n region?: 'cn' | 'intl'\n authUrl?: string\n progress?: string\n accountId?: string\n error?: string\n}\n\ninterface ConnectionPayload {\n connected: boolean\n account: WorkBuddyAccount | null\n latencyMs: number\n model: string\n checkedAt: number\n}\n\n/**\n * Call one settings route through the shared reader.\n *\n * This line is where the shared reader's tolerance came from: reading the body\n * as text first is what lets a route that is not mounted (an empty body, which\n * is exactly what a stale host half produces) be reported as such instead of as\n * a bare \"Unexpected end of JSON input\".\n */\nconst api = createLineApi(API, 'WorkBuddy')\n\n/** One selectable default reasoning level, with the models that declare it. */\nexport interface ReasoningEffortChoice {\n value: WorkBuddyReasoningEffort\n /** Model names that accept this level, in catalog order. */\n models: string[]\n}\n\n/**\n * Reasoning levels the default-effort control may offer.\n *\n * The levels come from what this account's models actually declare — never from\n * the shipped enum alone. The setting is one global default applied to whichever\n * model a conversation uses, so the list is their union; each entry carries the\n * models behind it, and a level only some models accept is labelled as such.\n * Order follows {@link WORKBUDDY_REASONING_EFFORTS}, which is the escalating\n * order the upstream ladder uses.\n */\nexport function reasoningEffortChoices(models: WorkBuddyModelOption[]): ReasoningEffortChoice[] {\n const declared = new Map<string, string[]>()\n for (const model of models) {\n for (const effort of model.reasoningEfforts ?? []) {\n const names = declared.get(effort)\n if (names === undefined) declared.set(effort, [model.name])\n else names.push(model.name)\n }\n }\n return WORKBUDDY_REASONING_EFFORTS\n .filter((effort) => declared.has(effort))\n .map((effort) => ({ value: effort, models: declared.get(effort)! }))\n}\n\n/**\n * Whether a saved default is unusable for every model on this account.\n *\n * The adapter drops a level the chosen model does not accept instead of sending\n * it, so a value that no model declares silently does nothing. Reporting it is\n * what keeps that from looking like the setting was applied.\n */\nexport function unsupportedReasoningEffort(\n configured: WorkBuddyReasoningEffort | null | undefined,\n models: WorkBuddyModelOption[],\n): WorkBuddyReasoningEffort | null {\n if (configured === null || configured === undefined) return null\n const supported = models.some((model) => (model.reasoningEfforts ?? []).includes(configured))\n return supported ? null : configured\n}\n\n/** Defend against a response that omits the arrays the card renders. */\nfunction normalizeStatus(data: WorkBuddyWebStatus): WorkBuddyWebStatus {\n return {\n ...data,\n models: Array.isArray(data?.models) ? data.models : [],\n contextWindowOverrides: data?.contextWindowOverrides ?? {},\n accounts: Array.isArray(data?.accounts) ? data.accounts : [],\n }\n}\n\n/**\n * Everything the card's view consumes, grouped by kind.\n *\n * Returned as one named shape instead of one status blob: a reader can see at a\n * glance what the hook tracks, what it computes from a status answer, and what\n * the view is allowed to ask it to do.\n */\nexport interface WorkBuddySectionView {\n /** Values that change as the card runs. */\n state: {\n /** Last status answer; null until the first read lands. */\n status: WorkBuddyWebStatus | null\n /** True until the first status read settles, whatever its outcome. */\n loading: boolean\n /** Id of the action in flight, or null; every disabled control reads it. */\n busy: string | null\n /** The failure the card's error strip shows. */\n error: string | null\n /** Result of the last explicit connection test. */\n connection: ConnectionPayload | null\n /** Line the host reports while a regional sign-in is being polled. */\n loginProgress: string | null\n /** One free-text capacity draft per model, keyed by model id. */\n contextDrafts: Record<string, string>\n /** Model id whose context-window save or restore is in flight. */\n savingModel: string | null\n }\n /** Facts read straight off the current status answer. */\n derived: {\n /** Every account row the shared pool card lists. */\n poolAccounts: WorkBuddyAccountSummaryDto[]\n /** Levels this account's models declare, each with the models behind it. */\n effortChoices: ReasoningEffortChoice[]\n /** Every catalog model, enabled or not; the effort labels count them. */\n allModels: WorkBuddyModelOption[]\n /**\n * A saved default no current model declares, when there is one.\n *\n * The adapter drops a level the chosen model does not accept, so reporting\n * this is what keeps an inert setting from looking applied.\n */\n strayEffort: WorkBuddyReasoningEffort | null\n /** Models the context-window editor offers: the enabled ones only. */\n contextModels: WorkBuddyModelOption[]\n /** How many stored overrides exist, whether or not a row still shows them. */\n overrideCount: number\n /** The displayed account's quota snapshot, when the host has one. */\n quota: WorkBuddyAccountQuota | null | undefined\n /** Whether a credential is signed in; every authenticated control reads it. */\n authenticated: boolean\n /**\n * A failed status read with no answer to fall back on.\n *\n * A failed read leaves `status` null, which must NOT be rendered as \"no\n * credential found\": that claims a credential problem when the real cause is\n * an unreachable route.\n */\n unreachable: boolean\n /**\n * The line's dictionary, handed to the shared pool card as one object.\n *\n * The hook already owns it for its own sentences, so the view takes the same\n * object from here rather than reaching for a second import.\n */\n poolLabels: AccountPoolLabels\n }\n /** Everything the view can trigger. */\n actions: {\n /** Start a regional sign-in; its flow is polled until it settles. */\n login(region: 'cn' | 'intl'): Promise<void>\n /** Re-read the credentials the host can find on this machine. */\n rescan(): Promise<void>\n /**\n * One account action, whether it is a pool action (`set-primary`, `hide`,\n * `restore`, `relogin`, `clear-cooldown`) or a credential action (`delete`).\n * The host route dispatches on `action`.\n */\n accountAction(action: string, accountId: string): Promise<void>\n /** Delete one plugin-owned credential, after the user confirms. */\n deleteAccount(accountId: string): Promise<void>\n setStrategy(strategy: AccountRotationStrategy): Promise<void>\n testConnection(): Promise<void>\n refreshQuota(): Promise<void>\n /** Run the daily check-in for every eligible account, now. */\n checkinNow(): Promise<void>\n /** Patch the check-in preference; omitted fields keep their stored value. */\n updateCheckin(checkin: Partial<WorkBuddyCheckinSettings>): Promise<void>\n toggleModel(modelId: string, enabled: boolean): Promise<void>\n setAllModels(enabled: boolean): Promise<void>\n updateEffort(effort: WorkBuddyReasoningEffort | null): Promise<void>\n refreshCatalog(): Promise<void>\n saveContextWindow(modelId: string): Promise<void>\n resetContextWindow(modelId: string): Promise<void>\n resetAllContextWindows(): Promise<void>\n /** Edit one capacity draft mid-typing; the editor never parses it. */\n updateContextDraft(modelId: string, draft: string): void\n }\n}\n\nexport function useWorkBuddySection({ onModelChange, loadModelDirectory }: WorkBuddySectionProps): WorkBuddySectionView {\n const [status, setStatus] = useState<WorkBuddyWebStatus | null>(null)\n const [loading, setLoading] = useState(true)\n const [busy, setBusy] = useState<string | null>(null)\n const [error, setError] = useState<string | null>(null)\n // Whether the last `/status` call failed. A failed status read leaves\n // `status` null, which must NOT be rendered as \"no credential found\": that\n // claims a credential problem when the real cause is an unreachable route.\n const [statusFailed, setStatusFailed] = useState(false)\n const [connection, setConnection] = useState<ConnectionPayload | null>(null)\n const [loginProgress, setLoginProgress] = useState<string | null>(null)\n const loginIntervalRef = useRef<number | null>(null)\n const loginTimeoutRef = useRef<number | null>(null)\n /** Follow-up poll owed while the host refreshes the quota behind an answer. */\n const quotaFollowUp = useRef<QuotaFollowUp | null>(null)\n const [contextDrafts, setContextDrafts] = useState<Record<string, string>>({})\n const [savingModel, setSavingModel] = useState<string | null>(null)\n\n const t = zh\n\n const notifyChange = useCallback(() => {\n onModelChange?.()\n loadModelDirectory?.()\n }, [onModelChange, loadModelDirectory])\n\n // The level list follows the models this account actually declares, so the\n // control cannot offer a level none of them accepts.\n const effortChoices = useMemo(\n () => reasoningEffortChoices(status?.models ?? []),\n [status?.models],\n )\n const allModels = status?.models ?? []\n // The pool summaries the shared card renders; the legacy single-account view\n // below stays for a caller whose host has no pool installed.\n const poolAccounts = useMemo<WorkBuddyAccountSummaryDto[]>(\n () => (Array.isArray(status?.accounts) ? status.accounts : []),\n [status?.accounts],\n )\n const strayEffort = unsupportedReasoningEffort(status?.defaultReasoningEffort, allModels)\n\n const loadStatus = useCallback(async (quiet = false) => {\n if (!quiet) setError(null)\n try {\n const data = await api.request<WorkBuddyWebStatus>('/status')\n // A response without the expected arrays must still render, so they are\n // normalized rather than trusted.\n const normalized = normalizeStatus(data)\n setStatus(normalized)\n setStatusFailed(false)\n setContextDrafts(contextDraftsFor(normalized))\n // An answer that refreshed the quota behind itself is followed up shortly,\n // so the fresh numbers land without waiting for the next poll.\n quotaFollowUp.current ??= createQuotaFollowUp()\n quotaFollowUp.current.observe(data.quotaRefreshing === true, () => { void loadStatus(true) })\n } catch (err) {\n setStatusFailed(true)\n if (!quiet) setError(err instanceof Error ? err.message : String(err))\n } finally {\n setLoading(false)\n }\n }, [])\n\n useEffect(() => {\n void loadStatus()\n const refreshWhenVisible = () => {\n if (document.visibilityState === 'visible') void loadStatus(true)\n }\n document.addEventListener('visibilitychange', refreshWhenVisible)\n return () => {\n document.removeEventListener('visibilitychange', refreshWhenVisible)\n quotaFollowUp.current?.cancel()\n if (loginIntervalRef.current !== null) window.clearInterval(loginIntervalRef.current)\n if (loginTimeoutRef.current !== null) window.clearTimeout(loginTimeoutRef.current)\n }\n }, [loadStatus])\n\n const rescan = async () => {\n try {\n setBusy('rescan')\n setError(null)\n const updated = await api.request<WorkBuddyWebStatus>('/rescan', { method: 'POST' })\n setStatus(normalizeStatus(updated))\n notifyChange()\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n } finally {\n setBusy(null)\n }\n }\n\n const login = async (region: 'cn' | 'intl') => {\n try {\n setBusy(`login:${region}`)\n setError(null)\n setLoginProgress(t.loginWaiting)\n const flow = await api.request<LoginPollStatus>('/accounts/login', {\n method: 'POST',\n body: JSON.stringify({ region }),\n })\n if (flow.authUrl) window.open(flow.authUrl, '_blank', 'noopener,noreferrer')\n if (loginIntervalRef.current !== null) window.clearInterval(loginIntervalRef.current)\n if (loginTimeoutRef.current !== null) window.clearTimeout(loginTimeoutRef.current)\n const timer = window.setInterval(() => {\n void (async () => {\n try {\n const poll = await api.request<LoginPollStatus>('/accounts/login/status')\n if (poll.progress) setLoginProgress(poll.progress)\n if (poll.status === 'complete') {\n window.clearInterval(timer)\n loginIntervalRef.current = null\n if (loginTimeoutRef.current !== null) window.clearTimeout(loginTimeoutRef.current)\n loginTimeoutRef.current = null\n setBusy(null)\n setLoginProgress(null)\n if (poll.accountId) {\n await api.request<WorkBuddyWebStatus>('/settings', {\n method: 'POST',\n body: JSON.stringify({ selectedAccountId: poll.accountId }),\n })\n }\n await loadStatus()\n notifyChange()\n } else if (poll.status === 'error') {\n window.clearInterval(timer)\n loginIntervalRef.current = null\n if (loginTimeoutRef.current !== null) window.clearTimeout(loginTimeoutRef.current)\n loginTimeoutRef.current = null\n setBusy(null)\n setLoginProgress(null)\n setError(poll.error || t.loginFailed)\n }\n } catch {\n // Transient polling failure; the next interval retries.\n }\n })()\n }, 1500)\n loginIntervalRef.current = timer\n loginTimeoutRef.current = window.setTimeout(() => {\n window.clearInterval(timer)\n loginIntervalRef.current = null\n loginTimeoutRef.current = null\n setBusy(null)\n setLoginProgress(null)\n }, 5 * 60 * 1000)\n } catch (err) {\n setBusy(null)\n setLoginProgress(null)\n setError(err instanceof Error ? err.message : String(err))\n }\n }\n\n /**\n * One account action, whether it is a pool action (`set-primary`, `hide`) or a\n * credential action (`delete`). The host route dispatches on `action`.\n */\n const accountAction = async (action: string, accountId: string) => {\n try {\n setBusy(`${action}:${accountId}`)\n setError(null)\n const updated = await api.request<WorkBuddyWebStatus>('/accounts/action', {\n method: 'POST',\n body: JSON.stringify({ action, accountId }),\n })\n setStatus(normalizeStatus(updated))\n notifyChange()\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n } finally {\n setBusy(null)\n }\n }\n\n const deleteAccount = async (accountId: string) => {\n if (!window.confirm(t.deleteConfirm)) return\n await accountAction('delete', accountId)\n }\n\n const setStrategy = async (strategy: AccountRotationStrategy) => {\n try {\n setBusy('strategy')\n setError(null)\n const updated = await api.request<WorkBuddyWebStatus>('/accounts/strategy', {\n method: 'POST',\n body: JSON.stringify({ strategy }),\n })\n setStatus(normalizeStatus(updated))\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n } finally {\n setBusy(null)\n }\n }\n\n const testConnection = async () => {\n try {\n setBusy('connection')\n setError(null)\n setConnection(await api.request<ConnectionPayload>('/connection/test', { method: 'POST' }))\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n } finally {\n setBusy(null)\n }\n }\n\n const refreshQuota = async () => {\n try {\n setBusy('quota')\n setError(null)\n const updated = await api.request<WorkBuddyWebStatus>('/quota', { method: 'POST' })\n setStatus(updated)\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n } finally {\n setBusy(null)\n }\n }\n\n const checkinNow = async () => {\n try {\n setBusy('checkin')\n setError(null)\n const updated = await api.request<WorkBuddyWebStatus>('/checkin/now', { method: 'POST' })\n setStatus(normalizeStatus(updated))\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n } finally {\n setBusy(null)\n }\n }\n\n const updateCheckin = async (checkin: Partial<WorkBuddyCheckinSettings>) => {\n try {\n setBusy('checkin')\n setError(null)\n const updated = await api.request<WorkBuddyWebStatus>('/settings', {\n method: 'POST',\n body: JSON.stringify({ checkin }),\n })\n setStatus(normalizeStatus(updated))\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n } finally {\n setBusy(null)\n }\n }\n\n const toggleModel = async (modelId: string, enabled: boolean) => {\n if (status === null) return\n const current = status.models.filter((model) => model.enabled).map((model) => model.id)\n const next = enabled\n ? [...new Set([...current, modelId])]\n : current.filter((id) => id !== modelId)\n try {\n setBusy(`model:${modelId}`)\n setError(null)\n const updated = await api.request<WorkBuddyWebStatus>('/settings', {\n method: 'POST',\n body: JSON.stringify({ enabledModelIds: next }),\n })\n const normalized = normalizeStatus(updated)\n setStatus(normalized)\n // A model that was just checked has no draft yet; the context window\n // section only renders enabled models.\n setContextDrafts(contextDraftsFor(normalized))\n notifyChange()\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n } finally {\n setBusy(null)\n }\n }\n\n const setAllModels = async (enabled: boolean) => {\n if (status === null) return\n try {\n setBusy('models-all')\n setError(null)\n const updated = await api.request<WorkBuddyWebStatus>('/settings', {\n method: 'POST',\n body: JSON.stringify({ enabledModelIds: enabled ? status.models.map((model) => model.id) : [] }),\n })\n const normalized = normalizeStatus(updated)\n setStatus(normalized)\n setContextDrafts(contextDraftsFor(normalized))\n notifyChange()\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n } finally {\n setBusy(null)\n }\n }\n\n const updateEffort = async (effort: WorkBuddyReasoningEffort | null) => {\n try {\n setBusy('effort')\n setError(null)\n const updated = await api.request<WorkBuddyWebStatus>('/settings', {\n method: 'POST',\n body: JSON.stringify({ defaultReasoningEffort: effort }),\n })\n setStatus(updated)\n notifyChange()\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n } finally {\n setBusy(null)\n }\n }\n\n const refreshCatalog = async () => {\n try {\n setBusy('catalog')\n setError(null)\n const updated = await api.request<WorkBuddyWebStatus>('/catalog/refresh', { method: 'POST' })\n const normalized = normalizeStatus(updated)\n setStatus(normalized)\n setContextDrafts(contextDraftsFor(normalized))\n notifyChange()\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n } finally {\n setBusy(null)\n }\n }\n\n const saveContextWindow = async (modelId: string) => {\n const raw = contextDrafts[modelId] || ''\n const parsed = parsePositiveCapacity(raw)\n if (parsed === null) {\n setError(`Invalid context capacity: ${raw}`)\n return\n }\n try {\n setSavingModel(modelId)\n setError(null)\n const updated = await api.request<WorkBuddyWebStatus>('/settings', {\n method: 'POST',\n body: JSON.stringify({ contextWindowOverrides: { [modelId]: parsed } }),\n })\n setStatus(updated)\n setContextDrafts((prev) => ({ ...prev, [modelId]: formatCapacity(parsed) }))\n notifyChange()\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n } finally {\n setSavingModel(null)\n }\n }\n\n /** Clear one override; the row falls back to the catalog length. */\n const resetContextWindow = async (modelId: string) => {\n try {\n setSavingModel(modelId)\n setError(null)\n const updated = normalizeStatus(await api.request<WorkBuddyWebStatus>('/settings', {\n method: 'POST',\n body: JSON.stringify({ contextWindowOverrides: { [modelId]: null } }),\n }))\n setStatus(updated)\n setContextDrafts((prev) => {\n const model = updated.models.find((candidate) => candidate.id === modelId)\n return model === undefined ? prev : { ...prev, [modelId]: formatCapacity(model.defaultContextWindow) }\n })\n notifyChange()\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n } finally {\n setSavingModel(null)\n }\n }\n\n /** Clear every stored override, including models the picker no longer shows. */\n const resetAllContextWindows = async () => {\n const models = Object.keys(status?.contextWindowOverrides ?? {})\n if (models.length === 0) return\n if (!window.confirm(t.contextWindowResetAllConfirm)) return\n try {\n setBusy('context')\n setError(null)\n const updated = normalizeStatus(await api.request<WorkBuddyWebStatus>('/settings', {\n method: 'POST',\n body: JSON.stringify({ contextWindowOverrides: Object.fromEntries(models.map((model) => [model, null])) }),\n }))\n setStatus(updated)\n setContextDrafts(contextDraftsFor(updated))\n notifyChange()\n } catch (err) {\n setError(err instanceof Error ? err.message : String(err))\n } finally {\n setBusy(null)\n }\n }\n\n const updateContextDraft = (modelId: string, draft: string): void => {\n setContextDrafts((prev) => ({ ...prev, [modelId]: draft }))\n }\n\n // Only checked models get a context row; the batch restore still covers every\n // stored override, including one left behind by a model the user unchecked.\n const contextModels = status?.models.filter((model) => model.enabled) ?? []\n const overrideCount = Object.keys(status?.contextWindowOverrides ?? {}).length\n const quota = status?.quota\n const authenticated = status?.authenticated === true\n // A failed status read is not \"no credential\": showing the credential hint\n // here would send the user chasing a problem that does not exist.\n const unreachable = statusFailed && status === null\n\n return {\n state: {\n status,\n loading,\n busy,\n error,\n connection,\n loginProgress,\n contextDrafts,\n savingModel,\n },\n derived: {\n poolAccounts,\n effortChoices,\n allModels,\n strayEffort,\n contextModels,\n overrideCount,\n quota,\n authenticated,\n unreachable,\n poolLabels: accountPoolLabels(t),\n },\n actions: {\n login,\n rescan,\n accountAction,\n deleteAccount,\n setStrategy,\n testConnection,\n refreshQuota,\n checkinNow,\n updateCheckin,\n toggleModel,\n setAllModels,\n updateEffort,\n refreshCatalog,\n saveContextWindow,\n resetContextWindow,\n resetAllContextWindows,\n updateContextDraft,\n },\n }\n}\n","/**\n * The WorkBuddy subscription settings card.\n *\n * Markup only: every piece of state, every effect and every request this card\n * makes lives in 'useWorkBuddySection.ts', which returns one named shape the JSX\n * below reads. The two files are the split of a single 885-line component — the\n * behaviour is unchanged, and this one should stay render-shaped.\n */\nimport React from 'react'\nimport type {\n WorkBuddyAccountSummaryDto,\n WorkBuddyModelCredits,\n WorkBuddyModelOption,\n WorkBuddyReasoningEffort,\n WorkBuddyRegion,\n} from '../../shared/workbuddy-contracts.ts'\nimport { AccountPoolSection } from '../common/AccountPoolSection.tsx'\nimport { ContextWindowEditor } from '../common/ContextWindowEditor.tsx'\nimport { ModelChecklist } from '../common/ModelChecklist.tsx'\nimport { formatCapacity, formatDate, formatReset } from '../common/format.ts'\nimport { useWorkBuddySection, type WorkBuddySectionProps } from './useWorkBuddySection.ts'\nimport { zh } from './locales.ts'\n\n/**\n * Display label per reasoning level. The locale dictionary only accepts flat\n * string values, so this nested table lives with the control that renders it.\n */\nconst EFFORT_LABELS: Record<WorkBuddyReasoningEffort, string> = {\n minimal: 'Minimal',\n low: 'Low',\n medium: 'Medium',\n high: 'High',\n xhigh: 'X-High',\n max: 'Max',\n}\n\n/**\n * The consumption rate of one model, as the settings row states it.\n *\n * The gateway publishes one rate per region and the official CodeBuddy picker\n * spells it beside a model as `6.67x`; the row uses the same shape behind the\n * section's own label. Which rates reach the row depends on what the card knows\n * about the account, and the two cases are deliberately different:\n *\n * - A KNOWN region shows that region's rate and nothing else. Borrowing the\n * sibling region's number would state a price this account never pays —\n * measured 2026-10-09, `deepseek-v4.1-flash` is `0.11` on cn against `0.00`\n * on intl, and the backends reject a model asked of the wrong region anyway.\n * - An UNKNOWN region (no account read back yet) shows both rates when the\n * backends disagree, so the row is honest about the range instead of picking\n * one of them. When they agree there is nothing to disambiguate.\n *\n * The two-region form is assembled entirely from the caller's labels: the\n * qualifier comes from `labels.region(value, key)` and the join from\n * `labels.pair(first, second)`, so the dictionary owns the region nouns, the\n * bracket glyphs AND the separator. Nothing about the two-region string is\n * spelled in this file, which is the point — the glyphs differ per language\n * (`倍率 0.11x(国区) / 0.00x(国际区)` in Chinese,\n * `Multiplier 0.11x (China) / 0.00x (International)` in English) and a\n * separator chosen here would be right in at most one of them.\n *\n * `null` means \"this row states no rate\"; the caller drops it from the hint\n * array rather than rendering a placeholder, because a guessed rate on a spend\n * figure is worse than a missing one. `'0.00'` is a declaration — this model\n * consumes no allowance — so it renders like any other value.\n */\nexport function creditMultiplierHint(\n credits: WorkBuddyModelCredits | undefined,\n region: WorkBuddyRegion | null,\n labels: {\n multiplier: string\n region: (value: string, key: WorkBuddyRegion) => string\n pair: (first: string, second: string) => string\n },\n): string | null {\n // An empty string is the shape a catalog entry takes when its publisher\n // declared no rate: the host's parser already turns it into an absent key,\n // and a client running against a host that did not must not print `倍率 x`.\n const rate = (key: WorkBuddyRegion): string | null => {\n const value = credits?.[key]\n return typeof value === 'string' && value !== '' ? value : null\n }\n\n if (region !== null) {\n const value = rate(region)\n return value === null ? null : `${labels.multiplier} ${value}x`\n }\n\n const cn = rate('cn')\n const intl = rate('intl')\n if (cn === null) return intl === null ? null : `${labels.multiplier} ${intl}x`\n if (intl === null || intl === cn) return `${labels.multiplier} ${cn}x`\n // Both regions, cn first, each qualified: an unqualified pair would read as\n // one rate with a stray number beside it. The join comes from `labels.pair`\n // too — a separator written here would be the one piece of this string the\n // dictionary could not reach, and it is exactly where the two languages\n // diverge (a full-width bracket already carries its own spacing, an ASCII one\n // does not, so `(China)/ 0.00x` glued the entries together).\n return `${labels.multiplier} ${labels.pair(\n labels.region(`${cn}x`, 'cn'),\n labels.region(`${intl}x`, 'intl'),\n )}`\n}\n\n/** Mask a UIN so the card shows identity without publishing the full number. */\nexport function maskUin(uin?: string | null): string {\n if (uin === undefined || uin === null || uin === '') return '—'\n if (uin.length <= 6) return uin\n return `${uin.slice(0, 4)}****${uin.slice(-2)}`\n}\n\nexport function WorkBuddySection({ onModelChange, loadModelDirectory }: WorkBuddySectionProps): React.ReactElement {\n const { state, derived, actions } = useWorkBuddySection({ onModelChange, loadModelDirectory })\n const { status, loading, busy, error, connection, loginProgress, contextDrafts, savingModel } = state\n const {\n poolAccounts, effortChoices, allModels, strayEffort, contextModels, overrideCount,\n quota, authenticated, unreachable, poolLabels,\n } = derived\n const {\n login, rescan, accountAction, deleteAccount, setStrategy, testConnection, refreshQuota,\n checkinNow, updateCheckin, toggleModel, setAllModels, updateEffort, refreshCatalog,\n saveContextWindow, resetContextWindow, resetAllContextWindows, updateContextDraft,\n } = actions\n\n const t = zh\n\n if (loading) {\n return (\n <div className=\"dsha-page\">\n <div className=\"dsha-empty\">{t.loading}</div>\n </div>\n )\n }\n\n return (\n <div className=\"dsha-page\">\n <AccountPoolSection<WorkBuddyAccountSummaryDto>\n accounts={poolAccounts}\n activeAccountId={status?.activeAccountId}\n rotationStrategy={status?.rotationStrategy ?? 'sequential'}\n labels={poolLabels}\n busy={busy}\n showQuota\n onLogin={() => void login('cn')}\n onSetPrimary={(id) => void accountAction('set-primary', id)}\n onDelete={(id) => void deleteAccount(id)}\n onClearCooldown={(id) => void accountAction('clear-cooldown', id)}\n onRelogin={(id) => void accountAction('relogin', id)}\n onSetStrategy={(strategy) => void setStrategy(strategy)}\n renderLoginActions={() => (\n <div className=\"dsha-account-add-actions\">\n <button className=\"dsha-btn dsha-btn-primary\" disabled={busy !== null} onClick={() => void login('cn')}>\n {busy === 'login:cn' ? t.authorizing : t.addCnAccount}\n </button>\n <button className=\"dsha-btn dsha-btn-primary\" disabled={busy !== null} onClick={() => void login('intl')}>\n {busy === 'login:intl' ? t.authorizing : t.addIntlAccount}\n </button>\n </div>\n )}\n renderAccountActions={(candidate) => (\n // Only an account this plugin owns may be deleted; a desktop account\n // is the IDE's, so the card offers hide/restore for it instead.\n candidate.removable ? null : (\n <>\n {candidate.hidden === true && (\n <button className=\"dsha-btn\" disabled={busy !== null} onClick={() => void accountAction('restore', candidate.id)}>\n {t.restoreAccount}\n </button>\n )}\n {candidate.hidden !== true && (\n <button className=\"dsha-btn\" disabled={busy !== null} onClick={() => void accountAction('hide', candidate.id)}>\n {t.hideAccount}\n </button>\n )}\n </>\n )\n )}\n renderDetails={(candidate) => (\n <>\n {candidate.uin ? <span>{t.uin}: {maskUin(candidate.uin)}</span> : null}\n {candidate.accountType ? <span>{t.accountType}: {candidate.accountType}</span> : null}\n <span>\n {t.region}: {candidate.region === 'intl' ? t.regionIntl : t.regionCn}\n </span>\n {candidate.domain ? (\n <span className=\"dshwb-mono\" title={`${candidate.domain} · ${candidate.backend ?? ''}`}>\n {candidate.domain}\n </span>\n ) : null}\n {candidate.hidden === true ? <span>{t.hiddenAccount}</span> : null}\n </>\n )}\n >\n {/* The shared empty state already covers \"no account signed in\"; only\n an unreachable route needs a panel of its own, because it must not\n read as a credential problem. */}\n {unreachable ? (\n <>\n <div className=\"dsha-empty\">{t.routeUnreachable}</div>\n <p className=\"dsha-notice\">{t.routeUnreachableHint}</p>\n </>\n ) : null}\n {loginProgress ? <p className=\"dsha-notice\">{loginProgress}</p> : null}\n <div className=\"dsha-actions\">\n <button className=\"dsha-btn\" disabled={busy !== null} onClick={() => void rescan()}>\n {busy === 'rescan' ? t.rescanning : t.rescan}\n </button>\n </div>\n </AccountPoolSection>\n\n {status?.checkin != null ? (\n <section className=\"dsha-group\">\n <div className=\"dsha-grouphead\">\n <h3>{t.dailyCheckin}</h3>\n </div>\n <p className=\"dsha-muted\">{t.checkinHint}</p>\n <div className=\"dsha-row\" style={{ marginBottom: 8 }}>\n <span className=\"dsha-label\" style={{ fontWeight: 600 }}>{t.checkinAuto}</span>\n <input\n type=\"checkbox\"\n checked={status.checkin.enabled}\n disabled={busy !== null}\n onChange={(event) => void updateCheckin({ enabled: event.currentTarget.checked })}\n />\n </div>\n <div className=\"dsha-row\">\n <span className=\"dsha-label\">{t.dailyCheckin}</span>\n <span className=\"dsha-value\">\n {t.checkinToday.replace('{done}', String(status.checkin.doneToday)).replace('{total}', String(status.checkin.totalAccounts))}\n {status.checkin.skippedToday > 0\n ? ` · ${t.checkinSkipped.replace('{count}', String(status.checkin.skippedToday))}`\n : ''}\n {status.checkin.failedToday > 0\n ? ` · ${t.checkinFailed.replace('{count}', String(status.checkin.failedToday))}`\n : ''}\n {` · ${status.checkin.lastRunAt === null ? t.checkinNever : t.checkinLastRun.replace('{time}', new Date(status.checkin.lastRunAt).toLocaleString())}`}\n </span>\n </div>\n <div className=\"dsha-actions\">\n <button className=\"dsha-btn\" disabled={busy !== null} onClick={() => void checkinNow()}>\n {busy === 'checkin' ? t.checkinRunning : t.checkinNow}\n </button>\n </div>\n </section>\n ) : null}\n\n <section className=\"dsha-group\">\n <div className=\"dsha-grouphead\">\n <h3>{t.connection}</h3>\n </div>\n <p className=\"dsha-notice\">\n {status?.serving === false && status.conflict\n ? t.routeConflict.replace('{detail}', status.conflict)\n : t.routeOwned}\n </p>\n <div className=\"dsha-actions\">\n <button\n className=\"dsha-btn\"\n disabled={busy !== null || !authenticated}\n onClick={() => void testConnection()}\n >\n {busy === 'connection' ? t.testingConnection : t.testConnection}\n </button>\n </div>\n </section>\n\n <section className=\"dsha-group\">\n <div className=\"dsha-grouphead\">\n <h3>{t.modelsSection}</h3>\n <button\n className=\"dsha-btn\"\n disabled={busy !== null || !authenticated}\n onClick={() => void refreshCatalog()}\n >\n {busy === 'catalog' ? t.refreshingCatalog : t.refreshCatalog}\n </button>\n </div>\n <p className=\"dsha-muted dsha-models-hint\">{t.modelsHint}</p>\n <ModelChecklist\n items={(status?.models ?? []).map((model: WorkBuddyModelOption) => {\n // The spend rate goes LAST: capacity and the image/effort facts\n // describe what the model accepts, while the multiplier describes\n // what it costs. Keeping the money fact at the end leaves the\n // capability cluster readable as one phrase, and it reads the same\n // way the official picker spells a rate beside a model.\n const multiplier = creditMultiplierHint(model.credits, status?.account?.region ?? null, {\n multiplier: t.creditMultiplier,\n region: (value: string, key: WorkBuddyRegion): string => t.creditMultiplierRegion\n .replace('{value}', value)\n .replace('{region}', key === 'cn' ? t.regionCn : t.regionIntl),\n pair: (first: string, second: string): string => t.creditMultiplierPair\n .replace('{first}', first)\n .replace('{second}', second),\n })\n return {\n id: model.id,\n name: model.name,\n hint: [\n formatCapacity(model.contextWindow),\n model.supportsImage ? t.imageSupport : t.textOnly,\n ...(model.reasoningEfforts && model.reasoningEfforts.length > 0\n ? [model.reasoningEfforts.join('/')]\n : []),\n // A model with no published rate contributes NO element, so the\n // line neither grows a placeholder nor gains a doubled separator.\n ...(multiplier === null ? [] : [multiplier]),\n ].join(' · '),\n enabled: model.enabled,\n }\n })}\n busy={busy !== null}\n onToggle={(id, enabled) => void toggleModel(id, enabled)}\n onToggleAll={(enabled) => void setAllModels(enabled)}\n labels={{ selectAll: t.selectAll, clearAll: t.unselectAll, list: t.modelsSection }}\n />\n </section>\n\n <section className=\"dsha-group\">\n <div className=\"dsha-grouphead\">\n <h3>{t.enhanced}</h3>\n </div>\n <div className=\"dsha-pref-row\">\n <div>\n <strong>{t.defaultReasoningEffort}</strong>\n <p className=\"dsha-muted\">{t.defaultReasoningEffortHint}</p>\n {strayEffort !== null ? <p className=\"dsha-muted\">{t.defaultEffortKept}</p> : null}\n </div>\n <select\n className=\"dsha-select\"\n aria-label={t.defaultReasoningEffort}\n value={status?.defaultReasoningEffort ?? ''}\n disabled={busy !== null}\n onChange={(event) => {\n const value = event.currentTarget.value\n void updateEffort(value === '' ? null : (value as WorkBuddyReasoningEffort))\n }}\n >\n <option value=\"\">{t.defaultEffortAuto}</option>\n {/* A saved level no model declares is kept selectable so opening\n the card does not silently rewrite the stored value. */}\n {strayEffort !== null ? (\n <option value={strayEffort}>{`${EFFORT_LABELS[strayEffort]} (${t.effortUnsupported})`}</option>\n ) : null}\n {effortChoices.map((choice) => (\n <option key={choice.value} value={choice.value}>\n {choice.models.length === allModels.length\n ? EFFORT_LABELS[choice.value]\n : `${EFFORT_LABELS[choice.value]} (${choice.models.length}/${allModels.length})`}\n </option>\n ))}\n </select>\n </div>\n {effortChoices.length === 0 ? (\n <p className=\"dsha-muted\">{t.noReasoningModels}</p>\n ) : null}\n </section>\n\n <section className=\"dsha-group\">\n <div className=\"dsha-grouphead\">\n <h3>{t.contextWindowSection}</h3>\n </div>\n <p className=\"dsha-muted\">{t.contextWindowHint}</p>\n <ContextWindowEditor\n rows={contextModels.map((model: WorkBuddyModelOption) => ({\n id: model.id,\n name: model.name,\n draft: contextDrafts[model.id] ?? '',\n inputLabel: `${model.name} context window`,\n hasOverride: status?.contextWindowOverrides[model.id] !== undefined,\n saving: savingModel === model.id,\n }))}\n labels={{\n tokens: 'tokens',\n save: t.save,\n saving: t.saving,\n reset: t.contextWindowReset,\n resetAll: t.contextWindowResetAll,\n empty: t.contextWindowNoneEnabled,\n }}\n busy={busy !== null}\n overrideCount={overrideCount}\n onDraftChange={(id, draft) => updateContextDraft(id, draft)}\n onCommit={(id) => void saveContextWindow(id)}\n onReset={(id) => void resetContextWindow(id)}\n onResetAll={() => void resetAllContextWindows()}\n />\n </section>\n\n <section className=\"dsha-group\">\n <div className=\"dsha-grouphead\">\n <h3>{t.quotaSection}</h3>\n <button\n className=\"dsha-btn\"\n disabled={busy !== null || !authenticated}\n onClick={() => void refreshQuota()}\n >\n {busy === 'quota' ? t.refreshingQuota : t.refreshQuota}\n </button>\n </div>\n <p className=\"dsha-muted\">{t.quotaDesc}</p>\n {/* The progress bars moved into each account card: quota follows the\n account, so a bar here could only ever describe whichever account\n happened to be active when the snapshot was read. What stays is what\n has no per-account bar to live in — the package and its credits, the\n cycle counters, the meters that state no share, and the freshness of\n this reading. */}\n <p className=\"dsha-muted\">{poolLabels.quotaFactsScope}</p>\n\n {!authenticated ? (\n <div className=\"dsha-empty\">{t.signedOut}</div>\n ) : quota === null || quota === undefined ? (\n <div className=\"dsha-empty\">{busy === 'quota' ? t.refreshingQuota : t.quotaEmpty}</div>\n ) : (\n <div className=\"dsha-quota-card\">\n <div className=\"dsha-quota-title\">\n <strong>{quota.packageName || t.quotaPackage}</strong>\n <span>\n {quota.remainingCredits !== null\n ? `${quota.remainingCredits} ${t.credits}`\n : '—'}\n </span>\n </div>\n\n {quota.cycleUsedCredits !== null && (\n <div className=\"dsha-row\">\n <span className=\"dsha-label\">{t.quotaCycle}</span>\n <span className=\"dsha-value\">\n {quota.cycleUsedCredits}\n {quota.cycleCredits !== null ? ` / ${quota.cycleCredits}` : ''}\n {` ${t.credits}`}\n </span>\n </div>\n )}\n {quota.cycleEndsAt !== null && (\n <div className=\"dsha-row\">\n <span className=\"dsha-label\">{t.quotaReset}</span>\n <span className=\"dsha-value\">\n {formatDate(quota.cycleEndsAt)}\n {formatReset(quota.cycleEndsAt) ? ` · ${formatReset(quota.cycleEndsAt)}` : ''}\n </span>\n </div>\n )}\n\n {quota.meters.filter((meter) => meter.remainingFraction === null).map((meter) => (\n <div key={meter.id} className=\"dsha-meter-wrap\">\n <div className=\"dsha-meter-label\">\n <span>{meter.label}</span>\n <strong>{meter.limit ?? '—'}</strong>\n </div>\n <div className=\"dsha-meter-meta\">\n {meter.used !== null && <span>{meter.used} / {meter.limit ?? '—'}</span>}\n {meter.resetsAt !== null && <span>{t.quotaReset}: {formatReset(meter.resetsAt)}</span>}\n </div>\n {meter.description !== null && (\n <div className=\"dsha-meter-meta\"><span>{meter.description}</span></div>\n )}\n </div>\n ))}\n\n {quota.meters.length === 0 && <div className=\"dsha-empty\">{t.quotaEmpty}</div>}\n\n <div className=\"dsha-timestamp\">\n {t.updatedAt.replace('{time}', new Date(quota.fetchedAt).toLocaleString())}\n </div>\n </div>\n )}\n </section>\n\n {error && (\n <div className=\"dsha-error\">\n <div>{error}</div>\n </div>\n )}\n </div>\n )\n}\n","/**\n * The MiniMax Code routes the settings card consumes.\n *\n * This module used to carry its own reader — the last one left after\n * `common/line-api.ts` took the other nine — and it still carried the predicate\n * the shared reader dropped: a 2xx answer of `{ ok: false, error }` with no\n * `value` was handed back as a payload instead of raising. Delegating is\n * therefore not only de-duplication: it is what makes this line answer a\n * failure exactly like its siblings.\n *\n * The names stay as they were so the hook that consumes them does not have to\n * change with the reader.\n */\nimport { MINIMAX_CODE_ROUTE_PREFIX } from '../../shared/minimax-code-contracts.ts'\nimport { createLineApi } from '../common/line-api.ts'\n\nconst api = createLineApi(MINIMAX_CODE_ROUTE_PREFIX, 'MiniMax Code')\n\nexport const request = api.request\nexport const get = api.get\nexport const post = api.post\n\nexport function messageOf(cause: unknown): string {\n return cause instanceof Error ? cause.message : String(cause)\n}\n","import { accountPoolEn, accountPoolZh } from '../common/account-pool-labels.ts'\n\nexport const NS_MINIMAX_CODE = 'dsh-minimax-code'\n\nexport const zh = {\n // The account-management card is shared with every other provider tab.\n ...accountPoolZh,\n title: 'MiniMax Code',\n pageDesc: '登录 MiniMax Code 编程订阅(设备码 OAuth),复用本机 MiniMax Code 的登录态,管理账号、连接与模型。',\n account: '账号',\n signedIn: '已登录',\n signedOut: '未登录',\n accountLabel: '账号标签',\n accountId: '账号 ID',\n email: '邮箱',\n region: '区域',\n regionCn: '中国大陆 (minimax.cn)',\n regionGlobal: '国际 (minimax.io)',\n expiresAt: '令牌到期',\n expiresRemaining: '剩余 {hours} 小时',\n expiresExpired: '已过期',\n expiresHint: '访问令牌约 24 小时有效;Host 会在令牌过期或上游返回 401 时自动刷新。刷新被拒绝时请回到 MiniMax Code 重新登录。',\n signIn: '登录 MiniMax Code',\n signingIn: '正在申请设备码...',\n signOut: '登出',\n cancelSignIn: '取消登录',\n deviceCodeSection: '设备码授权',\n deviceCodeHint: '在浏览器中打开下方链接(用户码已单独列出,可复制),用你的 MiniMax 账号确认授权。',\n userCode: '用户码',\n copyCode: '复制用户码',\n copied: '已复制',\n openSignInPage: '打开授权页面',\n codeExpires: '设备码有效期',\n codeMinutes: '剩余 {minutes} 分钟',\n waitingAuthorization: '等待浏览器授权...',\n loginFailed: '登录失败',\n loginExpired: '设备码已过期,请重新发起登录。',\n loginDenied: '授权被拒绝。',\n logoutOwnedByApp: '当前登录态属于 MiniMax Code 桌面端:本插件复用它并会在需要时续期写回,但不会撤销或删除它(那会把你从正在运行的 MiniMax Code 里踢下线)。请在 MiniMax Code 应用中退出登录。',\n connection: '连接',\n routeOwned: '本插件正在服务该模型路由。',\n routeConflict: '模型路由已被其他 Provider 占用:{detail}。请在 DSH 设置中移除重复的 Provider 配置后重新加载。',\n testConnection: '测试连接',\n testingConnection: '测试中...',\n testSuccess: '连接正常',\n testSuccessModel: '连接正常({model})',\n testFailed: '连接失败',\n modelsSection: '模型',\n modelsHint: '模型目录由本线路硬编码(MiniMax Code 未开放 /v1/models 接口),当前共 {count} 个可用模型。勾选后模型才会出现在对话页的模型选择列表中;未勾选或关闭下方「启用此供应商」可在列表中隐藏该线路。',\n modelsUnavailable: '暂无可显示的模型。',\n quotaSection: '用量与配额',\n dailyCheckin: '每日签到',\n checkinHint: '用本线路自己的登录态签到(与官方 MiniMax Code 客户端同一条接口)。DSH 启动时自动签到一次,运行期间每 10 分钟补检,进程关闭的当天不会签到。',\n checkinAuto: '自动签到',\n checkinToday: '今日已签 {done}/{total}',\n checkinSkipped: '{count} 个暂不可签',\n checkinFailed: '{count} 个失败',\n checkinStreak: '连续 {days} 天',\n checkinClaimed: '本轮 +{points} 积分',\n checkinLastRun: '上次运行:{time}',\n checkinNever: '尚未运行',\n checkinNow: '立即签到',\n checkinRunning: '签到中…',\n quotaUnavailable: '暂时没有用量数据。',\n quotaNeedsApiKey: '上游拒绝了这个登录态读取用量(官方客户端的用量端点要求带官方客户端标识头,本插件默认不伪造)。请在 MiniMax 控制台的用量条里查看 Token Plan 用量;如果你接受该取舍,可设 DSH_MINIMAX_CODE_QUOTA_ATTRIBUTION=1 后重试。',\n quotaUnreachable: '暂时读不到用量(用量端点未应答),稍后会自动重试。',\n quotaTokenExpired: '读取用量时令牌刚好过期,正在自动续期——账号仍然是登录状态,无需重新登录。',\n quotaStale: '下面是上一次成功读取到的用量(本次刷新未成功),稍后会自动重试。',\n quotaUsedShare: '已用 {percent}%',\n quotaRefresh: '刷新用量',\n quotaRefreshing: '刷新中...',\n composerLabel: '额度',\n // --- 与兄弟线路对齐的设置面(模型勾选 / 上下文窗口 / 默认思考深度)---\n selectAll: '全选',\n unselectAll: '全不选',\n enhanced: '增强功能',\n defaultReasoningEffort: '默认思考深度',\n defaultReasoningEffortHint: '控制支持推理的模型在未单独指定时的思考强度。',\n defaultEffortAuto: '自动(各模型默认)',\n contextWindowSection: '模型上下文窗口',\n contextWindowHint: '默认值来自订阅网关的模型目录(每个模型的真实上下文上限);可覆盖为自定义容量,该值用于 DSH 的压缩与溢出判断,可输入 1M、512K、200K 等容量。',\n contextWindowNoneEnabled: '尚未勾选任何模型,先在上方「模型」中勾选。',\n contextWindowReset: '恢复默认',\n contextWindowResetAll: '全部恢复默认',\n tokens: 'tokens',\n save: '保存',\n saving: '保存中...',\n invalidCapacity: '容量格式无效:{value}',\n // --- 思考形态(与 model-catalog.ts 的三种模式同名同义)---\n thinkingAlwaysOn: '恒定开启(无档位)',\n thinkingToggle: '可关闭',\n thinkingForced: '强制开启(可选档位)',\n capText: '文本',\n capImage: '图片',\n loading: '加载中...',\n unknown: '—',\n} as const\n\nexport const en: Record<keyof typeof zh, string> = {\n ...accountPoolEn,\n title: 'MiniMax Code',\n pageDesc: 'Sign in to the MiniMax Code coding subscription (device-code OAuth) and reuse the local MiniMax Code sign-in to manage the account, connection, and models.',\n account: 'Account',\n signedIn: 'Signed in',\n signedOut: 'Not signed in',\n accountLabel: 'Account label',\n accountId: 'Account ID',\n email: 'Email',\n region: 'Region',\n regionCn: 'Mainland China (minimax.cn)',\n regionGlobal: 'Global (minimax.io)',\n expiresAt: 'Token expires',\n expiresRemaining: '{hours} h left',\n expiresExpired: 'Expired',\n expiresHint: 'The access token lives about 24 hours; the Host refreshes it once it expires or the upstream answers 401. When a refresh is rejected, sign in again from MiniMax Code.',\n signIn: 'Sign in to MiniMax Code',\n signingIn: 'Requesting a device code...',\n signOut: 'Sign out',\n cancelSignIn: 'Cancel',\n deviceCodeSection: 'Device authorization',\n deviceCodeHint: 'Open the link below in a browser (the user code is listed separately so it can be copied) and approve it with your MiniMax account.',\n userCode: 'User code',\n copyCode: 'Copy user code',\n copied: 'Copied',\n openSignInPage: 'Open the sign-in page',\n codeExpires: 'Device code expires',\n codeMinutes: '{minutes} min left',\n waitingAuthorization: 'Waiting for browser authorization...',\n loginFailed: 'Sign-in failed',\n loginExpired: 'The device code expired — start the sign-in again.',\n loginDenied: 'Authorization was denied.',\n logoutOwnedByApp: 'This sign-in belongs to the MiniMax Code desktop app. This plugin reuses it and renews it in place when needed, but it will not revoke or delete it (doing so would sign you out of the running MiniMax Code app). Sign out in the MiniMax Code app instead.',\n connection: 'Connection',\n routeOwned: 'This plugin serves the model route.',\n routeConflict: 'Another provider already owns the model route: {detail}. Remove the duplicate provider configuration in DSH settings and reload.',\n testConnection: 'Test connection',\n testingConnection: 'Testing...',\n testSuccess: 'Connection OK',\n testSuccessModel: 'Connection OK ({model})',\n testFailed: 'Connection failed',\n modelsSection: 'Models',\n modelsHint: 'The catalog is hardcoded on this line (MiniMax Code exposes no /v1/models endpoint): {count} models available. Only checked models appear in the conversation model picker; unchecking or switching off \"Enable this provider\" hides the line from the list.',\n modelsUnavailable: 'No model to show yet.',\n quotaSection: 'Usage & quota',\n dailyCheckin: 'Daily check-in',\n checkinHint: 'Signs in with this line’s own credential (the same interface the official MiniMax Code client uses). The host signs in once at startup and re-checks every 10 minutes while running; a day the process never runs is not signed.',\n checkinAuto: 'Auto check-in',\n checkinToday: 'Checked in today {done}/{total}',\n checkinSkipped: '{count} not claimable yet',\n checkinFailed: '{count} failed',\n checkinStreak: '{days}-day streak',\n checkinClaimed: '+{points} credits this run',\n checkinLastRun: 'Last run: {time}',\n checkinNever: 'Never run',\n checkinNow: 'Check in now',\n checkinRunning: 'Checking in…',\n quotaUnavailable: 'No usage data yet.',\n quotaNeedsApiKey: 'The service refused this sign-in for the usage read (the official client\\'s endpoint expects first-party attribution headers, which this plugin does not forge by default). Check the usage bar in the MiniMax console; if you accept that trade, set DSH_MINIMAX_CODE_QUOTA_ATTRIBUTION=1 and retry.',\n quotaUnreachable: 'Usage is temporarily unreadable (the usage endpoint did not answer); this retries on its own.',\n quotaTokenExpired: 'The token expired just as usage was being read, and is being renewed automatically. The account is still signed in; no action needed.',\n quotaStale: 'Below is the last usage read that succeeded (this refresh failed); it retries on its own.',\n quotaUsedShare: '{percent}% used',\n quotaRefresh: 'Refresh usage',\n quotaRefreshing: 'Refreshing...',\n composerLabel: 'Quota',\n selectAll: 'Select all',\n unselectAll: 'Unselect all',\n enhanced: 'Enhanced',\n defaultReasoningEffort: 'Default reasoning effort',\n defaultReasoningEffortHint: 'Thinking strength for reasoning models when the conversation does not pick one.',\n defaultEffortAuto: 'Auto (each model default)',\n contextWindowSection: 'Model context windows',\n contextWindowHint: 'Defaults come from the subscription gateway model directory (each model\\'s real upper bound). Override one to a custom capacity; the value feeds the compression and overflow decisions. Accepts 1M, 512K, 200K and similar.',\n contextWindowNoneEnabled: 'No model is checked yet — pick one in \"Models\" above.',\n contextWindowReset: 'Restore default',\n contextWindowResetAll: 'Restore all defaults',\n tokens: 'tokens',\n save: 'Save',\n saving: 'Saving...',\n invalidCapacity: 'Invalid capacity: {value}',\n thinkingAlwaysOn: 'Always on (no level)',\n thinkingToggle: 'Can be disabled',\n thinkingForced: 'Forced on (level selectable)',\n capText: 'Text',\n capImage: 'Image',\n loading: 'Loading...',\n unknown: '—',\n}\n\nexport const dictionaries = {\n zh,\n 'zh-CN': zh,\n en,\n 'en-US': en,\n}\n\nexport type MinimaxCodeLocaleKey = keyof typeof zh\n","/**\n * The MiniMax Code card's state, effects and actions.\n *\n * Split out of 'MinimaxCodeSection.tsx' so that file is markup and this one is\n * behaviour: what the card tracks, what it derives from a status answer, and\n * every request a control can make. The view reads one named shape — see\n * `MinimaxCodeSectionView` — so the contract between the two is visible here\n * rather than inferred from the JSX.\n */\nimport { useCallback, useEffect, useRef, useState } from 'react'\nimport type {\n AccountPoolStatusDto,\n AccountRotationStrategy,\n} from '../../shared/account-pool-contracts.ts'\nimport type {\n MinimaxCodeAccount,\n MinimaxCodeModelOption,\n MinimaxCodeQuota,\n MinimaxCodeReasoningEffort,\n MinimaxCodeWebLogin,\n MinimaxCodeWebStatus,\n} from '../../shared/minimax-code-contracts.ts'\nimport type { AccountPoolLabels } from '../common/AccountPoolSection.tsx'\nimport { contextDraftsFor } from '../common/ContextWindowEditor.tsx'\nimport { formatCapacity, parsePositiveCapacity } from '../common/format.ts'\nimport { createQuotaFollowUp, type QuotaFollowUp } from '../common/quota-follow-up.ts'\nimport { get, messageOf, post } from './api.ts'\nimport { zh } from './locales.ts'\n\n/** The pool slice the status card renders, absent when the line has no pool. */\nexport type MinimaxCodePoolStatus = Pick<AccountPoolStatusDto, 'accounts' | 'rotationStrategy'> & {\n activeAccountId?: string\n}\n\n/**\n * The keys this card renders.\n *\n * The provider hub hosts every provider tab inside one settings section whose\n * injected `t` seat is bound to the hub's own namespace, and every sibling tab\n * therefore renders its own dictionary instead of that seat (see KimiCodeSection,\n * WorkBuddySection and CommandCodeSection, none of which declare a locale prop).\n * This card must do the same: its keys are not a subset of the hub's, so using the\n * hub's seat resolves the overlap to ChatGPT wording (\"使用 ChatGPT 登录\" on the\n * MiniMax tab) and every other key to the literal key text.\n */\nexport type Translate = (key: keyof typeof zh) => string\n\n/** The card's own dictionary; stable identity keeps effect dependencies intact. */\nexport const fallbackTranslate: Translate = (key) => zh[key]\n\n/**\n * The shared pool card's labels, resolved through this card's dictionary.\n *\n * The sibling tabs hand the shared card their raw `zh` object, which works because\n * they render `zh` directly. This card renders through a translate function\n * instead, so the same label set is assembled here by looking each key up. It is\n * derived from the shared ZH label object's own keys, so a label added to the\n * shared card cannot be silently missed — the `satisfies` below turns that into a\n * compile error.\n */\nfunction accountPoolLabelsFor(t: Translate): AccountPoolLabels {\n return {\n accountPool: t('accountPool'),\n addAccount: t('addAccount'),\n accountCount: t('accountCount'),\n primaryAccount: t('primaryAccount'),\n activeAccount: t('activeAccount'),\n setPrimary: t('setPrimary'),\n deleteAccount: t('deleteAccount'),\n cooling: t('cooling'),\n cooldownLeft: t('cooldownLeft'),\n clearCooldown: t('clearCooldown'),\n needsRelogin: t('needsRelogin'),\n relogin: t('relogin'),\n rotationStrategy: t('rotationStrategy'),\n strategySequential: t('strategySequential'),\n strategyRoundRobin: t('strategyRoundRobin'),\n strategySticky: t('strategySticky'),\n noAccounts: t('noAccounts'),\n email: t('email'),\n expires: t('expiresAt'),\n lastUsed: t('lastUsed'),\n accountId: t('accountId'),\n accountQuota: t('accountQuota'),\n quotaNone: t('quotaNone'),\n quotaSnapshot: t('quotaSnapshot'),\n quotaResets: t('quotaResets'),\n quotaExhausted: t('quotaExhausted'),\n quotaWindow: t('quotaWindow'),\n quotaUsed: t('quotaUsed'),\n quotaFactsScope: t('quotaFactsScope'),\n composerLabel: t('composerLabel'),\n }\n}\n\n/** Device-code poll cadence. The host owns the real expiry. */\nconst LOGIN_POLL_INTERVAL_MS = 2_000\n\n/** `/login/poll` answer, exactly as the frozen route table defines it. */\ninterface LoginPollResult {\n status: 'pending' | 'authenticated' | 'expired' | 'denied'\n account?: MinimaxCodeAccount\n}\n\n/** `/login/start` answer: `{ ok: true, login }` per the frozen route table. */\ninterface LoginStartResult {\n ok?: boolean\n login?: MinimaxCodeWebLogin\n}\n\n/** `/test` answer: `{ ok, model?, error? }` per the frozen route table. */\ninterface ConnectionTestResult {\n ok?: boolean\n model?: string\n error?: string\n}\n\n/**\n * Props this card accepts.\n *\n * Deliberately the same shape every sibling tab declares: the hub hands each tab\n * only the refresh callback. The card does not take the hub's `settings.section`\n * runtime seat or its locale seat, because it renders its own dictionary (see\n * below) and needs none of that scope's other props.\n */\nexport interface MinimaxCodeSectionProps {\n onModelChange?: () => void\n}\n\n/**\n * Everything the card's view consumes, grouped by kind.\n *\n * Returned as one named shape instead of one status blob: a reader can see at a\n * glance what the hook tracks, what it computes from a status answer, and what\n * the view is allowed to ask it to do.\n */\nexport interface MinimaxCodeSectionView {\n /** Values that change as the card runs. */\n state: {\n /** Last status answer; null until the first read lands. */\n status: MinimaxCodeWebStatus | null\n /** True until the first status read settles, whatever its outcome. */\n loading: boolean\n /** Id of the action in flight, or null; every disabled control reads it. */\n busy: string | null\n /** The failure the card's error strip shows. */\n error: string | null\n /** The device-code flow being polled, when one is running. */\n flow: MinimaxCodeWebLogin | null\n /** Whether the user code was just copied, so the button can say so. */\n copied: boolean\n /** Result of the last explicit connection test, as one sentence. */\n connectionNotice: string | null\n /** One free-text capacity draft per model, keyed by model id. */\n contextDrafts: Record<string, string>\n /** Model id whose context-window save or restore is in flight. */\n savingModel: string | null\n /** The pool slice read beside the status; undefined when the line has no pool. */\n pool: MinimaxCodePoolStatus | undefined\n }\n /** Facts read straight off the current status answer. */\n derived: {\n /** Whether the line holds a usable credential. */\n authenticated: boolean\n /** The signed-in account, when the host reports one. */\n account: MinimaxCodeAccount | undefined\n /** The displayed account's usage snapshot, when the host has one. */\n quota: MinimaxCodeQuota | undefined\n /** Every catalog row, in catalog order. */\n models: MinimaxCodeModelOption[]\n /** Models the context-window editor offers: the enabled ones only. */\n contextModels: MinimaxCodeModelOption[]\n /** How many stored overrides exist, whether or not a row still shows them. */\n overrideCount: number\n /**\n * The line's label set, handed to the shared pool card as one object.\n *\n * The hook resolves it for its own sentences too, so the view takes the\n * assembled labels from here rather than reaching for a second binding.\n */\n poolLabels: AccountPoolLabels\n }\n /** Everything the view can trigger. */\n actions: {\n /** Start a device-code sign-in. */\n login(): Promise<void>\n cancelLogin(): Promise<void>\n /** Copy the flow's user code; the button says so for two seconds. */\n copyCode(): Promise<void>\n logout(): Promise<void>\n /** One account-level action on the shared pool card. */\n poolAction(\n action: 'set-primary' | 'delete' | 'clear-cooldown' | 'relogin',\n accountId: string,\n ): Promise<void>\n setStrategy(strategy: AccountRotationStrategy): Promise<void>\n toggleModel(modelId: string, checked: boolean): void\n setAllModels(selectAll: boolean): void\n /** Flip the check-in scheduler's own switch. */\n setCheckinEnabled(enabled: boolean): Promise<void>\n /** Run one check-in pass now. */\n runCheckinNow(): Promise<void>\n updateEffort(effort: MinimaxCodeReasoningEffort | null): Promise<void>\n saveContextWindow(modelId: string): Promise<void>\n resetContextWindow(modelId: string): Promise<void>\n resetAllContextWindows(): Promise<void>\n refreshQuota(): Promise<void>\n testConnection(): Promise<void>\n /** Edit one capacity draft mid-typing; the editor never parses it. */\n updateContextDraft(modelId: string, draft: string): void\n }\n}\n\nexport function useMinimaxCodeSection({ onModelChange }: MinimaxCodeSectionProps): MinimaxCodeSectionView {\n const t: Translate = fallbackTranslate\n const [status, setStatus] = useState<MinimaxCodeWebStatus | null>(null)\n const [loading, setLoading] = useState(true)\n const [busy, setBusy] = useState<string | null>(null)\n const [error, setError] = useState<string | null>(null)\n const [flow, setFlow] = useState<MinimaxCodeWebLogin | null>(null)\n const [copied, setCopied] = useState(false)\n // Result of an explicit connection test. The button used to end silently on\n // success, which is indistinguishable from a click that never registered.\n const [connectionNotice, setConnectionNotice] = useState<string | null>(null)\n // Free-text context-window drafts, keyed by model id, so a half-typed value\n // does not round-trip to the host on every keystroke.\n const [contextDrafts, setContextDrafts] = useState<Record<string, string>>({})\n const [savingModel, setSavingModel] = useState<string | null>(null)\n // The pool slice, read beside the status. Absent until the first read answers,\n // and absent for a host that has no pool installed at all.\n const [pool, setPool] = useState<MinimaxCodePoolStatus | undefined>(undefined)\n\n // The follow-up poll for a usage read the host is running behind its answer.\n // Every sibling card has this and this one did not, which is why a page\n // opened right after a restart sat on \"no usage data\" until the 60 s tick:\n // the host was already fetching, the answer simply could not say so.\n const quotaFollowUp = useRef<QuotaFollowUp | undefined>(undefined)\n\n const loadStatus = useCallback(async (quiet = false) => {\n if (!quiet) setError(null)\n try {\n const next = await get<MinimaxCodeWebStatus>('/status')\n setStatus(next)\n setContextDrafts(contextDraftsFor(next))\n quotaFollowUp.current ??= createQuotaFollowUp()\n quotaFollowUp.current.observe(next.quotaRefreshing === true, () => { void loadStatus(true) })\n } catch (cause) {\n if (!quiet) setError(messageOf(cause))\n } finally {\n setLoading(false)\n }\n }, [])\n\n useEffect(() => {\n void loadStatus()\n void loadPool()\n const refreshWhenVisible = (): void => {\n if (document.visibilityState === 'visible') {\n void loadStatus(true)\n void loadPool()\n }\n }\n document.addEventListener('visibilitychange', refreshWhenVisible)\n const timer = window.setInterval(refreshWhenVisible, 60_000)\n return () => {\n window.clearInterval(timer)\n document.removeEventListener('visibilitychange', refreshWhenVisible)\n quotaFollowUp.current?.cancel()\n }\n }, [loadStatus])\n\n const loginId = flow?.loginId\n\n // Authorization happens in a browser this card does not control, so the host\n // owns the device-code exchange and the card polls the host for its verdict.\n useEffect(() => {\n if (loginId === undefined) return\n let stopped = false\n const timer = window.setInterval(() => {\n void (async () => {\n try {\n const poll = await post<LoginPollResult>('/login/poll', { loginId })\n if (stopped || poll.status === 'pending') return\n stopped = true\n window.clearInterval(timer)\n setFlow(null)\n if (poll.status === 'authenticated') {\n await loadStatus()\n onModelChange?.()\n return\n }\n setError(poll.status === 'expired' ? t('loginExpired') : t('loginDenied'))\n } catch {\n // A failed poll is transient; the next tick retries.\n }\n })()\n }, LOGIN_POLL_INTERVAL_MS)\n return () => {\n stopped = true\n window.clearInterval(timer)\n }\n }, [loginId, loadStatus, onModelChange, t])\n\n /**\n * Fetch the usage snapshot once, the first time the card sees a signed-in\n * account without one.\n *\n * The status route refreshes usage BEHIND its answer, so it never blocks on a\n * network read; that means the very first paint has no snapshot. Asking here\n * fills the section immediately instead of leaving it empty for a whole poll\n * interval. A failure is silent on purpose: the section already explains that no\n * usage is available, and a usage read must never surface as an error banner.\n */\n // Declared here rather than beside the render values because the effect below\n // needs it and hooks must all run before the loading early-return.\n const authenticated = status?.authenticated === true\n const quotaRequested = useRef(false)\n useEffect(() => {\n if (quotaRequested.current || !authenticated || status?.quota !== undefined) return\n quotaRequested.current = true\n void (async () => {\n try {\n setStatus(await post<MinimaxCodeWebStatus>('/quota'))\n } catch {\n // Silent by design - see above.\n }\n })()\n }, [authenticated, status?.quota])\n\n const login = async (): Promise<void> => {\n try {\n setBusy('login')\n setError(null)\n setConnectionNotice(null)\n setCopied(false)\n const started = await post<LoginStartResult>('/login/start')\n // `login` is the frozen shape; a host that answers with the login object\n // itself is still read, because the card loses nothing by accepting it.\n const next = started.login ?? (typeof (started as { loginId?: unknown }).loginId === 'string'\n ? started as unknown as MinimaxCodeWebLogin\n : undefined)\n if (next === undefined) {\n setError(t('loginFailed'))\n return\n }\n setFlow(next)\n } catch (cause) {\n setError(messageOf(cause))\n } finally {\n setBusy(null)\n }\n }\n\n const cancelLogin = async (): Promise<void> => {\n const pending = flow\n setFlow(null)\n if (pending === null) return\n try {\n await post('/login/cancel', { loginId: pending.loginId })\n } catch (cause) {\n setError(messageOf(cause))\n }\n }\n\n const copyCode = async (): Promise<void> => {\n const code = flow?.userCode\n if (code === undefined || code === '') return\n try {\n await navigator.clipboard.writeText(code)\n setCopied(true)\n window.setTimeout(() => setCopied(false), 2_000)\n } catch {\n // Clipboard access can be denied; the code stays on screen to copy by hand.\n }\n }\n\n const logout = async (): Promise<void> => {\n try {\n setBusy('logout')\n setError(null)\n setConnectionNotice(null)\n setFlow(null)\n // The host refuses to sign out a credential the desktop app owns; that\n // refusal is a successful, expected answer rather than an error, so it is\n // surfaced as a notice and the status is re-read either way.\n const result = await post<{ ok?: boolean; native?: boolean; error?: string }>('/logout')\n if (result.native === true) {\n setConnectionNotice(result.error ?? t('logoutOwnedByApp'))\n }\n await loadStatus(true)\n onModelChange?.()\n } catch (cause) {\n setError(messageOf(cause))\n await loadStatus(true)\n } finally {\n setBusy(null)\n }\n }\n\n /**\n * Apply one model-selection patch through `/models`.\n *\n * The host owns the selection and answers with the whole fresh status, so the\n * card never guesses which ids ended up enabled.\n */\n /** Re-read the pool slice, which lives beside the status on its own route. */\n const loadPool = useCallback(async (): Promise<void> => {\n try {\n const next = await get<MinimaxCodePoolStatus>('/accounts')\n setPool(next)\n } catch {\n // A host without a pool answers with an error here; the section simply does\n // not render rather than reporting a failure the user cannot act on.\n setPool(undefined)\n }\n }, [])\n\n /** Run one account action, then re-read both the pool and the status. */\n const poolAction = async (\n action: 'set-primary' | 'delete' | 'clear-cooldown' | 'relogin',\n accountId: string,\n ): Promise<void> => {\n try {\n setBusy(action)\n setError(null)\n await post('/accounts', { action, accountId })\n await loadPool()\n await loadStatus(true)\n onModelChange?.()\n } catch (cause) {\n setError(messageOf(cause))\n } finally {\n setBusy(null)\n }\n }\n\n const setStrategy = async (strategy: AccountRotationStrategy): Promise<void> => {\n try {\n setBusy('strategy')\n setError(null)\n await post('/accounts', { action: 'strategy', strategy })\n await loadPool()\n } catch (cause) {\n setError(messageOf(cause))\n } finally {\n setBusy(null)\n }\n }\n\n const applyEnabled = async (enabledModelIds: string[]): Promise<void> => {\n try {\n setError(null)\n const updated = await post<MinimaxCodeWebStatus>('/models', { enabledModelIds })\n setStatus(updated)\n // A model that was just checked has no draft yet; the context-window\n // section only renders enabled models.\n setContextDrafts(contextDraftsFor(updated))\n onModelChange?.()\n } catch (cause) {\n setError(messageOf(cause))\n }\n }\n\n /** Flip the check-in scheduler's own switch, through the same settings route. */\n const setCheckinEnabled = async (enabled: boolean): Promise<void> => {\n try {\n setBusy('checkin')\n setError(null)\n const updated = await post<MinimaxCodeWebStatus>('/settings', { checkin: { enabled } })\n setStatus(updated)\n } catch (cause) {\n setError(messageOf(cause))\n } finally {\n setBusy(null)\n }\n }\n\n /** Run one check-in pass now: the toggle and the retry cap are bypassed. */\n const runCheckinNow = async (): Promise<void> => {\n try {\n setBusy('checkin')\n setError(null)\n const updated = await post<MinimaxCodeWebStatus>('/checkin/now')\n setStatus(updated)\n } catch (cause) {\n setError(messageOf(cause))\n } finally {\n setBusy(null)\n }\n }\n\n const toggleModel = (modelId: string, checked: boolean): void => {\n if (status === null) return\n const current = status.models.filter((model) => model.enabled).map((model) => model.id)\n const next = checked ? [...new Set([...current, modelId])] : current.filter((id) => id !== modelId)\n void applyEnabled(next)\n }\n\n const setAllModels = (selectAll: boolean): void => {\n if (status === null || status.models.length === 0) return\n void applyEnabled(selectAll ? status.models.map((model) => model.id) : [])\n }\n\n const updateEffort = async (effort: MinimaxCodeReasoningEffort | null): Promise<void> => {\n try {\n setError(null)\n const updated = await post<MinimaxCodeWebStatus>('/settings', { defaultReasoningEffort: effort })\n setStatus(updated)\n onModelChange?.()\n } catch (cause) {\n setError(messageOf(cause))\n }\n }\n\n const saveContextWindow = async (modelId: string): Promise<void> => {\n const raw = contextDrafts[modelId] ?? ''\n const parsed = parsePositiveCapacity(raw)\n if (parsed === null) {\n setError(t('invalidCapacity').replace('{value}', raw))\n return\n }\n try {\n setSavingModel(modelId)\n setError(null)\n const updated = await post<MinimaxCodeWebStatus>('/settings', { contextWindowOverrides: { [modelId]: parsed } })\n setStatus(updated)\n setContextDrafts((prev) => ({ ...prev, [modelId]: formatCapacity(parsed) }))\n onModelChange?.()\n } catch (cause) {\n setError(messageOf(cause))\n } finally {\n setSavingModel(null)\n }\n }\n\n const resetContextWindow = async (modelId: string): Promise<void> => {\n try {\n setSavingModel(modelId)\n setError(null)\n // `null` is the wire spelling of \"drop this override\": the host deletes the\n // key so the catalog default applies again.\n const updated = await post<MinimaxCodeWebStatus>('/settings', { contextWindowOverrides: { [modelId]: null } })\n setStatus(updated)\n const model = updated.models.find((entry) => entry.id === modelId)\n if (model !== undefined) {\n setContextDrafts((prev) => ({ ...prev, [modelId]: formatCapacity(model.defaultContextWindow) }))\n }\n onModelChange?.()\n } catch (cause) {\n setError(messageOf(cause))\n } finally {\n setSavingModel(null)\n }\n }\n\n const resetAllContextWindows = async (): Promise<void> => {\n const ids = Object.keys(status?.contextWindowOverrides ?? {})\n if (ids.length === 0) return\n try {\n setError(null)\n const updated = await post<MinimaxCodeWebStatus>('/settings', {\n contextWindowOverrides: Object.fromEntries(ids.map((id) => [id, null])),\n })\n setStatus(updated)\n setContextDrafts(contextDraftsFor(updated))\n onModelChange?.()\n } catch (cause) {\n setError(messageOf(cause))\n }\n }\n\n /** Force one usage read through `/quota` and render the fresh status. */\n const refreshQuota = async (): Promise<void> => {\n try {\n setBusy('quota')\n setError(null)\n setStatus(await post<MinimaxCodeWebStatus>('/quota'))\n } catch (cause) {\n setError(messageOf(cause))\n } finally {\n setBusy(null)\n }\n }\n\n const testConnection = async (): Promise<void> => {\n try {\n setBusy('test')\n setError(null)\n setConnectionNotice(null)\n const result = await post<ConnectionTestResult>('/test')\n if (result.ok === true) {\n setConnectionNotice(result.model === undefined || result.model === ''\n ? t('testSuccess')\n : t('testSuccessModel').replace('{model}', result.model))\n return\n }\n setConnectionNotice(result.error === undefined || result.error === ''\n ? t('testFailed')\n : `${t('testFailed')}:${result.error}`)\n } catch (cause) {\n setConnectionNotice(`${t('testFailed')}:${messageOf(cause)}`)\n } finally {\n setBusy(null)\n }\n }\n\n const updateContextDraft = (modelId: string, draft: string): void => {\n setContextDrafts((prev) => ({ ...prev, [modelId]: draft }))\n }\n\n const account = status?.account\n const quota = status?.quota\n const models = status?.models ?? []\n // Only enabled models have a context window to override: an unchecked model is\n // not offered to a conversation, so a capacity for it would be dead settings.\n const contextModels = status?.models.filter((model) => model.enabled) ?? []\n const overrideCount = Object.keys(status?.contextWindowOverrides ?? {}).length\n\n return {\n state: {\n status,\n loading,\n busy,\n error,\n flow,\n copied,\n connectionNotice,\n contextDrafts,\n savingModel,\n pool,\n },\n derived: {\n authenticated,\n account,\n quota,\n models,\n contextModels,\n overrideCount,\n poolLabels: accountPoolLabelsFor(t),\n },\n actions: {\n login,\n cancelLogin,\n copyCode,\n logout,\n poolAction,\n setStrategy,\n toggleModel,\n setAllModels,\n setCheckinEnabled,\n runCheckinNow,\n updateEffort,\n saveContextWindow,\n resetContextWindow,\n resetAllContextWindows,\n refreshQuota,\n testConnection,\n updateContextDraft,\n },\n }\n}\n","/**\n * The MiniMax Code settings card.\n *\n * Markup only: every piece of state, every effect and every request this card\n * makes lives in 'useMinimaxCodeSection.ts', which returns one named shape the\n * JSX below reads. The two files are the split of a single 915-line component —\n * the behaviour is unchanged, and this one should stay render-shaped.\n */\nimport React from 'react'\nimport {\n MINIMAX_CODE_REASONING_EFFORTS,\n type MinimaxCodeModelOption,\n type MinimaxCodeReasoningEffort,\n} from '../../shared/minimax-code-contracts.ts'\nimport { AccountPoolSection } from '../common/AccountPoolSection.tsx'\nimport { ContextWindowEditor } from '../common/ContextWindowEditor.tsx'\nimport { ModelChecklist } from '../common/ModelChecklist.tsx'\nimport { formatCapacity, formatDate } from '../common/format.ts'\nimport {\n fallbackTranslate,\n useMinimaxCodeSection,\n type MinimaxCodeSectionProps,\n type Translate,\n} from './useMinimaxCodeSection.ts'\n\n/** Human label per thinking mode, so the card states what the model does. */\nfunction thinkingLabel(mode: MinimaxCodeModelOption['thinking'], t: Translate): string {\n if (mode === 'always-on') return t('thinkingAlwaysOn')\n if (mode === 'forced-effort') return t('thinkingForced')\n return t('thinkingToggle')\n}\n\n/**\n * Hours still left on the access token, or null once it has run out.\n *\n * MiniMax Code's token lives about 24 hours, so hours are the unit the card\n * reports; a value worth a fraction of an hour keeps one decimal instead of\n * rounding down to 0.\n */\nexport function remainingHours(expiresAtMs: number | undefined): string | null {\n if (expiresAtMs === undefined || !Number.isFinite(expiresAtMs) || expiresAtMs <= 0) return null\n const hours = (expiresAtMs - Date.now()) / 3_600_000\n if (hours <= 0) return null\n return hours >= 10 ? hours.toFixed(0) : hours.toFixed(1)\n}\n\nexport function MinimaxCodeSection({ onModelChange }: MinimaxCodeSectionProps): React.JSX.Element {\n const { state, derived, actions } = useMinimaxCodeSection({ onModelChange })\n const { status, loading, busy, error, flow, copied, connectionNotice, contextDrafts, savingModel, pool } = state\n const { authenticated, account, quota, models, contextModels, overrideCount, poolLabels } = derived\n const {\n login, cancelLogin, copyCode, logout, poolAction, setStrategy, toggleModel, setAllModels,\n setCheckinEnabled, runCheckinNow, updateEffort, saveContextWindow, resetContextWindow,\n resetAllContextWindows, refreshQuota, testConnection, updateContextDraft,\n } = actions\n\n const t: Translate = fallbackTranslate\n\n if (loading) {\n return (\n <div className=\"dsha-page\">\n <div className=\"dsha-empty\">{t('loading')}</div>\n </div>\n )\n }\n\n const hours = remainingHours(account?.expiresAtMs)\n\n return (\n <div className=\"dsha-page\">\n <p className=\"dsha-muted\">{t('pageDesc')}</p>\n\n {pool !== undefined && (\n <AccountPoolSection\n labels={poolLabels}\n accounts={pool.accounts}\n rotationStrategy={pool.rotationStrategy}\n {...(pool.activeAccountId === undefined ? {} : { activeAccountId: pool.activeAccountId })}\n busy={busy}\n onLogin={() => void login()}\n onSetPrimary={(accountId) => void poolAction('set-primary', accountId)}\n onDelete={(accountId) => void poolAction('delete', accountId)}\n onClearCooldown={(accountId) => void poolAction('clear-cooldown', accountId)}\n // The account card renders its 重新登录 button only when this handler is\n // supplied, and every sibling line supplies one. Without it a MiniMax Code\n // account could be reported as needing a new sign-in with no way to act on\n // it — the badge appeared and no button ever did.\n onRelogin={(accountId) => void poolAction('relogin', accountId)}\n onSetStrategy={(strategy) => void setStrategy(strategy)}\n // Quota follows the account, so the host reports each account's own\n // newest snapshot and the card draws it inside that account's row.\n showQuota\n />\n )}\n\n {status?.checkin != null ? (\n <section className=\"dsha-group\">\n <div className=\"dsha-grouphead\">\n <h3>{t('dailyCheckin')}</h3>\n </div>\n <p className=\"dsha-muted\">{t('checkinHint')}</p>\n <div className=\"dsha-row\" style={{ marginBottom: 8 }}>\n <span className=\"dsha-label\" style={{ fontWeight: 600 }}>{t('checkinAuto')}</span>\n <input\n type=\"checkbox\"\n checked={status.checkin.enabled}\n disabled={busy !== null}\n onChange={(event) => void setCheckinEnabled(event.currentTarget.checked)}\n />\n </div>\n <div className=\"dsha-row\">\n <span className=\"dsha-label\">{t('dailyCheckin')}</span>\n <span className=\"dsha-value\">\n {t('checkinToday').replace('{done}', String(status.checkin.doneToday)).replace('{total}', String(status.checkin.totalAccounts))}\n {status.checkin.skippedToday > 0\n ? ` · ${t('checkinSkipped').replace('{count}', String(status.checkin.skippedToday))}`\n : ''}\n {status.checkin.failedToday > 0\n ? ` · ${t('checkinFailed').replace('{count}', String(status.checkin.failedToday))}`\n : ''}\n {status.checkin.streakDays !== undefined\n ? ` · ${t('checkinStreak').replace('{days}', String(status.checkin.streakDays))}`\n : ''}\n {status.checkin.claimedPoints !== undefined\n ? ` · ${t('checkinClaimed').replace('{points}', String(status.checkin.claimedPoints))}`\n : ''}\n {` · ${status.checkin.lastRunAt === null ? t('checkinNever') : t('checkinLastRun').replace('{time}', formatDate(status.checkin.lastRunAt))}`}\n </span>\n </div>\n <div className=\"dsha-actions\">\n <button className=\"dsha-btn\" disabled={busy !== null} onClick={() => void runCheckinNow()}>\n {busy === 'checkin' ? t('checkinRunning') : t('checkinNow')}\n </button>\n </div>\n </section>\n ) : null}\n\n <section className=\"dsha-group\">\n <div className=\"dsha-grouphead\">\n <h3>{t('account')}</h3>\n <span className=\"dsha-value\">{authenticated ? t('signedIn') : t('signedOut')}</span>\n </div>\n\n {authenticated && (\n <>\n <div className=\"dsha-row\">\n <span className=\"dsha-label\">{t('accountLabel')}</span>\n <span className=\"dsha-value\">{account?.label !== undefined && account.label !== '' ? account.label : t('unknown')}</span>\n </div>\n {account?.id !== undefined && account.id !== '' && (\n <div className=\"dsha-row\">\n <span className=\"dsha-label\">{t('accountId')}</span>\n <span className=\"dsha-value dshm-mono\">{account.id}</span>\n </div>\n )}\n {account?.email !== undefined && account.email !== '' && (\n <div className=\"dsha-row\">\n <span className=\"dsha-label\">{t('email')}</span>\n <span className=\"dsha-value\">{account.email}</span>\n </div>\n )}\n <div className=\"dsha-row\">\n <span className=\"dsha-label\">{t('expiresAt')}</span>\n <span className=\"dsha-value\">\n {formatDate(account?.expiresAtMs)}\n {hours === null\n ? ` · ${t('expiresExpired')}`\n : ` · ${t('expiresRemaining').replace('{hours}', hours)}`}\n </span>\n </div>\n </>\n )}\n\n {status !== null && (\n <>\n <div className=\"dsha-row\">\n <span className=\"dsha-label\">{t('region')}</span>\n <span className=\"dsha-value\">{status.region === 'global' ? t('regionGlobal') : t('regionCn')}</span>\n </div>\n <p className=\"dsha-notice\">{t('expiresHint')}</p>\n </>\n )}\n\n {flow !== null && (\n <div className=\"dsha-device-box\">\n <strong>{t('deviceCodeSection')}</strong>\n <p className=\"dsha-muted\">{t('deviceCodeHint')}</p>\n <div className=\"dsha-code-row\">\n <span className=\"dsha-code\" aria-label={t('userCode')}>{flow.userCode}</span>\n <button className=\"dsha-btn\" onClick={() => void copyCode()}>\n {copied ? t('copied') : t('copyCode')}\n </button>\n </div>\n {flow.verificationUri !== '' && (\n <a className=\"dsha-link\" href={flow.verificationUri} target=\"_blank\" rel=\"noreferrer noopener\">\n {flow.verificationUri}\n </a>\n )}\n <div className=\"dsha-row\">\n <span className=\"dsha-label\">{t('codeExpires')}</span>\n <span className=\"dsha-value\">\n {t('codeMinutes').replace('{minutes}', String(Math.max(1, Math.round(flow.expiresInSec / 60))))}\n </span>\n </div>\n <p className=\"dsha-muted\">{t('waitingAuthorization')}</p>\n <div className=\"dsha-actions\">\n {flow.verificationUri !== '' && (\n <a className=\"dsha-btn\" href={flow.verificationUri} target=\"_blank\" rel=\"noreferrer noopener\">\n {t('openSignInPage')}\n </a>\n )}\n <button className=\"dsha-btn\" onClick={() => void cancelLogin()}>\n {t('cancelSignIn')}\n </button>\n </div>\n </div>\n )}\n\n <div className=\"dsha-actions\">\n {flow === null && !authenticated && (\n <button className=\"dsha-btn dsha-btn-primary\" disabled={busy !== null} onClick={() => void login()}>\n {busy === 'login' ? t('signingIn') : t('signIn')}\n </button>\n )}\n {flow === null && authenticated && (\n // A native sign-in is the desktop app's, so this plugin cannot end it.\n // The button stays (hiding it would leave the user guessing where\n // sign-out went) but is disabled, and the reason is rendered as text\n // below rather than only as a tooltip: a disabled button does not fire\n // the hover events a tooltip needs, so a title alone would leave the\n // control unexplained.\n <button\n className=\"dsha-btn\"\n disabled={busy !== null || status?.ownedByPlugin === false}\n title={status?.ownedByPlugin === false ? t('logoutOwnedByApp') : undefined}\n onClick={() => void logout()}\n >\n {t('signOut')}\n </button>\n )}\n </div>\n {flow === null && authenticated && status?.ownedByPlugin === false && (\n <p className=\"dsha-muted\">{t('logoutOwnedByApp')}</p>\n )}\n </section>\n\n <section className=\"dsha-group\">\n <div className=\"dsha-grouphead\">\n <h3>{t('connection')}</h3>\n </div>\n {/* The provider id is contended like every sibling line's, so the same\n notice they render is rendered here: a user whose models are served by\n another adapter must be told that, not shown \"connected\" for a route\n this plugin does not own. */}\n <p className=\"dsha-notice\">\n {status?.serving === false && status.conflict\n ? t('routeConflict').replace('{detail}', status.conflict)\n : t('routeOwned')}\n </p>\n {connectionNotice !== null && <p className=\"dsha-muted\">{connectionNotice}</p>}\n <div className=\"dsha-actions\">\n <button\n className=\"dsha-btn\"\n disabled={busy !== null || !authenticated}\n onClick={() => void testConnection()}\n >\n {busy === 'test' ? t('testingConnection') : t('testConnection')}\n </button>\n </div>\n </section>\n\n <section className=\"dsha-group\">\n <div className=\"dsha-grouphead\">\n <h3>{t('modelsSection')}</h3>\n </div>\n <p className=\"dsha-muted\">{t('modelsHint').replace('{count}', String(models.length))}</p>\n {models.length === 0\n ? <div className=\"dsha-empty\">{t('modelsUnavailable')}</div>\n : (\n <ModelChecklist\n items={models.map((model: MinimaxCodeModelOption) => ({\n id: model.id,\n name: model.name,\n hint: [\n thinkingLabel(model.thinking, t),\n ...(model.description === null || model.description === '' ? [] : [model.description]),\n ].join(' · ') || undefined,\n enabled: model.enabled,\n }))}\n busy={busy !== null}\n onToggle={toggleModel}\n onToggleAll={setAllModels}\n labels={{ selectAll: t('selectAll'), clearAll: t('unselectAll'), list: t('modelsSection') }}\n />\n )}\n </section>\n\n <section className=\"dsha-group\">\n <div className=\"dsha-grouphead\">\n <h3>{t('enhanced')}</h3>\n </div>\n <div className=\"dsha-pref-row\">\n <div>\n <strong>{t('defaultReasoningEffort')}</strong>\n <p className=\"dsha-muted\">{t('defaultReasoningEffortHint')}</p>\n </div>\n <select\n className=\"dsha-select\"\n aria-label={t('defaultReasoningEffort')}\n value={status?.defaultReasoningEffort ?? ''}\n disabled={busy !== null}\n onChange={(event) => {\n const value = event.currentTarget.value\n void updateEffort(value === '' ? null : (value as MinimaxCodeReasoningEffort))\n }}\n >\n <option value=\"\">{t('defaultEffortAuto')}</option>\n {MINIMAX_CODE_REASONING_EFFORTS.map((effort) => (\n <option key={effort} value={effort}>{effort}</option>\n ))}\n </select>\n </div>\n </section>\n\n <section className=\"dsha-group\">\n <div className=\"dsha-grouphead\">\n <h3>{t('contextWindowSection')}</h3>\n </div>\n <p className=\"dsha-muted\">{t('contextWindowHint')}</p>\n <ContextWindowEditor\n rows={contextModels.map((model: MinimaxCodeModelOption) => ({\n id: model.id,\n name: model.name,\n draft: contextDrafts[model.id] ?? '',\n meta: model.defaultContextWindow < model.contextWindow\n ? formatCapacity(model.contextWindow)\n : undefined,\n inputLabel: `${model.name} ${t('contextWindowSection')}`,\n hasOverride: status?.contextWindowOverrides[model.id] !== undefined,\n saving: savingModel === model.id,\n }))}\n labels={{\n tokens: t('tokens'),\n save: t('save'),\n saving: t('saving'),\n reset: t('contextWindowReset'),\n resetAll: t('contextWindowResetAll'),\n empty: t('contextWindowNoneEnabled'),\n }}\n busy={busy !== null}\n overrideCount={overrideCount}\n metaClassName=\"dsha-model-meta\"\n onDraftChange={(id, draft) => updateContextDraft(id, draft)}\n onCommit={(id) => void saveContextWindow(id)}\n onReset={(id) => void resetContextWindow(id)}\n onResetAll={() => void resetAllContextWindows()}\n />\n </section>\n\n <section className=\"dsha-group\">\n <div className=\"dsha-grouphead\">\n <h3>{t('quotaSection')}</h3>\n <button\n className=\"dsha-btn\"\n disabled={busy !== null || !authenticated}\n onClick={() => void refreshQuota()}\n >\n {busy === 'quota' ? t('quotaRefreshing') : t('quotaRefresh')}\n </button>\n </div>\n {/*\n The progress bars moved into each account card: quota follows the\n account, so a bar here could only ever describe whichever account\n happened to be active when the snapshot was read. What stays is what has\n no per-account bar to live in — the plan, each window's name with its\n counts and reset moment, the freshness of this reading, and the stale\n flag — and the note below says which account those facts describe.\n */}\n <p className=\"dsha-muted\">{t('quotaFactsScope')}</p>\n {quota === undefined\n ? (\n // The contract makes quota optional and the usage read is allowed to\n // fail, so the section explains itself rather than rendering an empty\n // meter. The host separates the refusal worth acting on (this\n // sign-in's credential type cannot read usage at all) from an endpoint\n // that merely did not answer, and each gets its own sentence.\n <p className=\"dsha-notice dshm-quota-note\">\n {status?.quotaUnavailable === 'credential-not-accepted'\n ? t('quotaNeedsApiKey')\n : status?.quotaUnavailable === 'unreachable'\n ? t('quotaUnreachable')\n : status?.quotaUnavailable === 'token-expired'\n ? t('quotaTokenExpired')\n : t('quotaUnavailable')}\n </p>\n )\n : (\n <div className=\"dsha-quota-card\">\n <div className=\"dsha-quota-title\">\n <strong>{quota.label}</strong>\n {quota.usedPercent !== undefined && (\n <span>{t('quotaUsedShare').replace('{percent}', String(Math.round(quota.usedPercent)))}</span>\n )}\n </div>\n {/* The per-window rows are gone: each window's remaining share, its\n counts and its reset moment are drawn on the account card that\n owns the snapshot. The card title above stays because the\n aggregate share has no per-account home. */}\n {/*\n The last read failed but the host is still serving the numbers that\n last parsed. Showing them WITH that qualification beats the old\n behaviour of replacing a working quota box with a sentence that\n read like a sign-in prompt.\n */}\n {status?.quotaUnavailable === 'stale' && (\n <p className=\"dsha-notice dshm-quota-note\">{t('quotaStale')}</p>\n )}\n </div>\n )}\n </section>\n\n {error !== null && (\n <div className=\"dsha-error\">\n <div>{error}</div>\n </div>\n )}\n </div>\n )\n}\n","/**\n * Wire contracts between the Claude subscription host routes and the browser\n * settings card. Everything here is public: NO CREDENTIAL EVER CROSSES THIS\n * BOUNDARY, and no shape below has a field a token could live in.\n *\n * ---------------------------------------------------------------------------\n * THE ONE RULE THIS FILE OBEYS, AND WHY IT IS NOT NEGOTIABLE\n * ---------------------------------------------------------------------------\n *\n * **Nothing in this file may resolve a module under 'src/host/'.** Not a value\n * import, not an `import type`, not an `export type … from`.\n *\n * This file is compiled by TWO projects with different worlds:\n *\n * - the host project ('tsconfig.host.json'): Node types, and 'src/host/**' in\n * its include list;\n * - the client project ('tsconfig.client.json'): NO 'types' at all, and\n * 'src/host/**' deliberately absent from its include list.\n *\n * The second one is the constraint. A type-only import is ERASED for emit but\n * still RESOLVED for checking, so a single `import type` of\n * '../host/claude/account-pool.ts' from here pulls that whole subtree —\n * node:path, node:fs, node:http, node:crypto — into the client program. It does\n * not degrade quietly; it fails the build:\n *\n * src/host/claude/account-pool.ts(104,18): error TS2307:\n * Cannot find module 'node:path' or its corresponding type declarations.\n * src/host/claude/account-pool.ts(105,28): error TS6307:\n * File '…/src/host/common/home.ts' is not listed within the file list of\n * project '…/tsconfig.client.json'.\n *\n * That was measured, not assumed: `npx tsc -p tsconfig.client.json` exits 0\n * with this file absent and exits 2 with a single type-only host re-export in\n * it. So the boundary is a property of the build, and this file is on the public\n * side of it.\n *\n * ---------------------------------------------------------------------------\n * THE TWO CONSEQUENCES, STATED PLAINLY RATHER THAN HIDDEN\n * ---------------------------------------------------------------------------\n *\n * 1. {@link ClaudeAccountSummaryDto} is DECLARED here rather than re-exported\n * from 'src/host/claude/account-pool.ts', which is where the pool chunk put\n * it. A re-export is what this file would prefer — and it is what the task\n * asked for — but it cannot compile, for the reason above.\n *\n * The drift that risks is closed from the OTHER side instead:\n * 'src/host/claude/routes.ts' imports BOTH declarations and carries a\n * compile-time assertion that each is assignable to the other. Adding a field\n * to the pool's copy without adding it here is therefore a build failure in\n * `npx tsc -p tsconfig.host.json` — the same protection a re-export would\n * have given, minus the impossible direction.\n *\n * 2. {@link CLAUDE_REASONING_EFFORTS} cannot be DERIVED from the catalog's\n * ladders by an indexed access, for the same reason. It is a literal, and the\n * equivalence between it and the catalog is asserted at the bottom of\n * 'src/host/claude/routes.ts' — against the real `CLAUDE_MODELS` table, in\n * the project that can read it. Adding a level to a catalog ladder without\n * adding it here stops the host typecheck, so the card cannot silently omit a\n * level the wire would accept.\n *\n * Both assertions live in the host project because that is the only project that\n * can see both sides. Neither is documentation: each is a line of TypeScript\n * whose deletion is the only way to make it stop working.\n */\n\nimport type { AccountPoolStatusDto, AccountRotationStrategy, PoolAccountSummaryDto } from './account-pool-contracts.ts'\n\n/**\n * How a model wants its thinking block shaped on the wire.\n *\n * Restated here rather than indexed off `ClaudeModelEntry` — see the module\n * comment. These four are not a quality ordering: 'mid-convo' and 'adaptive' are\n * different wire SHAPES, and the first is checked before every other branch\n * because a managed-effort model needs `block_binding` and `output_config`\n * or it answers with persistent 400s.\n *\n * The equivalence with the catalog's own `thinkingMode` field is asserted in\n * 'src/host/claude/routes.ts'.\n */\nexport type ClaudeThinkingMode = 'mid-convo' | 'adaptive' | 'budget' | 'none'\n\n/**\n * Every thinking level this route can name, in escalating order.\n *\n * The union of the whole shipped catalog rather than one model's ladder: these\n * are WIRE effort values, already collapsed by the upstream reference mapping\n * the frozen catalog transcribes ('minimal' and 'low' both send 'low', so\n * offering both would advertise a distinction the wire cannot make). The card\n * offers them as default-effort choices and narrows the dropdown per model with\n * {@link ClaudeModelOption.reasoningEfforts}.\n *\n * 'off' is deliberately absent, exactly as it is from every ladder in the\n * catalog: turning thinking off is the ABSENCE of a thinking block rather than\n * an effort level, and whether a model permits it is stated separately in\n * {@link ClaudeModelOption.canDisableThinking}.\n *\n * NOT derived from the catalog by an indexed access — the client project cannot\n * read that module. The equivalence is asserted against the real table in\n * 'src/host/claude/routes.ts'; see the module comment.\n */\nexport const CLAUDE_REASONING_EFFORTS = ['low', 'medium', 'high', 'xhigh', 'max'] as const\n\n/** One selectable thinking level. */\nexport type ClaudeReasoningEffort = (typeof CLAUDE_REASONING_EFFORTS)[number]\n\n/**\n * Whether a posted value is one of the levels this route can name.\n *\n * The membership test every settings route in this plugin performs against its\n * own constant, so a level no ladder carries is refused at the wire boundary\n * instead of being persisted and converged later.\n */\nexport function isClaudeReasoningEffort(value: unknown): value is ClaudeReasoningEffort {\n return typeof value === 'string' && (CLAUDE_REASONING_EFFORTS as readonly string[]).includes(value)\n}\n\n/**\n * Prompt-cache TTL the subscription route can request.\n *\n * `null` in the settings means \"follow the official subscription client\", which\n * asks for the one-hour tier while a plan is drawing on included usage.\n */\nexport type ClaudeCacheTtl = '5m' | '1h'\n\n/**\n * Whether a posted value names a tier this route can send.\n *\n * Membership is checked at the wire boundary for the same reason effort levels\n * are: the one-hour tier is a LICENSED capability, so a value that reached the\n * body without the matching beta would be refused by the service.\n */\nexport function isClaudeCacheTtl(value: unknown): value is ClaudeCacheTtl {\n return value === '5m' || value === '1h'\n}\n\n/** One model offered by the Claude subscription route. */\nexport interface ClaudeModelOption {\n id: string\n name: string\n /** Enabled models are the ones DSH offers in the conversation model picker. */\n enabled: boolean\n /** Context window this route assumes when the card saves no override. */\n defaultContextWindow: number\n /** Effective context window: the override when one is saved, else the default. */\n contextWindow: number\n /** Maximum output tokens this route requests when a caller omits one. */\n defaultMaxTokens: number\n /** Thinking levels this model exposes; empty for a model that takes none. */\n reasoningEfforts: string[]\n /**\n * Whether thinking can be turned off for this model.\n *\n * Reported because it is NOT derivable from {@link reasoningEfforts}: a model\n * the catalog maps `off: null` has a full ladder and still refuses to stop\n * thinking, and a card that offered the switch anyway would send a request the\n * wire rejects.\n */\n canDisableThinking: boolean\n /** Which thinking form this model needs; see {@link ClaudeThinkingMode}. */\n thinkingMode: ClaudeThinkingMode\n /** Whether the model accepts image input on this route. */\n supportsImage: boolean\n /** Whether the model accepts a `temperature` at all. */\n supportsTemperature: boolean\n}\n\n/**\n * One quota window, as the usage endpoint or the response headers stated it.\n *\n * The three numeric fields are null TOGETHER: null means \"the source did not\n * say\", which is a different statement from 0. A card that rendered null as 0\n * would show \"nothing used\" for a window nobody measured.\n */\nexport interface ClaudeQuotaWindow {\n /** Wire key: `five_hour`, `seven_day`, `seven_day_sonnet`. */\n id: string\n label: string\n /** Nominal length of the window in minutes, or null when unknown. */\n windowMinutes: number | null\n /** Fraction of the window consumed, 0-1. */\n usedFraction: number | null\n /** The same number as a percent, 0-100. */\n usedPercent: number | null\n /** Percent still available, 0-100. */\n remainingPercent: number | null\n /** ISO 8601 instant the window resets, or null. */\n resetsAt: string | null\n /** Which source these numbers came from, for the card's footnote. */\n source: 'usage' | 'headers'\n}\n\n/** One credit / usage meter the account carries beside its windows. */\nexport interface ClaudeMeter {\n id: string\n label: string\n /** Percent of the allowance consumed, 0-100. Null when the source said nothing. */\n usedPercent: number | null\n /** Percent still available, 0-100. Null when the source said nothing. */\n remainingPercent: number | null\n /** Monthly limit, in the account's own unit, when stated. */\n limit: number | null\n /** Amount consumed, in the same unit, when stated. */\n used: number | null\n /** Whether this meter is switched on for the account. */\n enabled: boolean\n}\n\n/** One point-in-time quota snapshot for the account the card displays. */\nexport interface ClaudeAccountQuota {\n /** Every window the account currently has, shortest first. */\n windows: ClaudeQuotaWindow[]\n /** Pay-as-you-go overage pool, when the account has one. */\n extraUsage: ClaudeMeter | null\n /** Unix milliseconds of the last successful FULL usage read; null if none. */\n fetchedAt: number | null\n /** Unix milliseconds of the most recent update from any source. */\n observedAt: number\n /** Unified rate-limit verdict the headers last reported, when they did. */\n status: string | null\n /** Window the headers last named as representative, when they did. */\n representativeClaim: string | null\n}\n\n/**\n * Account identity as the settings card renders it.\n *\n * There is no bearer field and no token: the identity this line can state from a\n * credential alone is exactly what the exchange reported — an address and a tier\n * — and everything else the card shows about WHO is signed in comes from the\n * account list.\n */\nexport interface ClaudeAccount {\n /** Address the sign-in reported, when it reported one. */\n email: string | null\n /** Subscription tier the exchange reported, verbatim ('max', 'pro', …). */\n subscriptionType: string | null\n}\n\n/**\n * One Claude account as the shared pool card renders it. Never carries a token.\n *\n * DECLARED here rather than re-exported from 'src/host/claude/account-pool.ts';\n * see the module comment for the measured reason. The two are kept identical by\n * the compile-time assertion in 'src/host/claude/routes.ts'.\n */\nexport interface ClaudeAccountSummaryDto extends PoolAccountSummaryDto {\n /** Where the credential came from; a card offers different actions per source. */\n source?: 'managed' | 'claude-code'\n /** Whether this row is a snapshot borrowed from a local Claude Code sign-in. */\n adopted?: boolean\n /** The Claude Code file an adopted snapshot was read from. */\n sourcePath?: string\n /** Subscription tier, from the credential itself. */\n subscriptionType?: string\n}\n\n/** Everything the settings card and the composer badge render. */\nexport interface ClaudeWebStatus extends Partial<AccountPoolStatusDto> {\n enabled?: boolean\n authenticated: boolean\n hasCredentials: boolean\n /** Storage description for this line's encrypted credential store. */\n storagePath: string\n /** Whether this plugin currently owns the provider route. */\n serving: boolean\n /** Diagnostic when another adapter family owns the provider route. */\n conflict: string | null\n /**\n * Whether a local Claude Code sign-in exists to offer for adoption.\n *\n * Answered by a stat and NOT by a read (see 'src/host/claude/adopt.ts'), so\n * the card can offer the import before anything has been read from the file.\n */\n claudeCodeSignInAvailable: boolean\n /** Paths the adoption reader consulted, whether or not each existed. */\n claudeCodePaths: string[]\n /** Account the displayed credential belongs to. */\n account: ClaudeAccount | null\n quota: ClaudeAccountQuota | null\n lastFetchedAt: number | null\n /**\n * Whether a quota refresh is running behind this answer.\n *\n * The card renders the snapshot it already had instead of waiting on the\n * upstream request; when this is true the client asks again shortly so the\n * refreshed snapshot reaches the UI.\n */\n quotaRefreshing?: boolean\n /** Why the last quota read failed, when it did. Reported BESIDE the snapshot. */\n quotaError?: string | null\n models: ClaudeModelOption[]\n contextWindowOverrides: Record<string, number>\n defaultReasoningEffort: ClaudeReasoningEffort | null\n /** Prompt-cache tier; `null` means \"follow the official subscription default\". */\n cacheTtl: ClaudeCacheTtl | null\n /** Account selected for catalog, quota and all requests; null means automatic. */\n selectedAccountId: string | null\n /** Signed-in accounts; empty or absent when no pool is installed. */\n accounts?: ClaudeAccountSummaryDto[]\n /** Account the next request would use. */\n activeAccountId?: string\n rotationStrategy?: AccountRotationStrategy\n}\n\n/** Patch accepted by the models/settings route. */\nexport interface ClaudeSettingsUpdateDto {\n enabled?: boolean\n enabledModelIds?: string[]\n /** A number sets an override for that model; `null` restores the default. */\n contextWindowOverrides?: Record<string, number | null>\n defaultReasoningEffort?: ClaudeReasoningEffort | null\n /** `null` restores the subscription default. */\n cacheTtl?: ClaudeCacheTtl | null\n selectedAccountId?: string | null\n}\n\n/** One account-pool action the card can post. */\nexport type ClaudeAccountAction =\n | 'set-primary'\n | 'set-alias'\n | 'delete'\n | 'clear-cooldown'\n | 'clear-auth-failed'\n | 'relogin'\n | 'strategy'\n\n/** Body accepted by the accounts route. */\nexport interface ClaudeAccountActionDto {\n action: ClaudeAccountAction\n accountId?: string\n alias?: string\n strategy?: AccountRotationStrategy\n}\n\n/**\n * Result of an explicit connection test.\n *\n * A failure is a VALUE rather than a thrown error, because the card's whole job\n * here is to render the reason: a probe that was refused is a fact about the\n * credential, not a failed request.\n */\nexport interface ClaudeConnectionDto {\n connected: boolean\n /** Model the probe asked for. */\n model: string\n /** Round-trip time of the probe request, in milliseconds. */\n latencyMs: number\n /** HTTP status the probe received; 0 when no response arrived at all. */\n status: number\n /** Why the probe did not connect, when it did not. */\n error: string | null\n /** Whether repeating the same probe could succeed. */\n retryable: boolean\n /** `stop_reason` of the one-token answer, when one arrived. */\n stopReason: string | null\n checkedAt: number\n}\n\n/**\n * Live state of the sign-in flow the card polls.\n *\n * This restates 'src/host/claude/oauth.ts''s `LoginFlowStatus` field for field,\n * and the restatement is deliberate rather than lazy: that object is serialized\n * straight into the HTTP response, and its own comment records that no secret\n * has a field to live in. Renaming a field here cannot leak anything — the host\n * serializes its own object — but it CAN make the card read a field the host\n * never sends, so the two are kept in step by eye and by the tests that drive\n * the real flow.\n */\nexport interface ClaudeLoginFlowDto {\n status: 'idle' | 'pending' | 'exchanging' | 'complete' | 'error'\n /** Correlates a status reading with the flow the user started. */\n flowId?: string\n /** Not a secret: it is the value that goes INTO the browser. */\n authUrl?: string\n mode?: 'manual' | 'loopback'\n /** Which redirect URI is armed, for the card to display. */\n redirectUri?: string\n hint?: string\n error?: string\n /** Why a loopback attempt degraded to manual. */\n fallbackReason?: string\n createdAt?: number\n completedAt?: number\n}\n","import { accountPoolEn, accountPoolZh } from '../common/account-pool-labels.ts'\n\n/**\n * Locale namespace of the Claude subscription tab.\n *\n * Its own namespace rather than the hub's, so a missing string surfaces as this\n * dictionary's key rather than as a wrong sentence borrowed from another\n * provider — the same reason every sibling line has one.\n */\nexport const NS_CLAUDE = 'dsh-claude'\n\nexport const zh = {\n // The account-management card is shared with every other provider tab.\n ...accountPoolZh,\n title: 'Claude(订阅)',\n pageDesc: '登录 Claude Pro/Max 订阅,管理模型、思考档位、上下文窗口与额度。',\n\n // --- Account card ---\n account: '账号',\n signedIn: '已登录',\n signedOut: '未登录',\n email: '邮箱',\n plan: '套餐',\n planUnknown: '—',\n subscriptionType: '订阅类型',\n source: '来源',\n sourceManaged: '本插件登录',\n sourceClaudeCode: '本机 Claude Code',\n adoptedBadge: '导入的快照',\n\n // --- Sign-in flow ---\n signIn: '登录 Claude 账号',\n signInSection: '登录授权',\n signInAgain: '重新登录',\n signingIn: '正在发起登录...',\n cancelSignIn: '取消登录',\n openAuthorizeUrl: '打开授权页面',\n authorizeUrl: '授权链接',\n redirectUri: '回调地址',\n loginModeManual: '当前是手动模式:浏览器回调不可用,授权完成后把页面上的 code 粘贴到下方输入框。',\n loginModeLoopback: '当前是本地回环模式:浏览器授权完成后会自动回到本机回调地址。',\n loginFallbackReason: '本地回环模式不可用,已降级为手动模式:{detail}',\n loginWaiting: '等待浏览器中的授权完成...',\n loginExchanging: '正在交换令牌...',\n loginComplete: '登录完成',\n loginFailed: '登录失败',\n manualPasteSection: '手动粘贴授权码',\n manualPasteHint: '把浏览器地址栏里的 code(或整段回调 URL)粘贴到这里完成登录。手动模式下没有浏览器回调,这里是唯一的入口。',\n manualPastePlaceholder: 'code#state 或完整的回调 URL',\n manualPasteSubmit: '提交授权码',\n manualPasteSubmitting: '提交中...',\n\n // --- Adoption of the local Claude Code sign-in ---\n importClaudeCode: '导入本机 Claude Code 登录态',\n importing: '导入中...',\n stopImporting: '停止导入',\n // Only the button's own labels live here now. The prose that used to sit under\n // the pool — what the import does, whether one was found, where it looked — was\n // removed: the button already names the action, and a click with no sign-in\n // present returns the host's own sentence in the card's error strip, so the\n // three paragraphs described a state the control itself already reports.\n\n // --- Connection ---\n connection: '连接',\n testConnection: '测试连接',\n testingConnection: '测试中...',\n testSuccess: '连接正常',\n testLatency: '往返 {ms} ms',\n testFailed: '连接失败:{detail}',\n testRetryable: '可重试',\n testNotRetryable: '不可重试',\n routeOwned: '模型路由由本插件提供',\n routeConflict: '模型路由已被其他 Provider 占用:{detail}。请在 DSH 设置中移除重复的 Provider 配置后重试。',\n\n // --- Models ---\n modelsSection: '模型',\n modelsHint: '勾选后模型才会出现在对话页的模型选择列表中。',\n refreshCatalog: '刷新模型目录',\n refreshingCatalog: '刷新中...',\n selectAll: '全选',\n unselectAll: '全不选',\n capImage: '图片',\n capNoImage: '仅文本',\n capThinkingOff: '可关闭思考',\n thinkingModeMidConvo: '多轮思考',\n thinkingModeAdaptive: '自适应思考',\n thinkingModeBudget: '预算思考',\n thinkingModeNone: '无思考',\n\n // --- Thinking ---\n enhanced: '思考设置',\n defaultReasoningEffort: '默认思考档位',\n defaultReasoningEffortHint: '下拉列出的是目录中出现过的全部档位(含 xhigh);每个模型真正支持的档位见下方列表,Host 按模型自身的阶梯发送。',\n defaultEffortAuto: '使用模型默认值',\n cacheTtl: '提示缓存时长',\n cacheTtlHint: 'Anthropic 提供 5 分钟与 1 小时两档。订阅用户在套餐额度内,官方 Claude Code 对主对话默认使用 1 小时;超出额度改按用量计费后官方会降回 5 分钟。1 小时写入更贵,短会话不划算。',\n cacheTtlSubscription: '跟随官方(订阅默认 1 小时)',\n cacheTtl1h: '1 小时',\n cacheTtl5m: '5 分钟',\n effortLow: '低 (low)',\n effortMedium: '中 (medium)',\n effortHigh: '高 (high)',\n effortXHigh: '极高 (xhigh)',\n effortMax: '最高 (max)',\n modelLadders: '各模型支持的档位',\n modelLadderNone: '该模型不接受思考档位',\n\n // --- Context windows ---\n contextWindowSection: '模型上下文窗口',\n contextWindowHint: '默认取模型目录的上下文长度,保存过的覆盖值优先。恢复默认会让 Host 删掉这条覆盖值,重新回到目录值。',\n contextWindowReset: '恢复默认',\n contextWindowResetAll: '全部恢复默认',\n contextWindowResetAllConfirm: '确定把已改过的模型上下文窗口全部恢复为默认值吗?',\n contextWindowNoneEnabled: '还没有勾选任何模型。在上方勾选后,这里会出现该模型的上下文窗口设置。',\n contextWindowInvalid: '上下文长度无效:{value}',\n save: '保存',\n saving: '保存中...',\n tokens: 'tokens',\n\n // --- Quota ---\n quotaSection: '用量与额度',\n quotaDesc: '数据来自 Claude 用量接口与响应头;页面可见时最多每 60 秒刷新一次。utilization 是「已用百分比」,所以 0% 已用是正常的空用量状态。',\n refreshQuota: '刷新用量',\n refreshingQuota: '刷新中...',\n quotaRefreshing: 'Host 正在后台刷新额度,稍后会自动更新。',\n quotaEmpty: '暂无配额数据,点击「刷新用量」重试。',\n quotaSignedOut: '未登录,无法读取用量。',\n quotaUnknown: '—',\n quotaUnknownHint: 'Host 没有给出这个窗口的数值,这里不显示为 0。',\n usedLabel: '已用',\n remainingLabel: '剩余',\n left: '可用',\n resetAt: '重置:{time}',\n resetUnknown: '重置时间未知',\n updatedAt: '更新时间:{time}',\n observedAt: '最近观察:{time}',\n quotaError: '额度读取失败',\n extraUsage: '额外用量',\n extraUsageEnabled: '已开启',\n extraUsageDisabled: '未开启',\n extraUsageLimit: '月度上限',\n sourceUsage: '来源:用量接口',\n sourceHeaders: '来源:响应头',\n quotaStatus: '限流状态',\n quotaRepresentative: '代表性窗口',\n\n loading: '加载中...',\n now: '即将重置',\n copy: '复制',\n copied: '已复制',\n} as const\n\nexport const en: Record<keyof typeof zh, string> = {\n ...accountPoolEn,\n title: 'Claude (subscription)',\n pageDesc: 'Sign in to a Claude Pro/Max subscription and manage models, thinking levels, context windows and quota.',\n\n account: 'Account',\n signedIn: 'Signed in',\n signedOut: 'Not signed in',\n email: 'Email',\n plan: 'Plan',\n planUnknown: '—',\n subscriptionType: 'Subscription',\n source: 'Source',\n sourceManaged: 'Signed in here',\n sourceClaudeCode: 'Local Claude Code',\n adoptedBadge: 'Imported snapshot',\n signIn: 'Sign in to Claude',\n signInSection: 'Sign-in',\n signInAgain: 'Sign in again',\n signingIn: 'Starting the sign-in...',\n cancelSignIn: 'Cancel',\n openAuthorizeUrl: 'Open the authorization page',\n authorizeUrl: 'Authorization URL',\n redirectUri: 'Redirect URI',\n loginModeManual: 'Manual mode: there is no browser callback, so paste the code shown after authorizing into the box below.',\n loginModeLoopback: 'Loopback mode: the browser returns to the local callback automatically after you authorize.',\n loginFallbackReason: 'Loopback was unavailable and the flow degraded to manual: {detail}',\n loginWaiting: 'Waiting for the browser to finish authorizing...',\n loginExchanging: 'Exchanging the token...',\n loginComplete: 'Signed in',\n loginFailed: 'Sign-in failed',\n manualPasteSection: 'Paste the authorization code',\n manualPasteHint: 'Paste the code from the browser address bar (or the whole callback URL) here to finish signing in. In manual mode there is no browser callback, so this box is the only way through.',\n manualPastePlaceholder: 'code#state or the full callback URL',\n manualPasteSubmit: 'Submit code',\n manualPasteSubmitting: 'Submitting...',\n\n importClaudeCode: 'Import the local Claude Code sign-in',\n importing: 'Importing...',\n stopImporting: 'Stop importing',\n // Only the button's own labels live here now. The prose that used to sit under\n // the pool — what the import does, whether one was found, where it looked — was\n // removed: the button already names the action, and a click with no sign-in\n // present returns the host's own sentence in the card's error strip, so the\n // three paragraphs described a state the control itself already reports.\n\n connection: 'Connection',\n testConnection: 'Test connection',\n testingConnection: 'Testing...',\n testSuccess: 'Connection OK',\n testLatency: 'round trip {ms} ms',\n testFailed: 'Connection failed: {detail}',\n testRetryable: 'retryable',\n testNotRetryable: 'not retryable',\n routeOwned: 'This plugin serves the model route',\n routeConflict: 'Another provider already owns the model route: {detail}. Remove the duplicate provider configuration in DSH settings and retry.',\n\n modelsSection: 'Models',\n modelsHint: 'Checked models appear in the DSH conversation model list.',\n refreshCatalog: 'Refresh catalog',\n refreshingCatalog: 'Refreshing...',\n selectAll: 'Select all',\n unselectAll: 'Deselect all',\n capImage: 'Images',\n capNoImage: 'Text only',\n capThinkingOff: 'Thinking can be turned off',\n thinkingModeMidConvo: 'Mid-conversation thinking',\n thinkingModeAdaptive: 'Adaptive thinking',\n thinkingModeBudget: 'Budgeted thinking',\n thinkingModeNone: 'No thinking',\n\n enhanced: 'Thinking',\n defaultReasoningEffort: 'Default thinking level',\n defaultReasoningEffortHint: 'The list is every level the catalog names (xhigh included); the per-model ladder is listed below, and the Host sends what that model itself accepts.',\n cacheTtl: 'Prompt cache duration',\n cacheTtlHint: 'Anthropic offers 5-minute and 1-hour tiers. While a subscription is drawing on included plan usage, the official Claude Code uses the hour for the main conversation; once the plan is exhausted and requests bill against usage credits, it drops back to five minutes. A 1-hour write costs more, so it does not pay off for short sessions.',\n cacheTtlSubscription: 'Follow the official (subscription default 1h)',\n cacheTtl1h: '1 hour',\n cacheTtl5m: '5 minutes',\n defaultEffortAuto: 'Use the model default',\n effortLow: 'Low',\n effortMedium: 'Medium',\n effortHigh: 'High',\n effortXHigh: 'X-High',\n effortMax: 'Max',\n modelLadders: 'Per-model levels',\n modelLadderNone: 'This model accepts no thinking level',\n\n contextWindowSection: 'Model context window',\n contextWindowHint: 'Defaults to the catalog context length; a saved override wins. Restoring the default makes the Host delete that override and fall back to the catalog value.',\n contextWindowReset: 'Restore default',\n contextWindowResetAll: 'Restore all defaults',\n contextWindowResetAllConfirm: 'Restore every changed model context window to its default?',\n contextWindowNoneEnabled: 'No model is checked yet. Check one above and its context window setting appears here.',\n contextWindowInvalid: 'Invalid context capacity: {value}',\n save: 'Save',\n saving: 'Saving...',\n tokens: 'tokens',\n\n quotaSection: 'Usage & quota',\n quotaDesc: 'Read from the Claude usage endpoint and response headers; refreshes at most once every 60 seconds while visible. utilization is PERCENT USED, so 0% used is the normal empty state.',\n refreshQuota: 'Refresh quota',\n refreshingQuota: 'Refreshing...',\n quotaRefreshing: 'The Host is refreshing the quota in the background; the numbers update shortly.',\n quotaEmpty: 'No quota data yet — use \"Refresh quota\" to retry.',\n quotaSignedOut: 'Not signed in, so usage cannot be read.',\n quotaUnknown: '—',\n quotaUnknownHint: 'The Host did not state a number for this window, so none is shown instead of a zero.',\n usedLabel: 'Used',\n remainingLabel: 'Remaining',\n left: 'left',\n resetAt: 'Reset: {time}',\n resetUnknown: 'reset time unknown',\n updatedAt: 'Updated at: {time}',\n observedAt: 'Last observed: {time}',\n quotaError: 'Quota read failed',\n extraUsage: 'Extra usage',\n extraUsageEnabled: 'enabled',\n extraUsageDisabled: 'disabled',\n extraUsageLimit: 'Monthly limit',\n sourceUsage: 'Source: usage endpoint',\n sourceHeaders: 'Source: response headers',\n quotaStatus: 'Rate-limit status',\n quotaRepresentative: 'Representative window',\n\n loading: 'Loading...',\n now: 'now',\n copy: 'Copy',\n copied: 'Copied',\n} as const\n\nexport const dictionaries = {\n zh,\n 'zh-CN': zh,\n en,\n 'en-US': en,\n}\n\nexport type ClaudeLocaleKey = keyof typeof zh\n","/**\n * The Claude card's state, effects and actions.\n *\n * Split out of 'ClaudeSection.tsx' so that file is markup and this one is\n * behaviour: what the card tracks, what it derives from a status answer, and\n * every request a control can make. The view reads one named shape — see\n * `ClaudeSectionView` — so the contract between the two is visible here rather\n * than inferred from a thousand lines of JSX.\n */\nimport { useCallback, useEffect, useRef, useState } from 'react'\nimport type { AccountRotationStrategy } from '../../shared/account-pool-contracts.ts'\nimport type {\n ClaudeAccountQuota,\n ClaudeAccountSummaryDto,\n ClaudeCacheTtl,\n ClaudeConnectionDto,\n ClaudeLoginFlowDto,\n ClaudeModelOption,\n ClaudeQuotaWindow,\n ClaudeReasoningEffort,\n ClaudeWebStatus,\n} from '../../shared/claude-contracts.ts'\nimport { contextDraftsFor } from '../common/ContextWindowEditor.tsx'\nimport { formatCapacity, parsePositiveCapacity } from '../common/format.ts'\nimport { createLineApi } from '../common/line-api.ts'\nimport { createQuotaFollowUp, type QuotaFollowUp } from '../common/quota-follow-up.ts'\nimport { zh } from './locales.ts'\n\nconst API = '/claude/api'\nconst api = createLineApi(API, 'Claude')\n\n/**\n * The poll cadence of a pending sign-in.\n *\n * There is NO SSE channel in this plugin — every sibling line polls\n * 'login/status' on a timer while the user is in the browser, and this one does\n * the same so a stalled flow is visible rather than silent.\n */\nconst LOGIN_POLL_MS = 2000\n\n/** The seats the settings hub hands the card; both optional, so a bare render works. */\nexport interface ClaudeSectionProps {\n onModelChange?: () => void\n loadModelDirectory?: () => void\n}\n\n/**\n * Everything the card's view consumes, grouped by kind.\n *\n * Returned as one named shape instead of one status blob: a reader can see at a\n * glance what the hook tracks, what it computes from a status answer, and what\n * the view is allowed to ask it to do.\n */\nexport interface ClaudeSectionView {\n /** Values that change as the card runs. */\n state: {\n /** Last status answer; null until the first read lands. */\n status: ClaudeWebStatus | null\n /** True until the first status read settles, whatever its outcome. */\n loading: boolean\n /** Id of the action in flight, or null; every disabled control reads it. */\n busy: string | null\n /** The failure the card's error strip shows. */\n error: string | null\n /** The sign-in flow being polled, when one is running. */\n flow: ClaudeLoginFlowDto | null\n /** Result of the last explicit connection test. */\n connection: ClaudeConnectionDto | null\n /** What the user has typed into the manual-paste box. */\n pasteValue: string\n /** One free-text capacity draft per model, keyed by model id. */\n contextDrafts: Record<string, string>\n /** Model id whose context-window save or restore is in flight. */\n savingModel: string | null\n }\n /** Facts read straight off the current status answer. */\n derived: {\n /** Every account row the shared pool card lists. */\n accounts: ClaudeAccountSummaryDto[]\n /** Whether any row is a snapshot of a sign-in this plugin does not own. */\n hasAdopted: boolean\n /** Models the context-window editor offers: the enabled ones only. */\n contextModels: ClaudeModelOption[]\n /** How many stored overrides exist, whether or not a row still shows them. */\n overrideCount: number\n /** The displayed account's quota snapshot, when the host has one. */\n quota: ClaudeAccountQuota | null | undefined\n /** Windows of that snapshot, shortest first. */\n windows: ClaudeQuotaWindow[]\n /**\n * The line's dictionary, handed to the shared pool card as one object.\n *\n * The hook already owns it for its own sentences, so the view takes the same\n * object from here rather than reaching for a second import.\n */\n poolLabels: typeof zh\n }\n /** Everything the view can trigger. */\n actions: {\n /** Start a sign-in; opens the authorize page when the flow carries one. */\n login(): Promise<void>\n cancelLogin(): Promise<void>\n /** Finish a manual-mode sign-in with the pasted code. */\n submitPaste(): Promise<void>\n /** Add the local Claude Code sign-in as a snapshot. */\n adopt(): Promise<void>\n /** Forget every imported snapshot, or one of them. */\n stopImporting(accountId?: string): Promise<void>\n /** One account-level action on the shared pool card. */\n accountAction(\n action: 'set-primary' | 'delete' | 'clear-cooldown',\n accountId: string,\n ): Promise<void>\n setStrategy(strategy: AccountRotationStrategy): Promise<void>\n /** Re-authorize ONE account; the returned flow starts the polling above. */\n relogin(accountId: string): void\n refreshQuota(): Promise<void>\n refreshCatalog(): Promise<void>\n testConnection(): Promise<void>\n toggleModel(modelId: string, checked: boolean): void\n setAllModels(selectAll: boolean): void\n updateEffort(effort: ClaudeReasoningEffort | null): Promise<void>\n updateCacheTtl(ttl: ClaudeCacheTtl | null): Promise<void>\n saveContextWindow(modelId: string): Promise<void>\n resetContextWindow(modelId: string): Promise<void>\n resetAllContextWindows(): Promise<void>\n /** Edit one capacity draft mid-typing; the editor never parses it. */\n updateContextDraft(modelId: string, draft: string): void\n /** Edit the manual-paste box. */\n setPasteValue(value: string): void\n }\n}\n\nexport function useClaudeSection({ onModelChange, loadModelDirectory }: ClaudeSectionProps): ClaudeSectionView {\n const [status, setStatus] = useState<ClaudeWebStatus | null>(null)\n const [loading, setLoading] = useState(true)\n const [busy, setBusy] = useState<string | null>(null)\n const [error, setError] = useState<string | null>(null)\n const [flow, setFlow] = useState<ClaudeLoginFlowDto | null>(null)\n const [pasteValue, setPasteValue] = useState('')\n const [contextDrafts, setContextDrafts] = useState<Record<string, string>>({})\n const [savingModel, setSavingModel] = useState<string | null>(null)\n const [connection, setConnection] = useState<ClaudeConnectionDto | null>(null)\n\n /** Follow-up poll owed while the host refreshes the quota behind an answer. */\n const quotaFollowUp = useRef<QuotaFollowUp | null>(null)\n\n const t = zh\n\n const notifyChange = useCallback(() => {\n onModelChange?.()\n loadModelDirectory?.()\n }, [onModelChange, loadModelDirectory])\n\n /** Report one failure in the card's error strip. */\n const reportError = useCallback((err: unknown): void => {\n setError(err instanceof Error ? err.message : String(err))\n }, [])\n\n const loadStatus = useCallback(async (quiet = false) => {\n if (!quiet) setError(null)\n try {\n const data = await api.request<ClaudeWebStatus>('/status')\n setStatus(data)\n setContextDrafts(contextDraftsFor(data))\n // An answer that refreshed the quota behind itself is followed up shortly,\n // so the fresh numbers land without waiting for the next 60 s poll.\n quotaFollowUp.current ??= createQuotaFollowUp()\n quotaFollowUp.current.observe(data.quotaRefreshing === true, () => { void loadStatus(true) })\n } catch (err) {\n if (!quiet) reportError(err)\n } finally {\n setLoading(false)\n }\n }, [reportError])\n\n useEffect(() => {\n void loadStatus()\n const refreshWhenVisible = () => {\n if (document.visibilityState === 'visible') void loadStatus(true)\n }\n document.addEventListener('visibilitychange', refreshWhenVisible)\n const timer = window.setInterval(refreshWhenVisible, 60_000)\n return () => {\n window.clearInterval(timer)\n document.removeEventListener('visibilitychange', refreshWhenVisible)\n quotaFollowUp.current?.cancel()\n }\n }, [loadStatus])\n\n // The sign-in flow runs on the host and is polled here, because authorization\n // happens in a browser this card does not control. Every entry point into the\n // flow — the account card's sign-in button, the two-option login action, and a\n // per-account re-login — ends in the same 'pending' state, so one effect\n // drives all of them.\n useEffect(() => {\n // 'exchanging' too: the host reports it while the code is redeemed, and a\n // poll that lands in that window used to stop polling for good - the card\n // then sat on \"exchanging\" while the host had long finished signing in.\n if (flow?.status !== 'pending' && flow?.status !== 'exchanging') return\n const timer = window.setInterval(() => {\n void (async () => {\n try {\n const poll = await api.request<ClaudeLoginFlowDto>('/login/status')\n setFlow(poll)\n if (poll.status === 'complete') {\n setPasteValue('')\n await loadStatus()\n notifyChange()\n } else if (poll.status === 'error') {\n setError(poll.error || t.loginFailed)\n }\n } catch {\n // A failed poll is transient; the next tick retries.\n }\n })()\n }, LOGIN_POLL_MS)\n return () => window.clearInterval(timer)\n }, [flow?.status, loadStatus, notifyChange, t.loginFailed])\n\n const login = async () => {\n try {\n setBusy('login')\n setError(null)\n setPasteValue('')\n const next = await api.request<ClaudeLoginFlowDto>('/login', {\n method: 'POST',\n body: JSON.stringify({}),\n })\n setFlow(next)\n // The card is the ONLY place the page is opened; the host no longer opens\n // it too (that showed two identical login pages). The desktop shell hands\n // window.open to the system browser, and a blocked popup changes nothing:\n // the card renders the link below.\n if (next.authUrl) window.open(next.authUrl, '_blank', 'noopener,noreferrer')\n } catch (err) {\n reportError(err)\n } finally {\n setBusy(null)\n }\n }\n\n const cancelLogin = async () => {\n try {\n const next = await api.request<ClaudeLoginFlowDto>('/login/cancel', { method: 'POST' })\n setFlow(next)\n } catch (err) {\n reportError(err)\n }\n }\n\n /** Finish a manual-mode sign-in with the code the user pasted. */\n const submitPaste = async () => {\n if (pasteValue.trim() === '') return\n try {\n setBusy('login-input')\n setError(null)\n // The route answers with the refreshed STATUS, not with the flow: a\n // successful exchange stores the credential, so the account card, the\n // models and the quota are all stale by the time it returns.\n const updated = await api.request<ClaudeWebStatus>('/login/input', {\n method: 'POST',\n body: JSON.stringify({ input: pasteValue }),\n })\n setStatus(updated)\n setContextDrafts(contextDraftsFor(updated))\n setFlow({ status: 'idle' })\n setPasteValue('')\n notifyChange()\n } catch (err) {\n reportError(err)\n } finally {\n setBusy(null)\n }\n }\n\n /**\n * Add the local Claude Code sign-in as a snapshot.\n *\n * The host reads the file; the card only asks for the import.\n */\n const adopt = async () => {\n try {\n setBusy('adopt')\n setError(null)\n const updated = await api.request<ClaudeWebStatus>('/adopt', { method: 'POST' })\n setStatus(updated)\n setContextDrafts(contextDraftsFor(updated))\n notifyChange()\n } catch (err) {\n reportError(err)\n } finally {\n setBusy(null)\n }\n }\n\n /** Forget every imported snapshot, or one of them. Claude Code's file is untouched. */\n const stopImporting = async (accountId?: string) => {\n try {\n setBusy(accountId === undefined ? 'adopt-disable' : `adopt-disable-${accountId}`)\n setError(null)\n const updated = await api.request<ClaudeWebStatus>('/adopt/disable', {\n method: 'POST',\n body: JSON.stringify(accountId === undefined ? {} : { accountId }),\n })\n setStatus(updated)\n notifyChange()\n } catch (err) {\n reportError(err)\n } finally {\n setBusy(null)\n }\n }\n\n /** One account-level action on the shared pool card. */\n const accountAction = async (\n action: 'set-primary' | 'delete' | 'clear-cooldown',\n accountId: string,\n ) => {\n try {\n setBusy(`${action}-${accountId}`)\n setError(null)\n const updated = await api.request<ClaudeWebStatus>('/accounts', {\n method: 'POST',\n body: JSON.stringify({ action, accountId }),\n })\n setStatus(updated)\n notifyChange()\n } catch (err) {\n reportError(err)\n } finally {\n setBusy(null)\n }\n }\n\n const setStrategy = async (strategy: AccountRotationStrategy) => {\n try {\n setBusy('strategy')\n setError(null)\n const updated = await api.request<ClaudeWebStatus>('/accounts', {\n method: 'POST',\n body: JSON.stringify({ action: 'strategy', strategy }),\n })\n setStatus(updated)\n } catch (err) {\n reportError(err)\n } finally {\n setBusy(null)\n }\n }\n\n /**\n * Re-authorize ONE account.\n *\n * Nothing is deleted: the sign-in route is addressed at this account id, so\n * the new credential lands in that row and keeps its alias and place in the\n * rotation. The flow DTO it returns is what starts the polling above.\n */\n const relogin = (accountId: string): void => {\n void (async () => {\n try {\n setBusy(`relogin-${accountId}`)\n setError(null)\n setPasteValue('')\n const next = await api.request<ClaudeLoginFlowDto>('/login', {\n method: 'POST',\n body: JSON.stringify({ accountId }),\n })\n setFlow(next)\n if (next.authUrl) window.open(next.authUrl, '_blank', 'noopener,noreferrer')\n } catch (err) {\n reportError(err)\n } finally {\n setBusy(null)\n }\n })()\n }\n\n const refreshQuota = async () => {\n try {\n setBusy('quota')\n setError(null)\n // A quota FAILURE is not a failed request: it arrives as `quotaError` on a\n // 200, so the card keeps rendering the account beside the reason.\n const updated = await api.request<ClaudeWebStatus>('/quota', { method: 'POST' })\n setStatus(updated)\n } catch (err) {\n reportError(err)\n // Re-read so the card still shows the account and any recorded reason.\n await loadStatus(true)\n } finally {\n setBusy(null)\n }\n }\n\n const refreshCatalog = async () => {\n try {\n setBusy('catalog')\n setError(null)\n const updated = await api.request<ClaudeWebStatus>('/catalog/refresh', { method: 'POST' })\n setStatus(updated)\n setContextDrafts(contextDraftsFor(updated))\n notifyChange()\n } catch (err) {\n reportError(err)\n } finally {\n setBusy(null)\n }\n }\n\n const testConnection = async () => {\n try {\n setBusy('connection')\n setError(null)\n setConnection(null)\n // A refusal is a VALUE here: the route answers 200 with `connected: false`\n // and a reason, because explaining the refusal is the whole job.\n const result = await api.request<ClaudeConnectionDto>('/connection/test', { method: 'POST' })\n setConnection(result)\n // The probe is a real request against the account, so the quota shown is\n // now current.\n await loadStatus(true)\n } catch (err) {\n reportError(err)\n } finally {\n setBusy(null)\n }\n }\n\n const applyEnabled = async (enabledModelIds: string[]) => {\n try {\n const updated = await api.request<ClaudeWebStatus>('/models', {\n method: 'POST',\n body: JSON.stringify({ enabledModelIds }),\n })\n setStatus(updated)\n // A model that was just checked has no draft yet; the context window\n // section only renders enabled models.\n setContextDrafts(contextDraftsFor(updated))\n notifyChange()\n } catch (err) {\n reportError(err)\n }\n }\n\n const toggleModel = (modelId: string, checked: boolean) => {\n if (!status) return\n const current = status.models.filter((model) => model.enabled).map((model) => model.id)\n const next = checked ? [...new Set([...current, modelId])] : current.filter((id) => id !== modelId)\n void applyEnabled(next)\n }\n\n const setAllModels = (selectAll: boolean) => {\n if (!status || status.models.length === 0) return\n void applyEnabled(selectAll ? status.models.map((model) => model.id) : [])\n }\n\n const updateEffort = async (effort: ClaudeReasoningEffort | null) => {\n try {\n const updated = await api.request<ClaudeWebStatus>('/settings', {\n method: 'POST',\n body: JSON.stringify({ defaultReasoningEffort: effort }),\n })\n setStatus(updated)\n notifyChange()\n } catch (err) {\n reportError(err)\n }\n }\n\n const updateCacheTtl = async (ttl: ClaudeCacheTtl | null) => {\n try {\n const updated = await api.request<ClaudeWebStatus>('/settings', {\n method: 'POST',\n body: JSON.stringify({ cacheTtl: ttl }),\n })\n setStatus(updated)\n notifyChange()\n } catch (err) {\n reportError(err)\n }\n }\n\n const saveContextWindow = async (modelId: string) => {\n const raw = contextDrafts[modelId] || ''\n const parsed = parsePositiveCapacity(raw)\n if (parsed === null) {\n setError(t.contextWindowInvalid.replace('{value}', raw))\n return\n }\n try {\n setSavingModel(modelId)\n setError(null)\n const updated = await api.request<ClaudeWebStatus>('/settings', {\n method: 'POST',\n body: JSON.stringify({ contextWindowOverrides: { [modelId]: parsed } }),\n })\n setStatus(updated)\n setContextDrafts((prev) => ({ ...prev, [modelId]: formatCapacity(parsed) }))\n notifyChange()\n } catch (err) {\n reportError(err)\n } finally {\n setSavingModel(null)\n }\n }\n\n /**\n * Clear one override.\n *\n * `null` is the card's \"restore the catalog default\" and the host preserves\n * it through its own normalization, which is what makes this a delete rather\n * than a save of the default value.\n */\n const resetContextWindow = async (modelId: string) => {\n try {\n setSavingModel(modelId)\n setError(null)\n const updated = await api.request<ClaudeWebStatus>('/settings', {\n method: 'POST',\n body: JSON.stringify({ contextWindowOverrides: { [modelId]: null } }),\n })\n setStatus(updated)\n setContextDrafts((prev) => {\n const model = updated.models.find((candidate) => candidate.id === modelId)\n return model === undefined ? prev : { ...prev, [modelId]: formatCapacity(model.defaultContextWindow) }\n })\n notifyChange()\n } catch (err) {\n reportError(err)\n } finally {\n setSavingModel(null)\n }\n }\n\n /** Clear every stored override, including models the picker no longer shows. */\n const resetAllContextWindows = async () => {\n const models = Object.keys(status?.contextWindowOverrides ?? {})\n if (models.length === 0) return\n if (typeof window !== 'undefined' && !window.confirm(t.contextWindowResetAllConfirm)) return\n try {\n setBusy('context')\n setError(null)\n const updated = await api.request<ClaudeWebStatus>('/settings', {\n method: 'POST',\n body: JSON.stringify({ contextWindowOverrides: Object.fromEntries(models.map((model) => [model, null])) }),\n })\n setStatus(updated)\n setContextDrafts(contextDraftsFor(updated))\n notifyChange()\n } catch (err) {\n reportError(err)\n } finally {\n setBusy(null)\n }\n }\n\n const updateContextDraft = (modelId: string, draft: string): void => {\n setContextDrafts((prev) => ({ ...prev, [modelId]: draft }))\n }\n\n const accounts = (status?.accounts ?? []) as ClaudeAccountSummaryDto[]\n const hasAdopted = accounts.some((account) => account.adopted === true || account.removable === false)\n const contextModels = status?.models.filter((model) => model.enabled) ?? []\n const overrideCount = Object.keys(status?.contextWindowOverrides ?? {}).length\n const quota = status?.quota\n const windows: ClaudeQuotaWindow[] = quota?.windows ?? []\n\n return {\n state: {\n status,\n loading,\n busy,\n error,\n flow,\n connection,\n pasteValue,\n contextDrafts,\n savingModel,\n },\n derived: {\n accounts,\n hasAdopted,\n contextModels,\n overrideCount,\n quota,\n windows,\n poolLabels: t,\n },\n actions: {\n login,\n cancelLogin,\n submitPaste,\n adopt,\n stopImporting,\n accountAction,\n setStrategy,\n relogin,\n refreshQuota,\n refreshCatalog,\n testConnection,\n toggleModel,\n setAllModels,\n updateEffort,\n updateCacheTtl,\n saveContextWindow,\n resetContextWindow,\n resetAllContextWindows,\n updateContextDraft,\n setPasteValue,\n },\n }\n}\n","/**\n * The Claude subscription settings card.\n *\n * Markup only: every piece of state, every effect and every request this card\n * makes lives in 'useClaudeSection.ts', which returns one named shape the JSX\n * below reads. The two files are the split of a single 900-line component — the\n * behaviour is unchanged, and this one should stay render-shaped.\n */\nimport React from 'react'\nimport type {\n ClaudeAccountSummaryDto,\n ClaudeCacheTtl,\n ClaudeModelOption,\n ClaudeReasoningEffort,\n} from '../../shared/claude-contracts.ts'\nimport { CLAUDE_REASONING_EFFORTS } from '../../shared/claude-contracts.ts'\nimport { AccountPoolSection } from '../common/AccountPoolSection.tsx'\nimport { ContextWindowEditor } from '../common/ContextWindowEditor.tsx'\nimport { ModelChecklist } from '../common/ModelChecklist.tsx'\nimport { formatCapacity, formatDate } from '../common/format.ts'\nimport { useClaudeSection, type ClaudeSectionProps } from './useClaudeSection.ts'\nimport { zh } from './locales.ts'\n\n/**\n * Display label per thinking level.\n *\n * The locale dictionary only accepts flat string values, so this table lives\n * with the control that renders it — the same arrangement every sibling uses.\n * Every level the wire can name is listed, 'xhigh' included: filtering a level\n * out here would hide a choice the host would accept and a catalog may expose.\n */\nconst EFFORT_LABELS: Record<ClaudeReasoningEffort, string> = {\n low: zh.effortLow,\n medium: zh.effortMedium,\n high: zh.effortHigh,\n xhigh: zh.effortXHigh,\n max: zh.effortMax,\n}\n\n/** One-line capability summary shown as a model pill's hover title. */\nfunction modelFacts(model: ClaudeModelOption, t: typeof zh): string[] {\n const thinking = model.thinkingMode === 'mid-convo'\n ? t.thinkingModeMidConvo\n : model.thinkingMode === 'adaptive'\n ? t.thinkingModeAdaptive\n : model.thinkingMode === 'budget' ? t.thinkingModeBudget : t.thinkingModeNone\n return [\n model.id,\n model.supportsImage ? t.capImage : t.capNoImage,\n thinking,\n ...(model.canDisableThinking ? [t.capThinkingOff] : []),\n ...(model.reasoningEfforts.length > 0 ? [model.reasoningEfforts.join('/')] : []),\n ]\n}\n\nexport function ClaudeSection({ onModelChange, loadModelDirectory }: ClaudeSectionProps): React.ReactElement {\n const { state, derived, actions } = useClaudeSection({ onModelChange, loadModelDirectory })\n const { status, loading, busy, error, flow, connection, pasteValue, contextDrafts, savingModel } = state\n const { accounts, hasAdopted, contextModels, overrideCount, quota, windows, poolLabels } = derived\n const {\n login, cancelLogin, submitPaste, adopt, stopImporting, accountAction, setStrategy, relogin,\n refreshQuota, refreshCatalog, testConnection, toggleModel, setAllModels, updateEffort,\n updateCacheTtl, saveContextWindow, resetContextWindow, resetAllContextWindows,\n updateContextDraft, setPasteValue,\n } = actions\n\n const t = zh\n\n if (loading) {\n return (\n <div className=\"dsha-page\">\n <div className=\"dsha-empty\">{t.loading}</div>\n </div>\n )\n }\n\n return (\n <div className=\"dsha-page\">\n <AccountPoolSection<ClaudeAccountSummaryDto>\n accounts={accounts}\n activeAccountId={status?.activeAccountId}\n rotationStrategy={status?.rotationStrategy ?? 'sequential'}\n busy={busy}\n labels={poolLabels}\n onLogin={() => void login()}\n onSetPrimary={(accountId) => void accountAction('set-primary', accountId)}\n onDelete={(accountId) => void accountAction('delete', accountId)}\n onClearCooldown={(accountId) => void accountAction('clear-cooldown', accountId)}\n onRelogin={(accountId) => relogin(accountId)}\n onSetStrategy={(strategy) => void setStrategy(strategy)}\n showQuota\n renderLoginActions={() => (\n <div className=\"dsha-account-add-actions\">\n <button\n className=\"dsha-btn dsha-btn-primary\"\n disabled={busy !== null}\n aria-label={t.signIn}\n onClick={() => void login()}\n >\n {busy === 'login' ? t.signingIn : t.signIn}\n </button>\n {/* The second entry: an existing local Claude Code sign-in can be\n borrowed instead of running a fresh OAuth flow. */}\n <button\n className=\"dsha-btn\"\n disabled={busy !== null}\n aria-label={t.importClaudeCode}\n onClick={() => void adopt()}\n >\n {busy === 'adopt' ? t.importing : t.importClaudeCode}\n </button>\n </div>\n )}\n renderAccountActions={(entry) => (\n // An imported row is a snapshot of a sign-in this plugin does NOT own,\n // so the shared card suppresses Delete for it ('removable: false') and\n // this is the action that replaces it. Un-importing forgets the\n // snapshot; Claude Code's own file is never touched.\n entry.adopted === true || entry.removable === false ? (\n <button\n className=\"dsha-btn\"\n disabled={busy !== null}\n aria-label={`${t.stopImporting}: ${entry.id}`}\n onClick={() => void stopImporting(entry.id)}\n >\n {busy === `adopt-disable-${entry.id}` ? t.importing : t.stopImporting}\n </button>\n ) : null\n )}\n // Only facts the shared card cannot know. E-mail is the shared card's\n // row (and is usually the card's title already); the snapshot path is\n // credential bookkeeping, which the card does not show anywhere.\n renderDetails={(entry) => (\n <>\n {entry.planLabel && <span>{t.plan}: {entry.planLabel}</span>}\n {entry.subscriptionType && <span>{t.subscriptionType}: {entry.subscriptionType}</span>}\n <span>\n {t.source}: {entry.source === 'claude-code' ? t.sourceClaudeCode : t.sourceManaged}\n </span>\n </>\n )}\n >\n {hasAdopted && (\n <div className=\"dsha-actions\">\n <button\n className=\"dsha-btn\"\n disabled={busy !== null}\n aria-label={t.stopImporting}\n onClick={() => void stopImporting()}\n >\n {busy === 'adopt-disable' ? t.importing : t.stopImporting}\n </button>\n </div>\n )}\n\n {flow !== null && flow.status !== 'idle' && flow.status !== 'complete' && (\n <div className=\"dshcl-flow\">\n <strong>{t.signInSection}</strong>\n <p className=\"dsha-muted\">\n {flow?.status === 'error'\n ? `${t.loginFailed}: ${flow.error ?? ''}`\n : flow?.status === 'exchanging'\n ? t.loginExchanging\n : flow?.mode === 'manual' ? t.loginModeManual : t.loginModeLoopback}\n </p>\n {flow?.hint !== undefined && <p className=\"dsha-muted\">{flow.hint}</p>}\n {flow?.fallbackReason !== undefined && (\n <p className=\"dsha-notice\">{t.loginFallbackReason.replace('{detail}', flow.fallbackReason)}</p>\n )}\n {flow?.authUrl !== undefined && (\n <>\n <span className=\"dsha-label\">{t.authorizeUrl}</span>\n <code className=\"dshcl-flow-url\">{flow.authUrl}</code>\n <div className=\"dsha-actions\">\n <a className=\"dsha-btn\" href={flow.authUrl} target=\"_blank\" rel=\"noreferrer noopener\">\n {t.openAuthorizeUrl}\n </a>\n </div>\n </>\n )}\n {flow?.redirectUri !== undefined && (\n <div className=\"dsha-row\">\n <span className=\"dsha-label\">{t.redirectUri}</span>\n <span className=\"dsha-value dshcl-mono\">{flow.redirectUri}</span>\n </div>\n )}\n {/* Always rendered while a flow is pending, and never hidden behind a\n mode test: manual mode has no browser callback at all, so for those\n users this box is the only way to finish signing in. */}\n <div className=\"dshcl-paste\">\n <strong>{t.manualPasteSection}</strong>\n <p className=\"dsha-muted\">{t.manualPasteHint}</p>\n <div className=\"dshcl-paste-row\">\n <input\n type=\"text\"\n className=\"dsha-select\"\n aria-label={t.manualPasteSection}\n placeholder={t.manualPastePlaceholder}\n value={pasteValue}\n disabled={busy !== null}\n onChange={(event) => setPasteValue(event.currentTarget.value)}\n onKeyDown={(event) => {\n if (event.key === 'Enter') void submitPaste()\n }}\n />\n <button\n className=\"dsha-btn dsha-btn-primary\"\n disabled={busy !== null || pasteValue.trim() === ''}\n onClick={() => void submitPaste()}\n >\n {busy === 'login-input' ? t.manualPasteSubmitting : t.manualPasteSubmit}\n </button>\n <button className=\"dsha-btn\" disabled={busy !== null} onClick={() => void cancelLogin()}>\n {t.cancelSignIn}\n </button>\n </div>\n </div>\n </div>\n )}\n </AccountPoolSection>\n\n <section className=\"dsha-group\">\n <div className=\"dsha-grouphead\">\n <h3>{t.connection}</h3>\n </div>\n {status?.account !== null && status?.account !== undefined && (\n <div className=\"dsha-row\">\n <span className=\"dsha-label\">{t.account}</span>\n <span className=\"dsha-value\">\n {status.account.email ?? t.planUnknown}\n {status.account.subscriptionType !== null ? ` · ${status.account.subscriptionType}` : ''}\n </span>\n </div>\n )}\n <p className=\"dsha-notice\">\n {status?.serving === false && status.conflict\n ? t.routeConflict.replace('{detail}', status.conflict)\n : t.routeOwned}\n </p>\n {connection !== null && (\n <p className={connection.connected ? 'dsha-muted' : 'dsha-notice'}>\n {connection.connected\n ? `${t.testSuccess} · ${t.testLatency.replace('{ms}', String(connection.latencyMs))}`\n : t.testFailed.replace('{detail}', connection.error ?? `HTTP ${connection.status}`)\n + ` (${connection.retryable ? t.testRetryable : t.testNotRetryable})`}\n </p>\n )}\n <div className=\"dsha-actions\">\n <button\n className=\"dsha-btn\"\n disabled={busy !== null || !status?.authenticated}\n onClick={() => void testConnection()}\n >\n {busy === 'connection' ? t.testingConnection : t.testConnection}\n </button>\n </div>\n </section>\n\n <section className=\"dsha-group\">\n <div className=\"dsha-grouphead\">\n <h3>{t.modelsSection}</h3>\n <button\n className=\"dsha-btn\"\n disabled={busy !== null}\n onClick={() => void refreshCatalog()}\n >\n {busy === 'catalog' ? t.refreshingCatalog : t.refreshCatalog}\n </button>\n </div>\n <p className=\"dsha-muted dsha-models-hint\">{t.modelsHint}</p>\n <ModelChecklist\n items={(status?.models ?? []).map((model: ClaudeModelOption) => ({\n id: model.id,\n name: model.name,\n hint: modelFacts(model, t).slice(1).join(' · ') || undefined,\n enabled: model.enabled,\n }))}\n busy={busy !== null}\n onToggle={toggleModel}\n onToggleAll={setAllModels}\n labels={{ selectAll: t.selectAll, clearAll: t.unselectAll, list: t.modelsSection }}\n />\n </section>\n\n <section className=\"dsha-group\">\n <div className=\"dsha-grouphead\">\n <h3>{t.enhanced}</h3>\n </div>\n <div className=\"dsha-pref-row\">\n <div>\n <strong>{t.defaultReasoningEffort}</strong>\n <p className=\"dsha-muted\">{t.defaultReasoningEffortHint}</p>\n </div>\n <select\n className=\"dsha-select\"\n aria-label={t.defaultReasoningEffort}\n value={status?.defaultReasoningEffort ?? ''}\n disabled={busy !== null}\n onChange={(event) => {\n const value = event.currentTarget.value\n void updateEffort(value === '' ? null : (value as ClaudeReasoningEffort))\n }}\n >\n <option value=\"\">{t.defaultEffortAuto}</option>\n {/* Exactly what the catalog exposes, 'xhigh' included. */}\n {CLAUDE_REASONING_EFFORTS.map((effort) => (\n <option key={effort} value={effort}>{EFFORT_LABELS[effort]}</option>\n ))}\n </select>\n </div>\n <div className=\"dsha-pref-row\">\n <div>\n <strong>{t.cacheTtl}</strong>\n <p className=\"dsha-muted\">{t.cacheTtlHint}</p>\n </div>\n <select\n className=\"dsha-select\"\n aria-label={t.cacheTtl}\n value={status?.cacheTtl ?? ''}\n disabled={busy !== null}\n onChange={(event) => {\n const value = event.currentTarget.value\n void updateCacheTtl(value === '' ? null : (value as ClaudeCacheTtl))\n }}\n >\n <option value=\"\">{t.cacheTtlSubscription}</option>\n <option value=\"1h\">{t.cacheTtl1h}</option>\n <option value=\"5m\">{t.cacheTtl5m}</option>\n </select>\n </div>\n <p className=\"dsha-muted\" style={{ paddingTop: 10 }}>{t.modelLadders}</p>\n {status?.models.map((model) => (\n <div key={model.id} className=\"dsha-row\">\n <span className=\"dsha-label\">{model.name}</span>\n <span className=\"dsha-value\">\n {model.reasoningEfforts.length === 0 ? t.modelLadderNone : model.reasoningEfforts.join(' · ')}\n </span>\n </div>\n ))}\n </section>\n\n <section className=\"dsha-group\">\n <div className=\"dsha-grouphead\">\n <h3>{t.contextWindowSection}</h3>\n </div>\n <p className=\"dsha-muted\">{t.contextWindowHint}</p>\n <ContextWindowEditor\n rows={contextModels.map((model: ClaudeModelOption) => ({\n id: model.id,\n name: model.name,\n draft: contextDrafts[model.id] ?? '',\n meta: model.defaultContextWindow < model.contextWindow\n ? formatCapacity(model.contextWindow)\n : undefined,\n inputLabel: `${model.name} context window`,\n hasOverride: status?.contextWindowOverrides[model.id] !== undefined,\n saving: savingModel === model.id,\n }))}\n labels={{\n tokens: t.tokens,\n save: t.save,\n saving: t.saving,\n reset: t.contextWindowReset,\n resetAll: t.contextWindowResetAll,\n empty: t.contextWindowNoneEnabled,\n }}\n busy={busy !== null}\n overrideCount={overrideCount}\n metaClassName=\"dshcl-model-meta\"\n onDraftChange={(id, draft) => updateContextDraft(id, draft)}\n onCommit={(id) => void saveContextWindow(id)}\n onReset={(id) => void resetContextWindow(id)}\n onResetAll={() => void resetAllContextWindows()}\n />\n </section>\n\n <section className=\"dsha-group\">\n <div className=\"dsha-grouphead\">\n <h3>{t.quotaSection}</h3>\n <button\n className=\"dsha-btn\"\n disabled={busy !== null || !status?.authenticated}\n onClick={() => void refreshQuota()}\n >\n {busy === 'quota' ? t.refreshingQuota : t.refreshQuota}\n </button>\n </div>\n <p className=\"dsha-muted\">{t.quotaDesc}</p>\n {/* The progress bars moved into each account card: quota follows the\n account, so a bar here could only ever describe whichever account\n happened to be active when the snapshot was read. What stays is what\n has no per-account bar to live in — the extra-usage meter's own\n facts, the rate-limit status, the representative window and the\n freshness of this reading. */}\n <p className=\"dsha-muted\">{t.quotaFactsScope}</p>\n\n {/* A refresh running behind the answer is rendered beside the snapshot\n rather than instead of it: the numbers on screen are real, just not\n the newest, and the follow-up poll brings the newer ones. */}\n {status?.quotaRefreshing === true && <p className=\"dsha-notice\">{t.quotaRefreshing}</p>}\n {status?.quotaError !== undefined && status.quotaError !== null && (\n <p className=\"dsha-notice\">{t.quotaError}: {status.quotaError}</p>\n )}\n\n {!status?.authenticated ? (\n <div className=\"dsha-empty\">{t.quotaSignedOut}</div>\n ) : quota === null || quota === undefined ? (\n <div className=\"dsha-empty\">{busy === 'quota' ? t.refreshingQuota : t.quotaEmpty}</div>\n ) : (\n <div className=\"dsha-quota-card\">\n <div className=\"dsha-quota-title\">\n <strong>{status.account?.subscriptionType ?? t.quotaSection}</strong>\n <span>{status.account?.email ?? t.planUnknown}</span>\n </div>\n\n {quota.extraUsage !== null && (\n <div className=\"dsha-meter-wrap\">\n <div className=\"dsha-meter-label\">\n <span>{quota.extraUsage.label || t.extraUsage}</span>\n <strong>\n {quota.extraUsage.remainingPercent === null\n ? t.quotaUnknown\n : `${Math.round(quota.extraUsage.remainingPercent)}% ${t.left}`}\n </strong>\n </div>\n <div className=\"dsha-meter-meta\">\n <span>{t.extraUsage}: {quota.extraUsage.enabled ? t.extraUsageEnabled : t.extraUsageDisabled}</span>\n {quota.extraUsage.used !== null && <span>{t.usedLabel}: {quota.extraUsage.used}</span>}\n {quota.extraUsage.limit !== null && (\n <span>{t.extraUsageLimit}: {quota.extraUsage.limit}</span>\n )}\n </div>\n </div>\n )}\n\n {quota.status !== null && (\n <div className=\"dsha-row\">\n <span className=\"dsha-label\">{t.quotaStatus}</span>\n <span className=\"dsha-value\">{quota.status}</span>\n </div>\n )}\n {quota.representativeClaim !== null && (\n <div className=\"dsha-row\">\n <span className=\"dsha-label\">{t.quotaRepresentative}</span>\n <span className=\"dsha-value\">{quota.representativeClaim}</span>\n </div>\n )}\n\n {windows.length === 0 && quota.extraUsage === null && (\n <div className=\"dsha-empty\">{t.quotaEmpty}</div>\n )}\n\n <div className=\"dsha-timestamp\">\n {quota.fetchedAt === null\n ? t.observedAt.replace('{time}', formatDate(quota.observedAt))\n : t.updatedAt.replace('{time}', formatDate(quota.fetchedAt))}\n </div>\n </div>\n )}\n </section>\n\n {error && (\n <div className=\"dsha-error\">\n <div>{error}</div>\n </div>\n )}\n </div>\n )\n}\n","import type { OllamaWebStatus } from '../../shared/ollama-contracts.ts'\n\nconst API = '/ollama/api'\n\n/**\n * The Ollama settings API, as the card uses it.\n *\n * Deliberately the same envelope and the same fetch shape every other provider\n * section uses, so the shared account-pool card and this helper read alike.\n */\nexport class OllamaApi {\n status(): Promise<OllamaWebStatus> {\n return request<OllamaWebStatus>(`${API}/status`)\n }\n\n /**\n * One pool action, returning the refreshed status.\n *\n * The host answers with the same envelope the status route uses, so the card\n * never has to guess what the pool looks like after a change.\n */\n accountAction(\n action: 'add' | 'set-primary' | 'set-alias' | 'delete' | 'clear-cooldown' | 'strategy',\n body: { accountId?: string; alias?: string; strategy?: string; apiKey?: string } = {},\n ): Promise<OllamaWebStatus> {\n return post<OllamaWebStatus>(`${API}/accounts`, { action, ...body })\n }\n\n refreshCatalog(): Promise<{ models: unknown[] }> {\n return post(`${API}/catalog/refresh`, {})\n }\n\n /**\n * Replace the enabled-model selection.\n *\n * The whole list is sent rather than a single id's new state, because the card\n * offers bulk select and unselect and would otherwise have to read the current\n * selection before it could answer 'turn this one off'.\n */\n setEnabledModels(enabledModelIds: string[]): Promise<{ enabledModelIds: string[] }> {\n return post(`${API}/models`, { enabledModelIds })\n }\n}\n\nasync function post<T>(url: string, body: object): Promise<T> {\n return request<T>(url, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body),\n })\n}\n\nasync function request<T>(url: string, init?: RequestInit): Promise<T> {\n const response = await fetch(url, { ...init, credentials: 'same-origin' })\n const envelope = await readEnvelope<T>(response)\n if (!response.ok || !envelope.ok) {\n throw new Error(envelope.error || `HTTP ${response.status}`)\n }\n return envelope.value as T\n}\n\n/**\n * Read the {ok,value,error} envelope, or say why there was not one.\n *\n * `response.json()` is not a way to report an error. A body that is empty —\n * which is what DSH's web server sends for a route handler that rejected, and\n * what a proxy sends for a blocked request — throws the browser's own\n * \"Failed to execute 'json' on 'Response': Unexpected end of JSON input\" (issue\n * #36), a sentence that names neither the status nor the request. Reading the\n * text first costs one string and turns every unreadable answer into a message\n * that says what the Host actually replied.\n *\n * The body is never echoed back: it can be an HTML page of arbitrary size, and\n * its content-type alone is what identifies the failure.\n */\nasync function readEnvelope<T>(\n response: Response,\n): Promise<{ ok: boolean; value?: T; error?: string }> {\n let text: string\n try {\n text = await response.text()\n } catch (cause) {\n throw new Error(unreadable(response, cause))\n }\n if (text.trim() === '') throw new Error(unreadable(response))\n let parsed: unknown\n try {\n parsed = JSON.parse(text)\n } catch {\n throw new Error(unreadable(response))\n }\n if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {\n throw new Error(unreadable(response))\n }\n const envelope = parsed as { ok: boolean; value?: T; error?: string }\n if (typeof envelope.error !== 'string') delete envelope.error\n return envelope\n}\n\n/** The one sentence every unreadable answer turns into. */\nfunction unreadable(response: Response, cause?: unknown): string {\n const kind = response.headers.get('content-type') ?? 'no content-type'\n return `The Ollama settings API answered with ${response.status} and no JSON body (${kind})`\n + (cause instanceof Error ? `: ${cause.message}` : '')\n + '. The Host log holds the underlying error.'\n}","import { accountPoolEn, accountPoolZh } from '../common/account-pool-labels.ts'\n\nexport const NS_OLLAMA = 'dsh-ollama'\n\nexport const zh = {\n // The account-management card is shared with every other provider tab, so its\n // labels come from one place instead of drifting per provider. Only the two\n // entries that are wrong for a pasted key are overridden below.\n ...accountPoolZh,\n // Two overrides, and both are factual rather than cosmetic: an Ollama key\n // never expires and is replaced rather than re-signed-in, so the shared\n // wording would state something untrue about this line.\n relogin: '更换 Key',\n needsRelogin: 'Key 已失效',\n addAccount: '添加 API Key',\n noAccounts: '暂无 API Key。点击「添加 API Key」粘贴 ollama.com 创建的 Key。',\n\n title: 'Ollama',\n pageDesc: '接入 Ollama Cloud,用多个 API Key 组成号池,自动轮换与故障转移。',\n routeOwned: '模型路由由本插件提供',\n routeConflict: '模型路由已被其他 Provider 占用:{detail}。请在 DSH 设置中移除重复的 Provider 配置后重试。',\n\n // Sign-in is a paste, not a flow: the service issues a static key and there\n // is nothing to authorize.\n keySection: '添加 API Key',\n keyHint: '在 https://ollama.com/settings/keys 创建 API Key 后粘贴到此处。Key 不会过期,可随时在设置页吊销。',\n keyPlaceholder: '粘贴 Ollama API Key',\n keyAliasLabel: '备注名(可选)',\n keyAliasPlaceholder: '例如:主号、备用号',\n keyAliasHint: 'Ollama 不返回账号信息,多个 Key 靠备注名区分。',\n keySave: '添加',\n keySaving: '添加中...',\n\n modelsSection: '模型',\n modelsHint: '模型列表来自 Ollama 的 /api/tags,随服务更新,无需手动维护。',\n catalogSync: '同步模型列表',\n catalogSyncing: '同步中...',\n catalogNeverSynced: '尚未同步模型列表。点右上角「同步模型列表」获取你账号可用的模型 —— 在此之前这里不会有任何条目,本线路也不会出现在模型选择器中。',\n catalogEmpty: 'Ollama 未返回任何模型。',\n catalogNeedKey: '请先添加一个 API Key,再同步模型列表。',\n catalogFailed: '无法从 Ollama 读取模型列表。',\n modelCount: '{count} 个模型',\n noModels: '暂无可用模型。',\n selectAll: '全选',\n unselectAll: '全不选',\n noneSelected: '未选择任何模型,该线路不会出现在模型选择器中。',\n\n // Stated plainly, because these are documented service limits and a user who\n // hits them deserves to know they are not a bug here.\n limitsSection: '能力边界',\n limitsHint: '以下为 Ollama Cloud 官方文档列出的限制,本线路不会绕过:',\n limitNoStateful: '不支持 Responses 的有状态会话(仅无状态形式)。',\n limitNoWebSearch: '不支持通过 /v1/responses 使用内置联网搜索。',\n limitNoToolReplay: '不支持自定义工具调用的重放(replay)。',\n limitUsage: 'Ollama 没有配额/剩余额度 API(上游 issue #15132、#15663 均已关闭),所以只能显示「已消耗」,无法显示「剩余多少」。',\n wireNote: '请求默认走 OpenAI 兼容面(/v1),必要时回落到原生面(/api/chat)。',\n\n lastModel: '最近模型',\n keyCreated: '添加于',\n error: '操作失败:{detail}',\n usageTitle: '累计消耗',\n usageInput: '输入 {tokens}',\n usageOutput: '输出 {tokens}',\n usageRequests: '{count} 次请求',\n usageNone: '尚无请求',\n usageHint: '按 Ollama 每次响应自带的 token 计数本地累加。',\n} as const\n\nexport const en = {\n ...accountPoolEn,\n relogin: 'Replace Key',\n needsRelogin: 'Key rejected',\n addAccount: 'Add API Key',\n noAccounts: 'No API keys yet. Click \"Add API Key\" to paste one from ollama.com.',\n\n title: 'Ollama',\n pageDesc: 'Connect Ollama Cloud with several API keys pooled for rotation and failover.',\n routeOwned: 'Model route served by this plugin',\n routeConflict: 'The model route is already owned by another provider: {detail}',\n\n keySection: 'Add an API key',\n keyHint: 'Create a key at https://ollama.com/settings/keys and paste it here. Keys do not expire and can be revoked from that page.',\n keyPlaceholder: 'Paste an Ollama API key',\n keyAliasLabel: 'Label (optional)',\n keyAliasPlaceholder: 'e.g. primary, backup',\n keyAliasHint: 'Ollama reports no account identity, so labels are what tell several keys apart.',\n keySave: 'Add',\n keySaving: 'Adding...',\n\n modelsSection: 'Models',\n modelsHint: 'The list comes from Ollama \\'/api/tags\\' and tracks the service, so there is nothing to maintain by hand.',\n catalogSync: 'Sync model list',\n catalogSyncing: 'Syncing...',\n catalogNeverSynced: 'The model list has not been synced yet. Use \"Sync model list\" above to fetch the models your account can use - until then this list is empty and the line will not appear in the model picker.',\n catalogEmpty: 'Ollama returned no models.',\n catalogNeedKey: 'Add an API key before syncing the model list.',\n catalogFailed: 'Could not read the model list from Ollama.',\n modelCount: '{count} model(s)',\n noModels: 'No models available.',\n selectAll: 'Select all',\n unselectAll: 'Clear all',\n noneSelected: 'No models are selected, so this line will not appear in the model picker.',\n\n limitsSection: 'Documented limits',\n limitsHint: 'Ollama Cloud documents these limits; this line does not work around them:',\n limitNoStateful: 'No stateful Responses (stateless only).',\n limitNoWebSearch: 'No built-in web search through /v1/responses.',\n limitNoToolReplay: 'No replay of custom tool calls.',\n limitUsage: 'Ollama has no quota or remaining-balance API (upstream issues #15132 and #15663 were both closed), so this card can show what has been consumed but not what is left.',\n wireNote: 'Requests use the OpenAI-compatible surface (/v1) and fall back to the native surface (/api/chat) when needed.',\n\n lastModel: 'Last model',\n keyCreated: 'Added',\n error: 'Action failed: {detail}',\n usageTitle: 'Consumed so far',\n usageInput: 'in {tokens}',\n usageOutput: 'out {tokens}',\n usageRequests: '{count} request(s)',\n usageNone: 'No requests yet',\n usageHint: 'Summed locally from the token counts Ollama returns on each response.',\n} as const\n\n// Same shape every other provider locale exports: the host selects the active\n// locale and the section reads the flat dictionary through it.\nexport const dictionaries = {\n zh,\n 'zh-CN': zh,\n en,\n 'en-US': en,\n}\n\nexport type OllamaLocaleKey = keyof typeof zh\n\n","import React, { useCallback, useEffect, useState } from 'react'\nimport { AccountPoolSection } from '../common/AccountPoolSection.tsx'\nimport { ModelChecklist } from '../common/ModelChecklist.tsx'\nimport type { AccountRotationStrategy } from '../../shared/account-pool-contracts.ts'\nimport type { OllamaWebStatus } from '../../shared/ollama-contracts.ts'\nimport { OllamaApi } from './api.ts'\nimport { zh } from './locales.ts'\n\nconst API = new OllamaApi()\n\n/**\n * A token count short enough to sit in an account card.\n *\n * Exact below a thousand, then thousands, then millions. A six-figure number with\n * no grouping is unreadable at card width, and these are running totals that only\n * ever grow, so rounding is fine but commas are not optional.\n */\nexport function formatTokens(value: number): string {\n if (!Number.isFinite(value) || value < 0) return '—'\n if (value < 1_000) return String(Math.floor(value))\n if (value < 1_000_000) return `${(value / 1_000).toFixed(value < 10_000 ? 1 : 0)}K`\n return `${(value / 1_000_000).toFixed(1)}M`\n}\n\ninterface Props {\n onModelChange?: () => void\n loadModelDirectory?: () => void\n}\n\n/**\n * The Ollama tab.\n *\n * Deliberately thin. The account card, its badges and the rotation picker are\n * the shared {@link AccountPoolSection}, so this line looks\n * like every other provider tab by construction rather than by imitation; only\n * what is genuinely Ollama's - pasting a key, syncing the catalog, and the\n * documented service limits - is written here.\n */\nexport function OllamaSection(props: Props): React.ReactElement {\n const [status, setStatus] = useState<OllamaWebStatus | null>(null)\n const [busy, setBusy] = useState<string | null>(null)\n const [error, setError] = useState<string | null>(null)\n const [key, setKey] = useState('')\n const [alias, setAlias] = useState('')\n const [showKeyForm, setShowKeyForm] = useState(false)\n /** Ids the user has switched on. Empty means 'no filter', i.e. all of them. */\n const [enabled, setEnabled] = useState<Set<string>>(new Set())\n\n const reload = useCallback(async () => {\n try {\n const next = await API.status()\n setStatus(next)\n setEnabled(new Set(next.enabledModelIds))\n } catch (cause) {\n setError(cause instanceof Error ? cause.message : String(cause))\n }\n }, [])\n\n useEffect(() => {\n void reload()\n }, [reload])\n\n const run = useCallback(async (label: string, action: () => Promise<OllamaWebStatus>) => {\n setBusy(label)\n setError(null)\n try {\n setStatus(await action())\n props.onModelChange?.()\n props.loadModelDirectory?.()\n } catch (cause) {\n setError(cause instanceof Error ? cause.message : String(cause))\n } finally {\n setBusy(null)\n }\n }, [props])\n\n const addKey = useCallback(() => {\n const trimmed = key.trim()\n if (trimmed === '') return\n void run('add', async () => {\n const next = await API.accountAction('add', {\n apiKey: trimmed,\n ...(alias.trim() === '' ? {} : { alias: alias.trim() }),\n })\n // Cleared only after the host accepted it, so a failed add never loses the\n // key the user just pasted and would have to find again.\n setKey('')\n setAlias('')\n setShowKeyForm(false)\n return next\n })\n }, [key, alias, run])\n\n const syncCatalog = useCallback(() => {\n void run('catalog', async () => {\n await API.refreshCatalog()\n return API.status()\n })\n }, [run])\n\n // An empty selection means 'everything the catalog returned', which is what the\n // adapter reads as no filter. Modelling it that way rather than storing an\n // explicit all-ids list means a model the service adds later is not silently\n // hidden by a selection made before it existed.\n const isModelEnabled = useCallback((id: string): boolean => {\n return enabled.size === 0 || enabled.has(id)\n }, [enabled])\n\n const applyEnabled = useCallback((next: string[]) => {\n void run('models', async () => {\n const result = await API.setEnabledModels(next)\n setEnabled(new Set(result.enabledModelIds))\n return API.status()\n })\n }, [run])\n\n const toggleModel = useCallback((id: string, checked: boolean) => {\n if (status === null) return\n const current = status.models.filter(model => isModelEnabled(model.id)).map(model => model.id)\n const next = checked\n ? [...new Set([...current, id])]\n : current.filter(entry => entry !== id)\n applyEnabled(next)\n }, [status, isModelEnabled, applyEnabled])\n\n const setAllModels = useCallback((selectAll: boolean) => {\n if (status === null || status.models.length === 0) return\n applyEnabled(selectAll ? status.models.map(model => model.id) : [])\n }, [status, applyEnabled])\n\n const t = zh\n const pool = status?.pool\n\n return (\n <div>\n <div className=\"dsha-group\">\n <div className=\"dsha-grouphead\">\n <h3>{t.title}</h3>\n </div>\n <p className=\"dsha-notice\">{t.pageDesc}</p>\n {error !== null && (\n <p className=\"dsha-notice\" style={{ color: 'var(--dsha-danger, #c0392b)' }}>\n {t.error.replace('{detail}', error)}\n </p>\n )}\n </div>\n\n {pool !== undefined && (\n <AccountPoolSection\n accounts={pool.accounts}\n activeAccountId={pool.activeAccountId}\n rotationStrategy={pool.rotationStrategy}\n labels={t}\n busy={busy}\n onLogin={() => setShowKeyForm(value => !value)}\n onSetPrimary={(id) => void run('set-primary', () => API.accountAction('set-primary', { accountId: id }))}\n onDelete={(id) => void run('delete', () => API.accountAction('delete', { accountId: id }))}\n onClearCooldown={(id) => void run('clear-cooldown', () => API.accountAction('clear-cooldown', { accountId: id }))}\n onSetStrategy={(strategy: AccountRotationStrategy) =>\n void run('strategy', () => API.accountAction('strategy', { strategy }))}\n renderDetails={(account) => {\n const usage = account.usage\n return <>\n {account.lastModelId !== undefined && <span>{t.lastModel}: {account.lastModelId}</span>}\n {usage === undefined\n ? <span>{t.usageNone}</span>\n : <span>\n {t.usageInput.replace('{tokens}', formatTokens(usage.inputTokens))}\n {t.usageOutput.replace('{tokens}', formatTokens(usage.outputTokens))}\n {t.usageRequests.replace('{count}', String(usage.requestCount))}\n </span>}\n </>\n }}\n renderLoginActions={() => (\n <div style={{ display: 'flex', gap: 8 }}>\n <button\n className=\"dsha-btn dsha-btn-primary\"\n disabled={busy !== null}\n onClick={() => setShowKeyForm(value => !value)}\n >\n {t.addAccount}\n </button>\n </div>\n )}\n >\n {showKeyForm && (\n <div className=\"dsha-pref-row\" style={{ flexDirection: 'column', alignItems: 'stretch', gap: 8 }}>\n <label className=\"dsha-label\" htmlFor=\"ollama-key\">{t.keySection}</label>\n <input\n id=\"ollama-key\"\n className=\"dsha-input\"\n type=\"password\"\n value={key}\n placeholder={t.keyPlaceholder}\n autoComplete=\"off\"\n onChange={(event) => setKey(event.target.value)}\n />\n <label className=\"dsha-label\" htmlFor=\"ollama-alias\">{t.keyAliasLabel}</label>\n <input\n id=\"ollama-alias\"\n className=\"dsha-input\"\n value={alias}\n placeholder={t.keyAliasPlaceholder}\n onChange={(event) => setAlias(event.target.value)}\n />\n <p className=\"dsha-muted\" style={{ fontSize: 12 }}>{t.keyHint}</p>\n <p className=\"dsha-muted\" style={{ fontSize: 12 }}>{t.keyAliasHint}</p>\n <div style={{ display: 'flex', gap: 8 }}>\n <button\n className=\"dsha-btn dsha-btn-primary\"\n disabled={busy !== null || key.trim() === ''}\n onClick={addKey}\n >\n {busy === 'add' ? t.keySaving : t.keySave}\n </button>\n <button className=\"dsha-btn\" disabled={busy !== null} onClick={() => setShowKeyForm(false)}>\n {zh.deleteAccount}\n </button>\n </div>\n </div>\n )}\n </AccountPoolSection>\n )}\n\n <div className=\"dsha-group\">\n <div className=\"dsha-grouphead\">\n <h3>{t.modelsSection}</h3>\n <button className=\"dsha-btn\" disabled={busy !== null} onClick={syncCatalog}>\n {busy === 'catalog' ? t.catalogSyncing : t.catalogSync}\n </button>\n </div>\n <p className=\"dsha-muted\" style={{ fontSize: 12 }}>{t.modelsHint}</p>\n <p className=\"dsha-muted\" style={{ fontSize: 12 }}>{t.wireNote}</p>\n {status !== null && status.models.length === 0 && (\n <div className=\"dsha-empty\">\n {status.catalogSynced ? t.catalogEmpty : t.catalogNeverSynced}\n </div>\n )}\n {status !== null && status.models.length === 0 && !status.usable && (\n <p className=\"dsha-muted\" style={{ fontSize: 12 }}>{t.catalogNeedKey}</p>\n )}\n {status !== null && status.models.length > 0 && (\n <>\n <p className=\"dsha-muted\" style={{ fontSize: 12 }}>\n {t.modelCount.replace('{count}', String(status.models.length))}\n </p>\n <ModelChecklist\n items={status.models.map((model) => ({\n id: model.id,\n name: model.name ?? model.id,\n enabled: isModelEnabled(model.id),\n }))}\n busy={busy !== null}\n onToggle={(id, enabled) => void toggleModel(id, enabled)}\n onToggleAll={(enabled) => void setAllModels(enabled)}\n labels={{ selectAll: t.selectAll, clearAll: t.unselectAll, list: t.modelsSection }}\n />\n </>\n )}\n </div>\n\n <div className=\"dsha-group\">\n <div className=\"dsha-grouphead\">\n <h3>{t.limitsSection}</h3>\n </div>\n <p className=\"dsha-muted\" style={{ fontSize: 12 }}>{t.limitsHint}</p>\n <ul className=\"dsha-notice\" style={{ paddingLeft: 18 }}>\n <li>{t.limitNoStateful}</li>\n <li>{t.limitNoWebSearch}</li>\n <li>{t.limitNoToolReplay}</li>\n <li>{t.limitUsage}</li>\n </ul>\n </div>\n </div>\n )\n}","/**\n * The hub's provider registry: one descriptor per subscription line.\n *\n * This is the single place the overview learns what a line is called, what\n * its card looks like, how its enable switch talks to the host, and which\n * section the detail page mounts. Adding a line to the hub means adding one\n * entry here — the overview, the navigation and the card rendering all read\n * this table.\n */\nimport type { ReactElement } from 'react'\nimport type { PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\nimport { ROUTE_PREFIX } from '../../compat.ts'\nimport { MINIMAX_CODE_ROUTE_PREFIX } from '../../shared/minimax-code-contracts.ts'\nimport { CodexSubscriptionSection } from '../CodexSubscriptionSection.tsx'\nimport { AntigravitySection } from '../antigravity/AntigravitySection.tsx'\nimport { CommandCodeSection } from '../command-code/CommandCodeSection.tsx'\nimport { KimiCodeSection } from '../kimi-code/KimiCodeSection.tsx'\nimport { WorkBuddySection } from '../workbuddy/WorkBuddySection.tsx'\nimport { MinimaxCodeSection } from '../minimax-code/MinimaxCodeSection.tsx'\nimport { ClaudeSection } from '../claude/ClaudeSection.tsx'\nimport { OllamaSection } from '../ollama/OllamaSection.tsx'\nimport type { HubProviderId } from './brand-icons.tsx'\n\n/** What the detail page hands to a mounted section. */\nexport interface HubDetailRenderProps {\n t: (key: any) => string\n onModelChange?: () => void\n /** The settings.section runtime props (close, etc.) the host slot passes in. */\n runtime: PropsRuntime<'settings.section'>\n}\n\nexport interface HubProviderDescriptor {\n id: HubProviderId\n /** Display name; brand names stay literal, matching the former tabs. */\n name: string\n /**\n * Commit an enable/disable to the line's own settings endpoint.\n *\n * The overview deliberately reuses each line's existing mutation route\n * rather than adding a second mutator to the aggregated overview route —\n * the aggregated route stays read-only, and every line keeps exactly one\n * place that writes its `enabled` flag. Null when the line has no switch.\n */\n setEnabled: ((enabled: boolean) => Promise<void>) | null\n renderDetail(props: HubDetailRenderProps): ReactElement\n}\n\n/** One POST to a line's settings endpoint, answered with that line's refreshed status. */\nasync function postLineSettings(prefix: string, body: Record<string, unknown>): Promise<void> {\n const response = await fetch(`${prefix}/settings`, {\n method: 'POST',\n credentials: 'same-origin',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(body),\n })\n const envelope = await response.json() as { ok: boolean; error?: { message?: string } | string }\n if (!response.ok || !envelope.ok) {\n const error = envelope.error\n throw new Error(typeof error === 'object' && error !== null ? error.message ?? 'Request failed' : String(error ?? 'Request failed'))\n }\n}\n\nasync function setChatGptEnabled(enabled: boolean): Promise<void> {\n const response = await fetch(`${ROUTE_PREFIX}/preferences/update`, {\n method: 'POST',\n credentials: 'same-origin',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ enabled }),\n })\n const envelope = await response.json() as { ok: boolean; error?: { message?: string } }\n if (!response.ok || !envelope.ok) throw new Error(envelope.error?.message ?? 'Request failed')\n}\n\n/** Card order on the overview; also the former tab order. */\nexport const HUB_PROVIDERS: readonly HubProviderDescriptor[] = [\n {\n id: 'chatgpt',\n name: 'ChatGPT',\n setEnabled: setChatGptEnabled,\n renderDetail: ({ t, runtime }) => <CodexSubscriptionSection t={t} {...runtime} />,\n },\n {\n id: 'antigravity',\n name: 'Antigravity',\n setEnabled: (enabled) => postLineSettings('/antigravity/api', { enabled }),\n renderDetail: ({ onModelChange }) => <AntigravitySection onModelChange={onModelChange} />,\n },\n {\n id: 'command-code',\n name: 'Command Code',\n setEnabled: (enabled) => postLineSettings('/command-code/api', { enabled }),\n renderDetail: ({ onModelChange }) => <CommandCodeSection onModelChange={onModelChange} />,\n },\n {\n id: 'kimi-code',\n name: 'Kimi Code',\n setEnabled: (enabled) => postLineSettings('/kimi-code/api', { enabled }),\n renderDetail: ({ onModelChange }) => <KimiCodeSection onModelChange={onModelChange} />,\n },\n {\n id: 'workbuddy',\n name: 'WorkBuddy',\n setEnabled: (enabled) => postLineSettings('/workbuddy/api', { enabled }),\n renderDetail: ({ onModelChange }) => <WorkBuddySection onModelChange={onModelChange} />,\n },\n {\n id: 'minimax-code',\n name: 'MiniMax Code',\n setEnabled: (enabled) => postLineSettings(MINIMAX_CODE_ROUTE_PREFIX, { enabled }),\n renderDetail: ({ onModelChange }) => <MinimaxCodeSection onModelChange={onModelChange} />,\n },\n {\n id: 'claude',\n name: 'Claude',\n setEnabled: (enabled) => postLineSettings('/claude/api', { enabled }),\n renderDetail: ({ onModelChange }) => <ClaudeSection onModelChange={onModelChange} />,\n },\n {\n id: 'ollama',\n name: 'Ollama',\n setEnabled: null,\n renderDetail: ({ onModelChange }) => <OllamaSection onModelChange={onModelChange} />,\n },\n]\n\nexport function hubProviderDescriptor(id: string): HubProviderDescriptor | undefined {\n return HUB_PROVIDERS.find((provider) => provider.id === id)\n}\n","/**\n * The hub's opening screen: one card per provider line, in the QQ-mail\n * account-picker idiom — a brand tile, the line's name, a one-line annotation\n * (accounts, models, state), and exactly two interactions per card: the\n * enable switch and drilling into the line's detail page.\n *\n * Data comes from the host's aggregated read-only overview route, so opening\n * the settings page costs one request and never touches an upstream service.\n * Switch commits go to each line's own settings endpoint (see providers.tsx)\n * and update optimistically; a failed commit rolls the switch back and says\n * so in the card's annotation line, where the user is already looking.\n */\nimport { useCallback, useEffect, useState } from 'react'\nimport type { PropsLocale } from '@deepseek-ai/dsh-client-ui-slots'\nimport type { ApiEnvelope } from '../../shared/contracts.ts'\nimport { HUB_OVERVIEW_PATH } from '../../shared/hub-contracts.ts'\nimport type { HubOverviewDto, HubProviderSummaryDto } from '../../shared/hub-contracts.ts'\nimport { formatPoolLabel } from '../common/account-pool-labels.ts'\nimport type { NS } from '../locales.ts'\nimport { BrandTile } from './brand-icons.tsx'\nimport { HUB_PROVIDERS, type HubProviderDescriptor } from './providers.tsx'\n\nexport type HubTranslate = PropsLocale<typeof NS>['t']\n\ninterface Props {\n t: HubTranslate\n onOpen(id: HubProviderDescriptor['id']): void\n}\n\nasync function fetchOverview(): Promise<HubOverviewDto> {\n const response = await fetch(HUB_OVERVIEW_PATH, { credentials: 'same-origin' })\n const envelope = await response.json() as ApiEnvelope<HubOverviewDto>\n if (!response.ok || !envelope.ok) {\n throw new Error(envelope.ok ? `Request failed (${response.status})` : envelope.error.message)\n }\n return envelope.value\n}\n\n/** The card's one-line annotation: accounts, then models, then state. */\nexport function cardAnnotation(summary: HubProviderSummaryDto | undefined, descriptor: HubProviderDescriptor, t: HubTranslate): string {\n if (summary === undefined) return '…'\n if (summary.error === true) return t('hubStatusFailed')\n const parts: string[] = []\n if (summary.canToggle && !summary.enabled) parts.push(t('hubStateDisabled'))\n parts.push(summary.accountCount > 0\n ? formatPoolLabel(t('hubAccountCount'), { count: summary.accountCount })\n : t('hubNoAccounts'))\n if (summary.enabledModelCount !== null) {\n parts.push(summary.totalModelCount !== null\n ? formatPoolLabel(t('hubModelsEnabledOfTotal'), { count: summary.enabledModelCount, total: summary.totalModelCount })\n : formatPoolLabel(t('hubModelsEnabled'), { count: summary.enabledModelCount }))\n }\n return parts.join(' · ')\n}\n\nexport function HubOverview({ t, onOpen }: Props): React.JSX.Element {\n const [summaries, setSummaries] = useState<ReadonlyMap<string, HubProviderSummaryDto> | null>(null)\n const [loadError, setLoadError] = useState<string | null>(null)\n const [busyId, setBusyId] = useState<string | null>(null)\n const [toggleErrors, setToggleErrors] = useState<ReadonlyMap<string, string>>(new Map())\n\n const load = useCallback(async (): Promise<void> => {\n try {\n const overview = await fetchOverview()\n setSummaries(new Map(overview.providers.map((provider) => [provider.id, provider])))\n setLoadError(null)\n } catch (error) {\n setLoadError(error instanceof Error ? error.message : String(error))\n }\n }, [])\n\n useEffect(() => {\n void load()\n }, [load])\n\n const toggle = useCallback(async (descriptor: HubProviderDescriptor, summary: HubProviderSummaryDto, enabled: boolean): Promise<void> => {\n if (descriptor.setEnabled === null) return\n setBusyId(descriptor.id)\n setToggleErrors((current) => {\n if (!current.has(descriptor.id)) return current\n const next = new Map(current)\n next.delete(descriptor.id)\n return next\n })\n // Optimistic: the switch flips now, the commit answers later.\n setSummaries((current) => new Map(current).set(descriptor.id, { ...summary, enabled }))\n try {\n await descriptor.setEnabled(enabled)\n // The commit did not carry the other lines' counts; refresh behind the\n // settled switch so the annotation stays exact.\n void load()\n } catch (error) {\n setSummaries((current) => new Map(current).set(descriptor.id, { ...summary, enabled: summary.enabled }))\n setToggleErrors((current) => new Map(current).set(descriptor.id, error instanceof Error ? error.message : String(error)))\n } finally {\n setBusyId(null)\n }\n }, [load])\n\n return <div className=\"dsh-hub-overview\">\n <p className=\"dsh-hub-hint\">{t('hubOverviewHint')}</p>\n {loadError !== null && summaries === null ? (\n <div className=\"dsh-codex-errorbar\" role=\"alert\">\n <span>{loadError}</span>\n <button type=\"button\" className=\"dsh-codex-button\" onClick={() => void load()}>{t('retry')}</button>\n </div>\n ) : (\n <div className=\"dsh-hub-cards\">\n {summaries === null ? HUB_PROVIDERS.map((descriptor) => (\n <div key={descriptor.id} className=\"dsh-hub-skeleton\" aria-hidden=\"true\">\n <i />\n <span style={{ flex: 1, display: 'flex', flexDirection: 'column' }}>\n <span className=\"dsh-hub-skel-name\" />\n <span className=\"dsh-hub-skel-note\" />\n </span>\n </div>\n )) : HUB_PROVIDERS.map((descriptor) => {\n const summary = summaries.get(descriptor.id)\n return <HubProviderCard\n key={descriptor.id}\n descriptor={descriptor}\n summary={summary}\n busy={busyId === descriptor.id}\n toggleError={toggleErrors.get(descriptor.id) ?? null}\n t={t}\n onOpen={onOpen}\n onToggle={toggle}\n />\n })}\n </div>\n )}\n </div>\n}\n\nconst CHEVRON_SVG = '<svg viewBox=\"0 0 16 16\" width=\"14\" height=\"14\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M6 4l4 4-4 4\"/></svg>'\n\nfunction HubProviderCard(props: {\n descriptor: HubProviderDescriptor\n summary: HubProviderSummaryDto | undefined\n busy: boolean\n toggleError: string | null\n t: HubTranslate\n onOpen(id: HubProviderDescriptor['id']): void\n onToggle(descriptor: HubProviderDescriptor, summary: HubProviderSummaryDto, enabled: boolean): Promise<void>\n}): React.JSX.Element {\n const { descriptor, summary, t } = props\n const enabled = summary?.enabled ?? true\n const annotation = props.toggleError ?? cardAnnotation(summary, descriptor, t)\n const canToggle = descriptor.setEnabled !== null && (summary?.canToggle ?? true)\n\n return <div\n role=\"button\"\n tabIndex={0}\n className=\"dsh-hub-card\"\n data-enabled={enabled}\n aria-label={formatPoolLabel(t('hubCardLabel'), { name: descriptor.name, annotation })}\n onClick={() => props.onOpen(descriptor.id)}\n onKeyDown={(event) => {\n if (event.key !== 'Enter' && event.key !== ' ') return\n if (event.target !== event.currentTarget) return\n event.preventDefault()\n props.onOpen(descriptor.id)\n }}\n >\n <BrandTile id={descriptor.id} />\n <span className=\"dsh-hub-card-copy\">\n <span className=\"dsh-hub-card-name\">{descriptor.name}</span>\n <span className={`dsh-hub-card-note${props.toggleError !== null || summary?.error === true ? ' dsh-hub-note-danger' : ''}`}>\n {annotation}\n </span>\n </span>\n <span className=\"dsh-hub-card-side\">\n {canToggle ? (\n <button\n type=\"button\"\n role=\"switch\"\n aria-checked={enabled}\n aria-label={formatPoolLabel(t(enabled ? 'hubSwitchOff' : 'hubSwitchOn'), { name: descriptor.name })}\n className=\"dsh-hub-switch\"\n disabled={props.busy || summary === undefined}\n onClick={(event) => {\n event.stopPropagation()\n if (summary === undefined) return\n void props.onToggle(descriptor, summary, !enabled)\n }}\n />\n ) : null}\n <span className=\"dsh-hub-chevron\" aria-hidden=\"true\" dangerouslySetInnerHTML={{ __html: CHEVRON_SVG }} />\n </span>\n </div>\n}\n","import { useCallback, useState } from 'react'\nimport type { PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\nimport { NS } from './locales.ts'\nimport { HubOverview } from './hub/HubOverview.tsx'\nimport { hubProviderDescriptor, HUB_PROVIDERS } from './hub/providers.tsx'\nimport type { HubProviderId } from './hub/brand-icons.tsx'\n\ntype Props = PropsRuntime<'settings.section'> & PropsLocale<typeof NS> & {\n onModelChange?: () => void\n}\n\ntype HubView = { view: 'overview' } | { view: 'detail'; id: HubProviderId }\n\nconst STORAGE_KEY = 'dsh-chatgpt-subscription:hub-view'\n\n/**\n * The detail page a user was last on survives a settings-page remount, so a\n * provider toggle deep in a detail page never throws them back to the\n * overview. Session storage, not local: a new browser session starts at the\n * overview, which is the page's whole point.\n */\nfunction readStoredView(): HubView {\n try {\n const raw = sessionStorage.getItem(STORAGE_KEY)\n if (raw === null) return { view: 'overview' }\n const parsed = JSON.parse(raw) as { view?: string; id?: string }\n if (parsed.view !== 'detail' || typeof parsed.id !== 'string') return { view: 'overview' }\n // A provider the registry no longer knows (renamed, removed) falls back\n // to the overview rather than stranding the page on an empty panel.\n return hubProviderDescriptor(parsed.id) === undefined ? { view: 'overview' } : { view: 'detail', id: parsed.id as HubProviderId }\n } catch {\n return { view: 'overview' }\n }\n}\n\nfunction storeView(view: HubView): void {\n try {\n sessionStorage.setItem(STORAGE_KEY, JSON.stringify(view))\n } catch {\n // Storage can be unavailable (private mode); navigation still works.\n }\n}\n\nconst BACK_SVG = '<svg viewBox=\"0 0 16 16\" width=\"14\" height=\"14\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M10 4l-4 4 4 4\"/></svg>'\n\n/**\n * Single settings page hosting every subscription provider. The opening\n * screen is the overview — one card per line with its enable switch and\n * account count — and picking a card replaces it with that line's detail\n * page under a back bar. Only the active view is mounted, mirroring the\n * shell's behavior of mounting just the selected settings page (each\n * provider section refetches its status on mount).\n */\nexport function ProviderHubSection({ t, onModelChange, ...runtime }: Props): React.JSX.Element {\n const [view, setView] = useState<HubView>(readStoredView)\n\n const open = useCallback((id: HubProviderId): void => {\n const next: HubView = { view: 'detail', id }\n storeView(next)\n setView(next)\n }, [])\n\n const back = useCallback((): void => {\n const next: HubView = { view: 'overview' }\n storeView(next)\n setView(next)\n }, [])\n\n if (view.view === 'overview') {\n return <section className=\"dsh-codex-page\" aria-labelledby=\"dsh-hub-title\">\n <header>\n <h2 id=\"dsh-hub-title\" className=\"dsh-codex-title\">{t('hubTitle')}</h2>\n </header>\n {/* The overview's whole job is the cards. A local sign-in belongs to the\n ONE provider whose account pool it would join, so it lives on that\n provider's detail page next to its own rows: an overview that answered\n for three providers at once had to tell users to visit the page they\n were already one click away from. */}\n <HubOverview t={t} onOpen={open} />\n </section>\n }\n\n const descriptor = hubProviderDescriptor(view.id) ?? HUB_PROVIDERS[0]\n return <section className=\"dsh-codex-page\" aria-labelledby=\"dsh-hub-detail-name\">\n <nav className=\"dsh-hub-backbar\">\n <button type=\"button\" className=\"dsh-hub-back\" onClick={back} aria-label={t('hubBack')}>\n <span aria-hidden=\"true\" dangerouslySetInnerHTML={{ __html: BACK_SVG }} />\n {t('hubBack')}\n </button>\n <span className=\"dsh-hub-backbar-name\" id=\"dsh-hub-detail-name\">{descriptor.name}</span>\n </nav>\n <div className=\"dsh-hub-detail\">\n {descriptor.renderDetail({ t, onModelChange, runtime })}\n </div>\n </section>\n}\n","export const NS = 'dsh-chatgpt-subscription' as const\n\nimport { accountPoolEn, accountPoolZh } from './common/account-pool-labels.ts'\n\nexport const zh = {\n // The account-management card is shared with every other provider tab, so its\n // labels live in one place and are translated through this tab's dictionary.\n ...accountPoolZh,\n title: 'ChatGPT',\n hubTitle: '订阅服务',\n intro: '使用 ChatGPT 账号登录,在 DSH 中使用订阅可用的模型。',\n account: '账号',\n signedOut: '尚未登录',\n signedIn: '已登录',\n plan: '套餐',\n accountId: '账号 ID',\n expires: '令牌到期',\n signIn: '使用 ChatGPT 登录',\n signInAgain: '重新登录',\n cancel: '取消登录',\n signOut: '注销',\n refreshToken: '刷新凭据',\n pending: '请在浏览器中完成登录。',\n popupBlocked: '浏览器拦截了登录窗口,请使用下面的链接继续。',\n continueLogin: '打开 ChatGPT 登录页',\n loading: '正在读取状态…',\n connection: '连接',\n testConnection: '测试连接',\n testing: '测试中…',\n latency: '最近延迟',\n selectAll: '全选',\n unselectAll: '全不选',\n models: '可用模型',\n modelsHint: '勾选后模型才会显示在对话页的模型选择列表中;全部取消勾选或关闭上方开关可在列表中隐藏该供应商。',\n proxySettings: '网络代理',\n proxyMode: '代理模式',\n proxyModeHint: 'GPT 与 Antigravity(Gemini)共用此代理设置;支持自动读取系统代理,修改后对后续请求生效。',\n proxyModeAuto: '系统代理(自动检测)',\n proxyModeCustom: '自定义代理',\n proxyModeDirect: '直连(禁用代理)',\n customProxyUrl: '自定义代理地址',\n customProxyUrlHint: '支持 HTTP/HTTPS/SOCKS5 代理地址,例如 http://127.0.0.1:7890',\n customProxyUrlPlaceholder: '例如: http://127.0.0.1:7890',\n saveProxyUrl: '保存代理地址',\n proxyDetected: '检测到系统代理',\n proxyDetectedEffective: '(已自动生效)',\n proxyNoneDetected: '未检测到系统代理,将使用直连',\n proxyDirectHint: '所有网络请求将直接连接,不经过任何代理服务器。',\n enhancements: '增强功能',\n fastMode: '快速模式(1.5x 速度)',\n fastModeHint: '提升 Token 生成速度至约 1.5 倍;将以约 2x–2.5x 速度消耗 Codex 订阅额度。',\n outputVerbosity: '输出详细程度',\n outputVerbosityHint: '控制 Codex 最终回答的详细程度;不影响思考深度。默认值与官方 Codex 客户端一致(低)。',\n verbosityLow: '低(保持回答简洁)',\n verbosityMedium: '中(兼顾细节与简洁)',\n verbosityHigh: '高(在回答中包含更多细节)',\n reasoningSummary: '推理摘要',\n reasoningSummaryHint: '选择 ChatGPT 总结其推理的方式;不影响思考深度。默认值与官方 Codex 客户端一致(不生成摘要,可省额度)。',\n summaryAuto: '自动(让模型选择摘要详细程度)',\n summaryConcise: '简洁(显示简要推理摘要)',\n summaryDetailed: '详细(显示更详细的推理摘要)',\n summaryNone: '无(不显示推理摘要)',\n searchProvider: '搜索来源',\n searchProviderHint: '选择 DSH 联网搜索使用默认来源,或改用当前 ChatGPT 订阅的 Codex 来源(自动走代理隧道)。抓取模式为 auto 时,抓取来源跟随此选择。',\n searchProviderDsh: 'DSH 默认',\n searchProviderCodex: 'ChatGPT(代理隧道)',\n fetchStatus: '抓取来源(只读)',\n fetchStatusHint: '以下内容由 Host 上报,只读展示。',\n fetchConfiguredProvider: '配置的抓取 Provider',\n fetchProviderDshDefault: 'DSH 默认(Host 未固定抓取 provider)',\n switcherState: '抓取选择器状态',\n switcherStateIdle: '空闲(尚未应用选择)',\n switcherStateApplying: '应用中(正在切换 Host 的 web provider)',\n switcherStateApplied: '已应用',\n switcherStateMissing: '未找到可切换的 web 服务',\n switcherStateFailed: '切换失败,请检查 Host 日志',\n fetchMode: '抓取模式',\n fetchModeAuto: 'auto(有可用代理或选了 ChatGPT 搜索时用插件抓取)',\n fetchModePlugin: 'plugin(始终用本插件抓取)',\n fetchModeDsh: 'dsh(保留 DSH 原有抓取来源)',\n fetchMaxBodyChars: '插件正文上限',\n fetchMaxResponseBytes: '插件响应体上限',\n characters: '字符',\n bytes: '字节',\n fetchLimitsInactive: '仅在实际使用插件抓取时生效;走 DSH 原有抓取来源时不适用这两个上限。',\n fetchConfigSource: '模式与上限在插件 Config 中修改(不是本页面偏好),修改后重载插件或重启 DSH 生效。',\n providerDefault: '使用 Provider 默认值',\n contextWindows: '模型上下文窗口',\n contextWindowsHint: '只列出已勾选「可用模型」的条目。默认取模型目录值(GPT-6 系列 384K,最高 872K;其余最高 1M),该值用于 DSH 的压缩与溢出判断,可输入 872K、512K 等容量;改过的模型可单独或一键恢复默认。',\n contextWindow: '上下文窗口',\n contextWindowInvalid: '上下文窗口必须是正整数,且不能超过模型上限(GPT-6 系列为 872K,其余为 1M);可使用 K 或 M 后缀。',\n contextWindowReset: '恢复默认',\n contextWindowResetAll: '全部恢复默认',\n contextWindowResetAllConfirm: '确定把已改过的模型上下文窗口全部恢复为默认值吗?',\n contextWindowsNoneEnabled: '还没有勾选任何模型。在上方「可用模型」里勾选后,这里会出现该模型的上下文窗口设置。',\n saveContextWindow: '保存上下文窗口',\n save: '保存',\n tokens: 'tokens',\n quickQuota: '在输入框旁显示快捷用量',\n quickQuotaHint: '仅在当前会话选中 codex-chatgpt 模型时显示。',\n quota: '用量与限额',\n quotaIntro: '数据来自 ChatGPT Codex 用量服务。页面可见时最多每 60 秒刷新一次。',\n refreshQuota: '刷新用量',\n refreshing: '刷新中…',\n noQuota: '当前套餐未返回可显示的限额窗口。',\n quotaSignedOut: '登录后可查看订阅限额。',\n stale: '显示的是上次成功获取的数据。',\n updated: '更新时间',\n primary: '主要窗口',\n secondary: '次要窗口',\n limitWindow: '额度',\n used: '已使用',\n remaining: '剩余',\n available: '可用',\n unavailable: '不可用',\n unlimited: '无限',\n credits: 'Credits',\n monthlySpend: '月度消费控制',\n resetCredits: '重置次数',\n resetCreditExpires: '到期时间',\n useResetCredit: '使用重置卡',\n usingResetCredit: '使用中…',\n useResetCreditConfirm: '使用后会立即消耗 1 次重置机会,并重置符合条件的 Codex 额度窗口。确定继续吗?',\n resetCreditUsed: '重置卡已使用,用量数据已刷新。',\n spendControlReached: '已触发月度消费控制,新的订阅调用可能被限制。',\n limit: '上限',\n exhausted: '额度已用尽',\n resets: '重置',\n quickQuotaLabel: 'Codex 剩余',\n quickQuotaLoading: '用量…',\n imageToolRunning: '正在生成图片',\n imageToolDone: '已生成图片',\n imageToolFailed: '图片生成失败',\n image: '图片',\n openImage: '打开图片',\n openNamedImage: '打开 {name}',\n imageLoading: '加载图片…',\n imageLoadFailed: '图片加载失败,点击重试',\n imagePreviewClose: '关闭',\n imagePreviewOpenOriginal: '打开原图',\n retry: '重试',\n unknown: '未知',\n // The hub overview: the settings page's opening screen.\n hubBack: '订阅服务',\n hubOverviewHint: '选择供应商以管理账号、模型与配额;右侧开关控制该供应商是否出现在模型列表中。',\n hubAccountCount: '{count} 个账号',\n hubNoAccounts: '暂无账号,点击进入添加',\n hubStateEnabled: '已启用',\n hubStateDisabled: '已停用',\n hubModelsEnabled: '{count} 个模型可用',\n hubModelsEnabledOfTotal: '{count}/{total} 个模型可用',\n hubStatusFailed: '状态读取失败',\n hubSwitchOn: '启用 {name}',\n hubSwitchOff: '停用 {name}',\n hubCardLabel: '{name},{annotation}',\n // The import button that sits beside 登录 in the account pool's login row.\n // Two labels and nothing else: the button says what it does, the row it sits in\n // says where it goes, and the Claude section's own import button is worded the\n // same way because the two are the same decision.\n localCodexLoginImport: '导入本机 Codex CLI 登录',\n localCodexLoginImporting: '导入中…',\n // The account pool's undo for the local sign-in imported just above it. The\n // wording says \"all\" because the host's route clears every imported row at once:\n // a label reading like a per-row action would promise something the pool forbids.\n stopImporting: '停止导入全部本机登录',\n stopImportingLabel: '停止导入全部本机登录(当前 {count} 个)',\n stopImportingBusy: '停止导入中…',\n stopImportingHint: '停止导入只会让本插件忘记本机 CLI 登录的副本;Codex CLI 自己的登录文件不会被删除或修改。账号池不允许逐条删除借来的凭据,所以这里一次会停止全部导入。',\n modelChecklistCount: '已启用 {count}/{total}',\n} as const\n\nexport const en: Record<keyof typeof zh, string> = {\n ...accountPoolEn,\n title: 'ChatGPT',\n hubTitle: 'Subscriptions',\n intro: 'Sign in with ChatGPT to use models available to your subscription in DSH.',\n account: 'Account',\n signedOut: 'Not signed in',\n signedIn: 'Signed in',\n plan: 'Plan',\n accountId: 'Account ID',\n expires: 'Token expires',\n signIn: 'Sign in with ChatGPT',\n signInAgain: 'Sign in again',\n cancel: 'Cancel sign-in',\n signOut: 'Sign out',\n refreshToken: 'Refresh credentials',\n pending: 'Complete sign-in in your browser.',\n popupBlocked: 'The sign-in window was blocked. Use the link below to continue.',\n continueLogin: 'Open ChatGPT sign-in',\n loading: 'Reading status…',\n connection: 'Connection',\n testConnection: 'Test connection',\n testing: 'Testing…',\n latency: 'Last latency',\n selectAll: 'Select all',\n unselectAll: 'Unselect all',\n models: 'Available models',\n modelsHint: 'Checked models appear in the conversation model picker; unchecking all or turning off the switch hides this provider from the picker.',\n proxySettings: 'Network Proxy',\n proxyMode: 'Proxy Mode',\n proxyModeHint: 'GPT and Antigravity (Gemini) share these proxy settings. Supports system proxy detection; changes apply to subsequent requests.',\n proxyModeAuto: 'System Proxy (Auto-detect)',\n proxyModeCustom: 'Custom Proxy',\n proxyModeDirect: 'Direct (No Proxy)',\n customProxyUrl: 'Custom Proxy URL',\n customProxyUrlHint: 'Supports HTTP/HTTPS/SOCKS5 proxy URLs, e.g. http://127.0.0.1:7890',\n customProxyUrlPlaceholder: 'e.g. http://127.0.0.1:7890',\n saveProxyUrl: 'Save Proxy URL',\n proxyDetected: 'Detected system proxy',\n proxyDetectedEffective: ' (active)',\n proxyNoneDetected: 'No system proxy detected; connecting directly',\n proxyDirectHint: 'All requests connect directly without using any proxy server.',\n enhancements: 'Enhancements',\n fastMode: 'Fast mode (1.5x speed)',\n fastModeHint: 'Generates tokens ~1.5x faster; consumes Codex subscription quota at ~2x–2.5x the normal rate.',\n outputVerbosity: 'Output verbosity',\n outputVerbosityHint: 'Controls the detail level of final Codex answers without changing reasoning effort. The default matches the official Codex client (low).',\n verbosityLow: 'Low (keep answers concise)',\n verbosityMedium: 'Medium (balance detail and brevity)',\n verbosityHigh: 'High (include more detail)',\n reasoningSummary: 'Reasoning summary',\n reasoningSummaryHint: 'Controls how ChatGPT summarizes its chain of thought; does not change reasoning depth. The default matches the official Codex client (no summary, which saves quota).',\n summaryAuto: 'Auto (let model determine detail)',\n summaryConcise: 'Concise (brief summary)',\n summaryDetailed: 'Detailed (in-depth summary)',\n summaryNone: 'None (hide reasoning summary)',\n searchProvider: 'Search provider',\n searchProviderHint: 'Choose whether DSH web search uses the default provider or the Codex proxy-backed source from this ChatGPT subscription. Fetch mode \"auto\" follows this choice.',\n searchProviderDsh: 'DSH default',\n searchProviderCodex: 'ChatGPT (Proxy tunnel)',\n fetchStatus: 'Fetch source (read-only)',\n fetchStatusHint: 'Reported by the host. Read-only.',\n fetchConfiguredProvider: 'Configured fetch provider',\n fetchProviderDshDefault: 'DSH default (the host pins no fetch provider)',\n switcherState: 'Fetch switcher state',\n switcherStateIdle: 'Idle (no selection applied yet)',\n switcherStateApplying: 'Applying (host web provider switch in progress)',\n switcherStateApplied: 'Applied',\n switcherStateMissing: 'No web service found to switch',\n switcherStateFailed: 'Switch failed, check the host log',\n fetchMode: 'Fetch mode',\n fetchModeAuto: 'auto (fetches with the plugin when a proxy is available or the ChatGPT search source is selected)',\n fetchModePlugin: 'plugin (always fetch with this plugin)',\n fetchModeDsh: 'dsh (keep the DSH default fetch source)',\n fetchMaxBodyChars: 'Plugin body limit',\n fetchMaxResponseBytes: 'Plugin response limit',\n characters: 'chars',\n bytes: 'bytes',\n fetchLimitsInactive: 'Only applied when the plugin actually fetches; the DSH default fetch source does not use these two limits.',\n fetchConfigSource: 'Mode and limits are changed in the plugin Config, not in these settings; they take effect after a plugin reload or a DSH restart.',\n providerDefault: 'Use provider default',\n contextWindows: 'Model context windows',\n contextWindowsHint: 'Lists the models checked under Available models. Each starts at its catalog value (384K for the GPT-6 family, up to 872K; up to 1M otherwise); DSH uses it for compaction and overflow detection. Values such as 872K and 512K are accepted, and a changed model can be restored one by one or all at once.',\n contextWindow: 'Context window',\n contextWindowInvalid: 'The context window must be a positive integer within the model limit (872K for the GPT-6 family, 1M otherwise). K and M suffixes are accepted.',\n contextWindowReset: 'Restore default',\n contextWindowResetAll: 'Restore all defaults',\n contextWindowResetAllConfirm: 'Restore every changed model context window to its default?',\n contextWindowsNoneEnabled: 'No model is checked yet. Check one under Available models above and its context window setting appears here.',\n saveContextWindow: 'Save context window',\n save: 'Save',\n tokens: 'tokens',\n quickQuota: 'Show quick usage beside the composer',\n quickQuotaHint: 'Shown only when the current session uses a codex-chatgpt model.',\n quota: 'Usage and limits',\n quotaIntro: 'Data comes from the ChatGPT Codex usage service and refreshes at most once per minute while visible.',\n refreshQuota: 'Refresh usage',\n refreshing: 'Refreshing…',\n noQuota: 'Your plan did not return any displayable limit windows.',\n quotaSignedOut: 'Sign in to view subscription limits.',\n stale: 'Showing the last successfully fetched data.',\n updated: 'Updated',\n primary: 'Primary window',\n secondary: 'Secondary window',\n limitWindow: 'limit',\n used: 'used',\n remaining: 'remaining',\n available: 'Available',\n unavailable: 'Unavailable',\n unlimited: 'Unlimited',\n credits: 'Credits',\n monthlySpend: 'Monthly spend control',\n resetCredits: 'Reset credits',\n resetCreditExpires: 'Expires',\n useResetCredit: 'Use reset credit',\n usingResetCredit: 'Using…',\n useResetCreditConfirm: 'This immediately spends one reset credit and resets eligible Codex limit windows. Continue?',\n resetCreditUsed: 'The reset credit was used and usage data was refreshed.',\n spendControlReached: 'Monthly spend control has been reached; new subscription calls may be limited.',\n limit: 'Limit',\n exhausted: 'Quota exhausted',\n resets: 'Resets',\n quickQuotaLabel: 'Codex left',\n quickQuotaLoading: 'Usage…',\n imageToolRunning: 'Generating image',\n imageToolDone: 'Generated image',\n imageToolFailed: 'Image generation failed',\n image: 'Image',\n openImage: 'Open image',\n openNamedImage: 'Open {name}',\n imageLoading: 'Loading image…',\n imageLoadFailed: 'Image failed to load. Click to retry',\n imagePreviewClose: 'Close',\n imagePreviewOpenOriginal: 'Open original',\n retry: 'Retry',\n unknown: 'Unknown',\n // The hub overview: the settings page's opening screen.\n hubBack: 'Subscriptions',\n hubOverviewHint: 'Pick a provider to manage its accounts, models and quota. The switch controls whether it appears in the model picker.',\n hubAccountCount: '{count} accounts',\n hubNoAccounts: 'No accounts yet — open to add one',\n hubStateEnabled: 'Enabled',\n hubStateDisabled: 'Disabled',\n hubModelsEnabled: '{count} models available',\n hubModelsEnabledOfTotal: '{count}/{total} models available',\n hubStatusFailed: 'Status unavailable',\n hubSwitchOn: 'Enable {name}',\n hubSwitchOff: 'Disable {name}',\n hubCardLabel: '{name}, {annotation}',\n // The import button that sits beside 登录 in the account pool's login row.\n // Two labels and nothing else: the button says what it does, the row it sits in\n // says where it goes, and the Claude section's own import button is worded the\n // same way because the two are the same decision.\n localCodexLoginImport: 'Import the local Codex CLI sign-in',\n localCodexLoginImporting: 'Importing…',\n // The account pool's undo for the local sign-in imported just above it. The\n // wording says \"all\" because the host's route clears every imported row at once:\n // a label reading like a per-row action would promise something the pool forbids.\n stopImporting: 'Stop importing all local sign-ins',\n stopImportingLabel: 'Stop importing all local sign-ins ({count} currently imported)',\n stopImportingBusy: 'Stopping the import…',\n stopImportingHint: 'Stopping the import only makes this plugin forget its copy of the local CLI sign-in; the Codex CLI own sign-in file is never deleted or changed. The account pool does not allow deleting a borrowed credential one at a time, so this stops every import at once.',\n modelChecklistCount: '{count}/{total} enabled',\n}\n\nexport type LocaleKey = keyof typeof zh\nexport const dictionaries = { zh, en }\n","/**\n * Shared installer for every stylesheet this plugin injects.\n *\n * The DSH client module system books stylesheet ownership by attribute. When a\n * package's factory materializes it claims every untagged `<style>` in the\n * document for itself (`style:not([data-plugin])` gains that package's id); when\n * a package reloads, is replaced at a new revision, or is pruned from the graph,\n * it removes every tag carrying its id. A sheet injected as a plain\n * `<style id=…>` therefore gets claimed by whichever sibling package\n * materializes next and is then deleted as that sibling's bookkeeping — which is\n * how the whole shared provider design system (`.dsha-*`) disappeared from the\n * settings page while the already-tagged chat-only `…/main` sheet survived.\n *\n * Tagging every sheet with this package's own `data-plugin` and a unique\n * `data-plugin-css` keeps the module system from attributing it to another\n * package, and re-running the installer on every `apply()` restores it after one\n * of our own reloads. The tag is owned by the document: the installer refreshes\n * stale text but never removes the element, so a stale fiber's teardown can\n * never take the styles away.\n */\nexport const PLUGIN_ID = '@eddyskywalker/dsh-chatgpt-subscription'\n\nexport function installPluginStyle(name: string, css: string, legacyId?: string): () => void {\n if (typeof document === 'undefined') return () => undefined\n const pluginCss = `${PLUGIN_ID}/${name}`\n let element = document.querySelector<HTMLStyleElement>(`style[data-plugin-css=\"${pluginCss}\"]`)\n // A bundle predating the ownership tags injected a plain tag; adopt that\n // element instead of stacking a second copy of the same CSS on the page.\n element ??= legacyId === undefined ? null : document.getElementById(legacyId) as HTMLStyleElement | null\n if (element === null) {\n element = document.createElement('style')\n if (legacyId !== undefined) element.id = legacyId\n document.head.appendChild(element)\n }\n element.dataset.plugin = PLUGIN_ID\n element.dataset.pluginCss = pluginCss\n if (element.textContent !== css) element.textContent = css\n return () => undefined\n}\n","import { installPluginStyle } from './common/plugin-style.ts'\n\nconst CSS = `\n.dsh-codex-page{box-sizing:border-box;color:var(--dsw-alias-label-primary);display:flex;flex-direction:column;gap:20px;max-width:780px;min-width:0;padding:2px 0 30px}\n.dsh-codex-page *{box-sizing:border-box}\n.dsh-codex-title{font-size:15px;font-weight:650;line-height:1.4;margin:0 0 5px}\n.dsh-codex-intro,.dsh-codex-muted{color:var(--dsw-alias-label-secondary);font-size:13px;line-height:1.55;margin:0}\n.dsh-codex-group{border-top:0.5px solid var(--dsw-alias-border-l2);min-width:0}\n.dsh-codex-grouphead{align-items:center;display:flex;gap:12px;justify-content:space-between;min-height:48px}\n.dsh-codex-grouphead h3{font-size:14px;font-weight:650;margin:0}\n.dsh-codex-row{align-items:center;border-bottom:0.5px solid var(--dsw-alias-border-l2);display:flex;gap:20px;justify-content:space-between;min-height:44px;padding:8px 0}\n.dsh-codex-label{color:var(--dsw-alias-label-secondary);font-size:13px;flex:0 0 auto}\n.dsh-codex-value{font-size:13px;min-width:0;overflow-wrap:anywhere;text-align:right}\n.dsh-codex-actions{display:flex;flex-wrap:wrap;gap:8px;justify-content:flex-end;padding-top:12px}\n.dsh-codex-button{background:var(--dsw-alias-bg-layer-2);border:0.5px solid var(--dsw-alias-border-l2);border-radius:999px;corner-shape:round;color:var(--dsw-alias-label-primary);cursor:pointer;font:inherit;font-size:13px;line-height:1;padding:8px 13px;white-space:nowrap}\n.dsh-codex-button:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}\n.dsh-codex-button:focus-visible,.dsh-codex-link:focus-visible{outline:2px solid var(--dsw-alias-button-info-fill,#397ee8);outline-offset:2px}\n.dsh-codex-button:disabled{cursor:default;opacity:.5}\n.dsh-codex-button-primary{background:var(--dsw-alias-button-info-fill,#397ee8);border-color:transparent;color:var(--dsw-alias-button-info-label,#fff)}\n.dsh-codex-notice{background:var(--dsw-alias-bg-layer-2);border:0.5px solid var(--dsw-alias-border-l2);border-radius:7px;color:var(--dsw-alias-label-secondary);font-size:12px;line-height:1.55;margin:12px 0 0;padding:10px 12px}\n.dsh-codex-error,.dsh-codex-warning,.dsh-codex-success{font-size:12px;line-height:1.5;margin:8px 0 0}\n.dsh-codex-error{color:var(--dsw-alias-label-danger,#d94b4b)}\n.dsh-codex-warning{color:var(--dsw-alias-label-warning,#c77a18)}\n.dsh-codex-success{color:var(--dsw-alias-label-success,#2e9b62)}\n.dsh-codex-errorbar{align-items:center;background:color-mix(in srgb,var(--dsw-alias-label-danger,#d94b4b) 9%,transparent);border:0.5px solid color-mix(in srgb,var(--dsw-alias-label-danger,#d94b4b) 28%,transparent);border-radius:7px;color:var(--dsw-alias-label-danger,#d94b4b);display:flex;font-size:13px;gap:12px;justify-content:space-between;padding:10px 12px}\n.dsh-codex-link{color:var(--dsw-alias-label-link,#3278d4);display:inline-block;font-size:13px;margin-top:8px}\n.dsh-codex-pref-row{align-items:center;border-bottom:0.5px solid var(--dsw-alias-border-l2);display:flex;gap:16px;justify-content:space-between;min-height:58px;padding:10px 0}\n.dsh-codex-pref-row strong,.dsh-codex-check strong{display:block;font-size:13px;font-weight:600;line-height:1.35}\n.dsh-codex-segments{background:var(--dsw-alias-bg-layer-2);border:0.5px solid var(--dsw-alias-border-l2);border-radius:8px;display:inline-flex;flex-wrap:nowrap;gap:3px;padding:3px}\n.dsh-codex-segments label{cursor:pointer;display:block;margin:0}\n.dsh-codex-segments input{position:absolute;opacity:0;pointer-events:none}\n.dsh-codex-segments span,.dsh-codex-segments button{border:0.5px solid transparent;border-radius:6px;color:var(--dsw-alias-label-secondary);display:block;font:inherit;font-size:12px;font-weight:500;line-height:1.2;padding:6px 12px;transition:all .15s ease;user-select:none;white-space:nowrap}\n.dsh-codex-segments button{background:transparent;cursor:pointer}\n.dsh-codex-segments label:hover span,.dsh-codex-segments button:hover:not(:disabled){color:var(--dsw-alias-label-primary)}\n.dsh-codex-segments input:checked+span,.dsh-codex-segments button.active,.dsh-codex-segments button[aria-pressed=true]{background:color-mix(in srgb,var(--dsw-alias-button-info-fill,#397ee8) 22%,var(--dsw-alias-bg-layer-2));border-color:color-mix(in srgb,var(--dsw-alias-button-info-fill,#397ee8) 60%,var(--dsw-alias-border-l2));color:var(--dsw-alias-label-primary);font-weight:600;box-shadow:0 1px 3px rgba(0,0,0,.15)}\n.dsh-codex-segments input:focus-visible+span,.dsh-codex-segments button:focus-visible{outline:2px solid var(--dsw-alias-button-info-fill,#397ee8);outline-offset:2px}\n.dsh-codex-segments input:disabled+span,.dsh-codex-segments button:disabled{cursor:default;opacity:.5}\n.dsh-codex-select,.dsh-codex-capacity-control input{background:var(--dsw-alias-bg-layer-2);border:0.5px solid var(--dsw-alias-border-l2);border-radius:7px;color:var(--dsw-alias-label-primary);font:inherit;font-size:12px;padding:7px 9px}\n.dsh-codex-select{max-width:210px;min-width:150px}\n.dsh-codex-context-settings{border-bottom:0.5px solid var(--dsw-alias-border-l2);display:grid;gap:10px;padding:12px 0}\n.dsh-codex-context-settings>div>strong{font-size:13px;font-weight:600}\n.dsh-codex-context-row{align-items:center;display:flex;font-size:12px;gap:14px;justify-content:space-between}\n.dsh-codex-proxy-control{align-items:center;display:flex;gap:8px;width:100%}\n.dsh-codex-proxy-control input{background:var(--dsw-alias-bg-layer-2);border:0.5px solid var(--dsw-alias-border-l2);border-radius:7px;color:var(--dsw-alias-label-primary);flex:1;font:inherit;font-family:ui-monospace,SFMono-Regular,Consolas,monospace;font-size:12px;min-width:220px;padding:7px 10px;text-align:left}\n.dsh-codex-proxy-status{align-items:center;color:var(--dsw-alias-label-secondary);display:flex;flex-wrap:wrap;font-size:12px;gap:6px;margin:6px 0 0}\n.dsh-codex-proxy-tag{background:color-mix(in srgb,var(--dsw-alias-button-info-fill,#397ee8) 18%,transparent);border:0.5px solid color-mix(in srgb,var(--dsw-alias-button-info-fill,#397ee8) 45%,transparent);border-radius:4px;color:var(--dsw-alias-label-primary);font-family:ui-monospace,SFMono-Regular,Consolas,monospace;font-size:11px;padding:2px 6px}\n.dsh-codex-capacity-control{align-items:center;display:flex;gap:7px}\n.dsh-codex-capacity-control input{font-family:ui-monospace,SFMono-Regular,Consolas,monospace;text-align:right;width:90px}\n.dsh-codex-capacity-control input[type=number]{width:110px}\n.dsh-codex-capacity-control small{color:var(--dsw-alias-label-tertiary);font-size:11px;width:42px}\n.dsh-codex-context-save{background:var(--dsw-alias-bg-layer-2);border:0.5px solid var(--dsw-alias-border-l2);border-radius:7px;color:var(--dsw-alias-label-primary);cursor:pointer;font:inherit;font-size:12px;line-height:1;padding:8px 10px;white-space:nowrap}\n.dsh-codex-context-save:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}\n.dsh-codex-context-save:focus-visible{outline:2px solid var(--dsw-alias-button-info-fill,#397ee8);outline-offset:2px}\n.dsh-codex-context-save:disabled{cursor:default;opacity:.45}\n.dsh-codex-check{align-items:flex-start;border-bottom:0.5px solid var(--dsw-alias-border-l2);cursor:pointer;display:flex;gap:10px;padding:12px 0}\n.dsh-codex-check input{flex:none;margin-top:2px}\n.dsh-codex-check small{color:var(--dsw-alias-label-secondary);display:block;font-size:12px;line-height:1.45;margin-top:2px}\n.dsh-codex-quota-card{background:var(--dsw-alias-bg-layer-2);border:0.5px solid var(--dsw-alias-border-l2);border-radius:8px;margin-top:12px;padding:12px}\n.dsh-codex-quota-title{align-items:center;display:flex;font-size:13px;gap:8px;justify-content:space-between}\n.dsh-codex-quota-title span{color:var(--dsw-alias-label-tertiary);font-size:11px;text-transform:uppercase}\n.dsh-codex-quota-fact{align-items:flex-start;border-bottom:0.5px solid var(--dsw-alias-border-l2);display:flex;font-size:12px;gap:12px;justify-content:space-between;line-height:1.45;padding:10px 0}\n.dsh-codex-quota-fact span{color:var(--dsw-alias-label-secondary);flex:none}\n.dsh-codex-quota-fact strong{font-weight:600;min-width:0;overflow-wrap:anywhere;text-align:right}\n.dsh-codex-reset-credits{align-items:center;border-bottom:0.5px solid var(--dsw-alias-border-l2);display:flex;gap:16px;justify-content:space-between;padding:10px 0}\n.dsh-codex-reset-credits-info{display:grid;font-size:12px;gap:2px;grid-template-columns:auto auto}\n.dsh-codex-reset-credits-info>span{color:var(--dsw-alias-label-secondary)}\n.dsh-codex-reset-credits-info>strong{font-weight:650;text-align:right}\n.dsh-codex-reset-credits-info>small{color:var(--dsw-alias-label-tertiary);font-size:11px;grid-column:1/-1}\n.dsh-codex-meter-wrap{margin-top:13px}\n.dsh-codex-meter-label,.dsh-codex-meter-meta{display:flex;gap:10px;justify-content:space-between}\n.dsh-codex-meter-label{font-size:12px;margin-bottom:6px}\n.dsh-codex-meter-meta{color:var(--dsw-alias-label-tertiary);font-size:11px;line-height:1.45;margin-top:6px}\n.dsh-codex-meter{background:var(--dsw-alias-bg-layer-1,rgba(127,127,127,.15));border-radius:999px;corner-shape:round;height:7px;overflow:hidden;width:100%}\n.dsh-codex-meter>span{background:var(--dsw-alias-button-info-fill,#397ee8);border-radius:inherit;display:block;height:100%;max-width:100%;min-width:0;transition:width .25s ease}\n.dsh-codex-meter-warning>span{background:var(--dsw-alias-label-warning,#d58a24)}\n.dsh-codex-meter-danger>span{background:var(--dsw-alias-label-danger,#d94b4b)}\n.dsh-codex-empty{border:0.5px dashed var(--dsw-alias-border-l2);border-radius:7px;color:var(--dsw-alias-label-tertiary);font-size:12px;margin:12px 0 0;padding:16px;text-align:center}\n.dsh-codex-timestamp{color:var(--dsw-alias-label-tertiary);font-size:11px;margin:10px 0 0;text-align:right}\n.dsh-codex-skeleton{display:grid;gap:9px;padding-top:10px}\n.dsh-codex-skeleton span{animation:dsh-codex-pulse 1.4s ease-in-out infinite;background:var(--dsw-alias-bg-layer-2);border-radius:5px;height:42px}\n.dsh-codex-skeleton span:nth-child(2){animation-delay:.12s}.dsh-codex-skeleton span:nth-child(3){animation-delay:.24s}\n.dsh-codex-sr{height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px;clip:rect(0 0 0 0);white-space:nowrap}\n.dsh-codex-composer-quota{align-items:center;background:var(--dsw-alias-bg-layer-2);border:0.5px solid var(--dsw-alias-border-l2);border-radius:999px;corner-shape:round;color:var(--dsw-alias-label-secondary);display:inline-flex;font-size:11px;gap:6px;height:28px;line-height:1;max-width:160px;padding:0 9px;white-space:nowrap}\n.dsh-codex-composer-quota strong{color:var(--dsw-alias-label-primary);font-size:11px;font-weight:650}\n.dsh-codex-composer-quota[data-level=warning] strong{color:var(--dsw-alias-label-warning,#d58a24)}\n.dsh-codex-composer-quota[data-level=danger] strong{color:var(--dsw-alias-label-danger,#d94b4b)}\n.dsh-codex-image-tool{border:0.5px solid var(--dsw-alias-border-l2);border-radius:8px;display:flex;flex-direction:column;gap:8px;margin:4px 0 4px 4px;max-width:520px;padding:10px 12px}\n.dsh-codex-image-tool-head{align-items:center;display:flex;font-size:13px;gap:8px;min-width:0}\n.dsh-codex-image-dot{background:var(--dsw-alias-button-info-fill,#397ee8);border-radius:50%;corner-shape:round;display:inline-block;flex:none;height:8px;width:8px}\n.dsh-codex-image-tool[data-state=error] .dsh-codex-image-dot{background:var(--dsw-alias-label-danger,#d94b4b)}\n.dsh-codex-image-title{font-weight:600}\n.dsh-codex-image-summary{color:var(--dsw-alias-label-tertiary);min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n.dsh-codex-image-grid{display:flex;flex-wrap:wrap;gap:8px}\n.dsh-codex-image-preview{background:var(--dsw-alias-bg-layer-2);border:0.5px solid var(--dsw-alias-border-l2);border-radius:8px;display:block;max-height:260px;max-width:min(100%,360px);object-fit:contain}\n.dsh-codex-image-loading,.dsh-codex-image-failed{border:0.5px dashed var(--dsw-alias-border-l2);border-radius:8px;color:var(--dsw-alias-label-tertiary);display:inline-flex;font-size:12px;line-height:1.4;padding:18px 20px}\n.dsh-codex-image-failed{color:var(--dsw-alias-label-danger,#d94b4b)}\n@keyframes dsh-codex-pulse{0%,100%{opacity:.45}50%{opacity:.85}}\n@media(max-width:560px){.dsh-codex-row,.dsh-codex-pref-row,.dsh-codex-quota-fact,.dsh-codex-reset-credits{align-items:flex-start;flex-direction:column;gap:3px}.dsh-codex-value,.dsh-codex-quota-fact strong{text-align:left}.dsh-codex-actions{justify-content:flex-start}.dsh-codex-grouphead{align-items:flex-start;flex-direction:column;gap:0;padding:12px 0}.dsh-codex-meter-meta{align-items:flex-start;flex-direction:column;gap:2px}.dsh-codex-errorbar{align-items:flex-start;flex-direction:column}.dsh-codex-segments{width:100%}.dsh-codex-select{max-width:none;width:100%}.dsh-codex-context-row{align-items:flex-start;flex-direction:column;gap:5px}.dsh-codex-segments label{flex:1}.dsh-codex-segments span{text-align:center}.dsh-codex-image-tool{max-width:100%;margin-left:0}}\n@media(prefers-reduced-motion:reduce){.dsh-codex-meter>span{transition:none}.dsh-codex-skeleton span{animation:none}}\n`\n\n/**\n * Install the ChatGPT tab's stylesheet as a document-owned, never-removed\n * `<style>` element.\n *\n * The other client stylesheets this plugin installs are additive: their\n * installers no-op when the element already exists and their disposers do\n * nothing, so a restart can never take the styles away. This one used to\n * create *and remove* its element, and the dedupe handoff was racy: on a\n * plugin fiber restart (config change, dependency reload, HMR) the new fiber\n * ran `apply()` before the old fiber's async unload removed the element —\n * dedupe saw the old tag, returned a no-op disposer, and the old unload then\n * deleted the only copy. Every later restart kept returning the no-op, so the\n * stylesheet never came back and the settings page rendered unstyled.\n *\n * Fix: treat the tag as owned by the document rather than by one fiber —\n * create it when missing, refresh `textContent` when a rebuilt bundle ships\n * different CSS (HMR), and return a no-op disposer unconditionally, matching\n * the additive installers.\n *\n * Every other sheet this plugin injects now goes through the same installer\n * (`installPluginStyle`), which additionally stamps the ownership attributes\n * the client module system needs so the tag cannot be claimed by, and later\n * removed with, some other package.\n */\nexport function installStyles(): () => void {\n return installPluginStyle('main', CSS)\n}\n","/**\n * Styles for the subscription hub: the overview's provider cards, the detail\n * page's back bar, and the provider switch. Installed through the shared\n * installer so the module system never claims the sheet (see\n * common/plugin-style.ts). Colors ride DSH theme tokens, so dark mode needs\n * no branch of its own.\n */\nimport { installPluginStyle } from '../common/plugin-style.ts'\n\nconst CSS = `\n.dsh-hub-overview{display:flex;flex-direction:column;min-width:0}\n.dsh-hub-hint{color:var(--dsw-alias-label-secondary,#5d5c52);font-size:13px;line-height:1.55;margin:0 0 14px}\n.dsh-hub-cards{border-top:0.5px solid var(--dsw-alias-border-l2,#eceadf)}\n.dsh-hub-card{align-items:center;background:transparent;border:none;border-bottom:0.5px solid var(--dsw-alias-border-l2,#eceadf);color:var(--dsw-alias-label-primary,#141413);cursor:pointer;display:flex;gap:14px;font:inherit;min-height:68px;padding:12px 6px;text-align:left;width:100%}\n.dsh-hub-card:hover{background:var(--dsw-alias-interactive-bg-hover,rgba(0,0,0,.04))}\n.dsh-hub-card:focus-visible{outline:2px solid var(--dsw-alias-button-info-fill,#397ee8);outline-offset:-2px}\n.dsh-hub-card[data-enabled=false] .dsh-hub-card-name,.dsh-hub-card[data-enabled=false] .dsh-hub-card-note{opacity:.55}\n.dsh-hub-card-copy{display:flex;flex:1;flex-direction:column;gap:3px;min-width:0}\n.dsh-hub-card-name{font-size:14px;font-weight:600;line-height:1.3}\n.dsh-hub-card-note{color:var(--dsw-alias-label-tertiary,#8f8d84);font-size:12px;line-height:1.4}\n.dsh-hub-card-note.dsh-hub-note-danger{color:var(--dsw-alias-label-danger,#d94b4b)}\n.dsh-hub-card-side{align-items:center;display:flex;flex:none;gap:10px}\n.dsh-hub-chevron{color:var(--dsw-alias-label-caption,#a6a094);display:inline-flex;flex:none}\n.dsh-hub-brand-tile{align-items:center;background:color-mix(in srgb,var(--dsh-hub-brand,#888) 10%,transparent);border-radius:10px;display:inline-flex;flex:none;justify-content:center;overflow:hidden}\n.dsh-hub-brand-tile>svg{display:block}\n.dsh-hub-brand-mono{font-family:ui-monospace,SFMono-Regular,Consolas,monospace;font-size:15px;font-weight:700;line-height:1}\n.dsh-hub-switch{background:var(--dsw-alias-bg-layer-2,#f2f1ea);border:0.5px solid var(--dsw-alias-border-l2,#e3e1d5);border-radius:999px;box-sizing:border-box;cursor:pointer;flex:none;height:24px;padding:2px;position:relative;transition:background .15s ease,border-color .15s ease;width:44px}\n.dsh-hub-switch::after{background:var(--dsw-alias-bg-layer-1,#fff);border-radius:50%;box-shadow:0 1px 3px rgba(0,0,0,.28);content:\"\";display:block;height:19px;transition:transform .15s ease;width:19px}\n.dsh-hub-switch[aria-checked=true]{background:var(--dsw-alias-button-info-fill,#397ee8);border-color:transparent}\n.dsh-hub-switch[aria-checked=true]::after{transform:translateX(20px)}\n.dsh-hub-switch:disabled{cursor:default;opacity:.5}\n.dsh-hub-switch:focus-visible{outline:2px solid var(--dsw-alias-button-info-fill,#397ee8);outline-offset:2px}\n.dsh-hub-skeleton{border-bottom:0.5px solid var(--dsw-alias-border-l2,#eceadf);display:flex;gap:14px;min-height:68px;padding:12px 6px;align-items:center}\n.dsh-hub-skeleton i{background:var(--dsw-alias-bg-layer-2,#f2f1ea);border-radius:10px;display:block;height:40px;width:40px}\n.dsh-hub-skeleton span{background:var(--dsw-alias-bg-layer-2,#f2f1ea);border-radius:5px;display:block;height:12px}\n.dsh-hub-skeleton .dsh-hub-skel-name{width:120px;margin-bottom:6px}\n.dsh-hub-skeleton .dsh-hub-skel-note{width:180px;height:10px}\n.dsh-hub-backbar{align-items:center;display:flex;gap:10px;margin-bottom:14px;min-height:32px}\n.dsh-hub-back{align-items:center;background:transparent;border:none;border-radius:6px;color:var(--dsw-alias-label-secondary,#5d5c52);cursor:pointer;display:inline-flex;font:inherit;font-size:13px;font-weight:550;gap:2px;padding:5px 8px 5px 2px}\n.dsh-hub-back:hover{background:var(--dsw-alias-interactive-bg-hover,rgba(0,0,0,.04));color:var(--dsw-alias-label-primary,#141413)}\n.dsh-hub-back:focus-visible{outline:2px solid var(--dsw-alias-button-info-fill,#397ee8);outline-offset:2px}\n.dsh-hub-back svg{display:block}\n.dsh-hub-backbar-name{color:var(--dsw-alias-label-tertiary,#8f8d84);font-size:13px;font-weight:600}\n/* In the hub's detail page the back bar already names the provider, so the\n section's own page-level title would read as a duplicate. The intro line\n under it stays — it describes the line, not the location. Only ChatGPT's\n section renders such a header; the other seven begin with their content. */\n.dsh-hub-detail .dsha-page>header .dsh-codex-title{display:none}\n.dsh-hub-detail .dsha-page>header{margin-bottom:4px}\n`\n\nexport function installHubStyles(): void {\n installPluginStyle('hub', CSS)\n}\n","/**\n * Styles for the shared ModelChecklist (see ModelChecklist.tsx). Row metrics\n * and hover follow the claude-style model picker so the settings list and the\n * conversation picker read as one surface.\n */\nimport { installPluginStyle } from './plugin-style.ts'\n\nconst CSS = `\n.dsh-mcl{display:flex;flex-direction:column;min-width:0;padding:4px 0 2px}\n.dsh-mcl-head{align-items:center;display:flex;justify-content:space-between;min-height:28px;padding:2px 2px 6px}\n.dsh-mcl-count{color:var(--dsw-alias-label-caption,#a6a094);font-size:11px;letter-spacing:.02em}\n.dsh-mcl-head-actions{display:inline-flex;gap:4px}\n.dsh-mcl-action{background:transparent;border:none;border-radius:5px;color:var(--dsw-alias-label-link,#3278d4);cursor:pointer;font:inherit;font-size:12px;padding:3px 7px}\n.dsh-mcl-action:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover,rgba(0,0,0,.05))}\n.dsh-mcl-action:disabled{cursor:default;opacity:.45}\n.dsh-mcl-action:focus-visible{outline:2px solid var(--dsw-alias-button-info-fill,#397ee8);outline-offset:2px}\n.dsh-mcl-list{display:flex;flex-direction:column;gap:1px}\n.dsh-mcl-option{align-items:center;background:transparent;border:none;border-radius:6px;color:var(--dsw-alias-label-primary,#141413);cursor:pointer;display:flex;font:inherit;gap:9px;min-height:34px;padding:3px 8px;text-align:left;width:100%}\n.dsh-mcl-option:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover,rgba(0,0,0,.06))}\n.dsh-mcl-option:disabled{cursor:default;opacity:.55}\n.dsh-mcl-option:focus-visible{outline:2px solid var(--dsw-alias-button-info-fill,#397ee8);outline-offset:-2px}\n.dsh-mcl-option>svg{flex:none}\n.dsh-mcl-copy{display:flex;flex:1;flex-direction:column;gap:1px;min-width:0}\n.dsh-mcl-name{font-size:13px;font-weight:500;line-height:16px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n.dsh-mcl-hint{color:var(--dsw-alias-label-tertiary,#8f8d84);font-size:11px;line-height:14px}\n.dsh-mcl-option[data-enabled=false] .dsh-mcl-name,.dsh-mcl-option[data-enabled=false] .dsh-mcl-hint{opacity:.6}\n.dsh-mcl-check{align-items:center;background:var(--dsw-alias-bg-layer-2,#f2f1ea);border:0.5px solid var(--dsw-alias-border-l1,#e8e6dc);border-radius:50%;color:transparent;display:inline-flex;flex:none;height:18px;justify-content:center;transition:background .12s ease,border-color .12s ease,color .12s ease;width:18px}\n.dsh-mcl-option[aria-checked=true] .dsh-mcl-check{background:var(--dsw-alias-button-info-fill,#397ee8);border-color:transparent;color:var(--dsw-alias-button-info-label,#fff)}\n.dsh-mcl-option:hover:not(:disabled) .dsh-mcl-check{border-color:var(--dsw-alias-button-info-fill,#397ee8)}\n`\n\nexport function installModelChecklistStyles(): void {\n installPluginStyle('model-checklist', CSS)\n}\n","import { installPluginStyle } from '../common/plugin-style.ts'\n\nexport const STYLE_ID = 'dsh-antigravity-settings-style'\n\nexport function installAntigravityStyles(): void {\n installPluginStyle('antigravity', `\n.dsha-page{box-sizing:border-box;color:var(--dsw-alias-label-primary);display:flex;flex-direction:column;gap:20px;max-width:780px;min-width:0;padding:2px 0 30px}\n.dsha-page *{box-sizing:border-box}\n.dsha-group{border-top:0.5px solid var(--dsw-alias-border-l2);min-width:0}\n.dsha-group:first-of-type{border-top:0}\n.dsha-grouphead{align-items:center;display:flex;gap:12px;justify-content:space-between;min-height:48px}\n.dsha-grouphead h3{font-size:14px;font-weight:650;margin:0;color:var(--dsw-alias-label-primary)}\n.dsha-row{align-items:center;border-bottom:0.5px solid var(--dsw-alias-border-l2);display:flex;gap:20px;justify-content:space-between;min-height:44px;padding:8px 0}\n.dsha-label{color:var(--dsw-alias-label-secondary);font-size:13px;flex:0 0 auto}\n.dsha-value{font-size:13px;min-width:0;overflow-wrap:anywhere;text-align:right;color:var(--dsw-alias-label-primary)}\n.dsha-actions{display:flex;flex-wrap:wrap;gap:8px;justify-content:flex-end;padding-top:12px}\n.dsha-btn{background:var(--dsw-alias-bg-layer-2);border:0.5px solid var(--dsw-alias-border-l2);border-radius:999px;corner-shape:round;color:var(--dsw-alias-label-primary);cursor:pointer;font:inherit;font-size:13px;line-height:1;padding:8px 13px;white-space:nowrap}\n.dsha-btn:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}\n.dsha-btn:disabled{cursor:default;opacity:.5}\n.dsha-btn-primary{background:var(--dsw-alias-button-info-fill,#397ee8);border-color:transparent;color:var(--dsw-alias-button-info-label,#fff)}\n.dsha-btn-primary:hover:not(:disabled){opacity:.9}\n.dsha-notice{background:var(--dsw-alias-bg-layer-2);border:0.5px solid var(--dsw-alias-border-l2);border-radius:7px;color:var(--dsw-alias-label-secondary);font-size:12px;line-height:1.55;margin:12px 0 0;padding:10px 12px}\n.dsha-muted{color:var(--dsw-alias-label-secondary);font-size:13px;line-height:1.55;margin:0}\n.dsha-models-hint{padding-top:10px}\n.dsha-pref-row{align-items:center;border-bottom:0.5px solid var(--dsw-alias-border-l2);display:flex;gap:16px;justify-content:space-between;min-height:58px;padding:10px 0}\n.dsha-pref-row strong{display:block;font-size:13px;font-weight:600;line-height:1.35;color:var(--dsw-alias-label-primary)}\n.dsha-select{background:var(--dsw-alias-bg-layer-2);border:0.5px solid var(--dsw-alias-border-l2);border-radius:7px;color:var(--dsw-alias-label-primary);font:inherit;font-size:12px;padding:7px 9px;max-width:220px;min-width:160px}\n.dsha-context-settings{border-bottom:0.5px solid var(--dsw-alias-border-l2);display:grid;gap:10px;padding:12px 0}\n.dsha-context-settings>div>strong{font-size:13px;font-weight:600;color:var(--dsw-alias-label-primary)}\n.dsha-context-row{align-items:center;display:flex;font-size:12px;gap:14px;justify-content:space-between}\n.dsha-capacity-control{align-items:center;display:flex;gap:7px}\n.dsha-capacity-control input{background:var(--dsw-alias-bg-layer-2);border:0.5px solid var(--dsw-alias-border-l2);border-radius:7px;color:var(--dsw-alias-label-primary);font:inherit;font-family:ui-monospace,SFMono-Regular,Consolas,monospace;font-size:12px;padding:7px 9px;text-align:right;width:90px}\n.dsha-capacity-control small{color:var(--dsw-alias-label-tertiary);font-size:11px;width:42px}\n.dsha-context-save{background:var(--dsw-alias-bg-layer-2);border:0.5px solid var(--dsw-alias-border-l2);border-radius:7px;color:var(--dsw-alias-label-primary);cursor:pointer;font:inherit;font-size:12px;line-height:1;padding:8px 10px;white-space:nowrap}\n.dsha-context-save:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}\n.dsha-context-save:disabled{cursor:default;opacity:.45}\n.dsha-context-reset{color:var(--dsw-alias-label-secondary)}\n.dsha-context-reset:hover:not(:disabled){color:var(--dsw-alias-label-primary)}\n.dsha-quota-card{background:var(--dsw-alias-bg-layer-2);border:0.5px solid var(--dsw-alias-border-l2);border-radius:8px;margin-top:12px;padding:12px}\n.dsha-quota-title{align-items:center;display:flex;font-size:13px;gap:8px;justify-content:space-between;color:var(--dsw-alias-label-primary);font-weight:650}\n.dsha-quota-title span{color:var(--dsw-alias-label-tertiary);font-size:11px;text-transform:uppercase}\n.dsha-meter-wrap{margin-top:13px}\n.dsha-meter-label,.dsha-meter-meta{display:flex;gap:10px;justify-content:space-between}\n.dsha-meter-label{font-size:12px;margin-bottom:6px;color:var(--dsw-alias-label-primary)}\n.dsha-meter-meta{color:var(--dsw-alias-label-tertiary);font-size:11px;line-height:1.45;margin-top:6px}\n.dsha-meter{background:var(--dsw-alias-bg-layer-1,rgba(127,127,127,.15));border-radius:999px;corner-shape:round;height:7px;overflow:hidden;width:100%}\n.dsha-meter>span{background:var(--dsw-alias-button-info-fill,#397ee8);border-radius:inherit;display:block;height:100%;max-width:100%;min-width:0;transition:width .25s ease}\n.dsha-meter-green>span{background:var(--dsw-alias-label-success,#10b981)}\n.dsha-meter-cyan>span{background:#06b6d4}\n.dsha-timestamp{color:var(--dsw-alias-label-tertiary);font-size:11px;margin:10px 0 0;text-align:right}\n.dsha-mini-btn{border:0;background:transparent;color:var(--dsw-alias-label-link,#397ee8);font-size:12px;line-height:18px;cursor:pointer;padding:0;margin-left:8px}\n.dsha-mini-btn:hover{text-decoration:underline}\n.dsha-empty{border:0.5px dashed var(--dsw-alias-border-l2);border-radius:7px;color:var(--dsw-alias-label-tertiary);font-size:12px;margin:12px 0 0;padding:16px;text-align:center}\n.dsha-error{color:var(--dsw-alias-label-danger,#d94b4b);font-size:12px;margin:8px 0 0}\n.dsha-composer-quota{align-items:center;background:var(--dsw-alias-bg-layer-2);border:0.5px solid var(--dsw-alias-border-l2);border-radius:999px;corner-shape:round;color:var(--dsw-alias-label-secondary);cursor:pointer;display:inline-flex;font-size:11px;gap:6px;height:28px;line-height:1;max-width:160px;padding:0 9px;white-space:nowrap;user-select:none;transition:all .15s ease}\n.dsha-composer-quota:hover{background:var(--dsw-alias-interactive-bg-hover);border-color:var(--dsw-alias-border-l1,var(--dsw-alias-border-l2))}\n.dsha-composer-quota strong{color:var(--dsw-alias-label-primary);font-size:11px;font-weight:650}\n.dsha-composer-quota[data-level=warning] strong{color:var(--dsw-alias-label-warning,#d58a24)}\n.dsha-composer-quota[data-level=danger] strong{color:var(--dsw-alias-label-danger,#d94b4b)}\n.dsha-accounts-list{display:flex;flex-direction:column;gap:10px;margin-top:10px}\n.dsha-account-card{background:var(--dsw-alias-bg-layer-2);border:0.5px solid var(--dsw-alias-border-l2);border-radius:8px;padding:12px 14px;display:flex;flex-direction:column;gap:8px;transition:border-color .15s ease}\n.dsha-account-card.active{border-color:color-mix(in srgb,var(--dsw-alias-button-info-fill,#397ee8) 60%,var(--dsw-alias-border-l2))}\n.dsha-account-header{display:flex;align-items:center;justify-content:space-between;gap:8px}\n.dsha-account-identity{display:flex;align-items:center;gap:8px;min-width:0}\n.dsha-account-title{font-size:13px;font-weight:600;color:var(--dsw-alias-label-primary);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n.dsha-badges{display:flex;align-items:center;gap:6px}\n.dsha-badge{font-size:11px;line-height:1;padding:3px 7px;border-radius:4px;font-weight:550;white-space:nowrap}\n.dsha-badge.primary{background:color-mix(in srgb,var(--dsw-alias-button-info-fill,#397ee8) 18%,var(--dsw-alias-bg-layer-1));color:var(--dsw-alias-button-info-fill,#397ee8);border:0.5px solid color-mix(in srgb,var(--dsw-alias-button-info-fill,#397ee8) 40%,transparent)}\n.dsha-badge.active{background:color-mix(in srgb,var(--dsw-alias-label-success,#10b981) 18%,var(--dsw-alias-bg-layer-1));color:var(--dsw-alias-label-success,#10b981);border:0.5px solid color-mix(in srgb,var(--dsw-alias-label-success,#10b981) 40%,transparent)}\n.dsha-badge.cooldown{background:color-mix(in srgb,var(--dsw-alias-label-warning,#d58a24) 18%,var(--dsw-alias-bg-layer-1));color:var(--dsw-alias-label-warning,#d58a24);border:0.5px solid color-mix(in srgb,var(--dsw-alias-label-warning,#d58a24) 40%,transparent)}\n.dsha-account-details{display:flex;flex-wrap:wrap;gap:14px;font-size:12px;color:var(--dsw-alias-label-secondary)}\n.dsha-account-actions{display:flex;flex-wrap:wrap;gap:6px;margin-top:2px}\n.dsha-account-actions .dsha-btn{padding:5px 10px;font-size:12px}\n`, STYLE_ID)\n}\n","import { installPluginStyle } from './plugin-style.ts'\n\nexport const POOL_STYLE_ID = 'dsh-provider-pool-style'\n\n/**\n * Styles the shared account-pool card adds on top of the existing provider\n * stylesheets: the badge variants no single provider tab owned before.\n *\n * Additive on purpose — the shared `.dsha-*` block and each provider's own\n * tweaks keep living in their own modules, in the order the client installs\n * them, so nothing that already rendered changes appearance.\n */\nexport function installPoolStyles(): void {\n installPluginStyle('pool', `\n.dsha-badge.danger{background:color-mix(in srgb,var(--dsw-alias-label-danger,#d94b4b) 18%,var(--dsw-alias-bg-layer-1));color:var(--dsw-alias-label-danger,#d94b4b);border:0.5px solid color-mix(in srgb,var(--dsw-alias-label-danger,#d94b4b) 40%,transparent)}\n.dsha-account-card .dsha-btn.danger{color:var(--dsw-alias-label-danger,#d94b4b)}\n/* Quota inside one account row. It follows the account, so it sits with the\n account's identity, badges and timestamps rather than in a page-level block\n that could only ever describe whichever account was active when it was read. */\n.dsha-account-quota{display:flex;flex-direction:column;gap:5px;margin-top:9px}\n.dsha-account-quota-head{align-items:baseline;color:var(--dsw-alias-label-secondary);display:flex;font-size:11px;font-weight:600;gap:8px;letter-spacing:.02em}\n.dsha-account-quota-head em{color:var(--dsw-alias-label-tertiary);font-style:normal;font-weight:400}\n.dsha-account-quota-empty{color:var(--dsw-alias-label-tertiary);font-size:12px}\n.dsha-account-quota-row{align-items:center;display:flex;font-size:12px;gap:8px}\n.dsha-account-quota-name{color:var(--dsw-alias-label-secondary);flex:none;max-width:38%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n/* The track is drawn even when nothing is used: an empty bar nobody can see\n leaves the row reading as a stray label next to a number. */\n.dsha-account-quota-track{background:color-mix(in srgb,var(--dsw-alias-label-tertiary,#8a8a8a) 16%,transparent);border-radius:999px;box-shadow:inset 0 0 0 0.5px var(--dsw-alias-border-l2);flex:1;height:6px;min-width:56px;overflow:hidden}\n.dsha-account-quota-fill{background:var(--dsw-alias-button-info-fill,#397ee8);border-radius:999px;display:block;height:100%;min-width:2px;transition:width .2s ease}\n.dsha-account-quota-row[data-level=warning] .dsha-account-quota-fill{background:var(--dsw-alias-label-warning,#d9913b)}\n.dsha-account-quota-row[data-level=danger] .dsha-account-quota-fill{background:var(--dsw-alias-label-danger,#d94b4b)}\n.dsha-account-quota-value{color:var(--dsw-alias-label-primary);flex:none;font-variant-numeric:tabular-nums;min-width:40px;text-align:right}\n.dsha-account-quota-meta{color:var(--dsw-alias-label-tertiary);flex:none;font-size:11px;font-variant-numeric:tabular-nums}\n@media(max-width:560px){.dsha-account-quota-meta{display:none}}\n`, POOL_STYLE_ID)\n}\n","/**\n * The composer badge every subscription line shows beside the input.\n *\n * Six of these were near-identical copies: the same mount guard, the same 60 s\n * poll that only ticks while the tab is visible, the same \"inert unless the\n * conversation is on this provider\" rule, the same markup. What differed was the\n * part worth reading — how each line picks its most meaningful number — and that\n * is the only thing a line still supplies.\n *\n * Two details this shared shape depends on:\n *\n * - the callbacks are held in refs. Every caller hands them over as an inline\n * arrow, and a callback in the dependency array would restart the interval —\n * and refetch — on every render. The copies this replaced were only safe\n * because each was rendered with a stable prop, which is a property of the\n * call site rather than of the badge;\n * - `authenticated` is part of the status contract rather than a predicate a\n * line could forget, so a signed-out line can never leave a stale badge up.\n */\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react'\nimport type { ModelDirectoryState } from '@deepseek-ai/dsh-client-ui-model-selection/client'\nimport type { SnapshotStore } from '../store.ts'\nimport { useStore } from './use-store.ts'\n\nexport interface ComposerQuotaFacts {\n /** The number the badge shows, already formatted. */\n text: string\n /** What the hover and the screen reader say. */\n tooltip: string\n level: 'normal' | 'warning' | 'danger'\n}\n\n/** The shared grading: 5% or less is critical, 20% or less warns. */\nexport function quotaLevel(remainingPercent: number): ComposerQuotaFacts['level'] {\n return remainingPercent <= 5 ? 'danger' : remainingPercent <= 20 ? 'warning' : 'normal'\n}\n\nexport interface ComposerQuotaBadgeProps<Status extends { authenticated: boolean }> {\n directory: SnapshotStore<ModelDirectoryState>\n loadModelDirectory(): void\n /** The provider id this badge speaks for; it renders for no other. */\n providerId: string\n /** One status read; `true` asks the host for a forced refresh. */\n readStatus(refresh: boolean): Promise<Status>\n /**\n * The line's own number picker; null means there is nothing to show.\n *\n * `modelId` is the conversation's selected model, which one line needs: its\n * allowance is reported per model group, so the number to show depends on\n * which group that model belongs to.\n */\n selectFacts(status: Status | null, modelId: string | undefined): ComposerQuotaFacts | null\n /** Label in front of the number, from the line's own dictionary. */\n label: string\n}\n\nexport function ComposerQuotaBadge<Status extends { authenticated: boolean }>(\n props: ComposerQuotaBadgeProps<Status>,\n): React.JSX.Element | null {\n const { directory, loadModelDirectory, providerId, label } = props\n const modelState = useStore(directory)\n const [status, setStatus] = useState<Status | null>(null)\n const [loading, setLoading] = useState(false)\n const mountedRef = useRef(false)\n // See the header: identity churn in these two must not restart the poll.\n const readRef = useRef(props.readStatus)\n const selectRef = useRef(props.selectFacts)\n readRef.current = props.readStatus\n selectRef.current = props.selectFacts\n\n const selected = modelState.current\n const isSelected = selected?.provider === providerId\n\n useEffect(() => {\n loadModelDirectory()\n }, [loadModelDirectory])\n\n useEffect(() => {\n mountedRef.current = true\n return () => {\n mountedRef.current = false\n }\n }, [])\n\n const fetchStatus = useCallback(async (refresh: boolean) => {\n if (!mountedRef.current) return\n setLoading(true)\n try {\n // The host refreshes a stale quota cache while serving the ordinary read;\n // only an explicit click asks for the forced one, so a poll never doubles\n // the upstream request count.\n const data = await readRef.current(refresh)\n if (mountedRef.current) setStatus(data)\n } catch {\n // best-effort: the settings card reports the actionable error\n } finally {\n if (mountedRef.current) setLoading(false)\n }\n }, [])\n\n useEffect(() => {\n if (!isSelected) return\n void fetchStatus(false)\n const timer = window.setInterval(() => {\n if (document.visibilityState === 'visible') void fetchStatus(false)\n }, 60_000)\n return () => {\n window.clearInterval(timer)\n }\n }, [fetchStatus, isSelected])\n\n const facts = useMemo(() => selectRef.current(status, selected?.model), [status, selected?.model])\n\n // Inert unless the conversation is actually on this provider: the badge is one\n // per line and six of them must never be visible at once.\n if (!isSelected || status === null || !status.authenticated || facts === null) return null\n\n return <span\n className=\"dsha-composer-quota\"\n data-level={facts.level}\n title={facts.tooltip}\n aria-label={facts.tooltip}\n onClick={() => void fetchStatus(true)}\n >\n <span className=\"dsha-composer-quota-label\">{label}</span>\n <strong className=\"dsha-composer-quota-val\">{loading ? '…' : facts.text}</strong>\n </span>\n}\n","import type { ModelDirectoryState } from '@deepseek-ai/dsh-client-ui-model-selection/client'\nimport type { PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\nimport type { AntigravityModelBucket, AntigravityQuotaGroup, AntigravityWebStatus } from '../../shared/antigravity-contracts.ts'\nimport { ComposerQuotaBadge, quotaLevel, type ComposerQuotaFacts } from '../common/ComposerQuotaBadge.tsx'\nimport { createLineApi } from '../common/line-api.ts'\nimport type { SnapshotStore } from '../store.ts'\nimport { NS_ANTIGRAVITY } from './locales.ts'\n\nconst api = createLineApi('/antigravity/api', 'Antigravity')\n\ntype Props = PropsRuntime<'conversation.input.right'> & PropsLocale<typeof NS_ANTIGRAVITY> & {\n directory: SnapshotStore<ModelDirectoryState>\n loadModelDirectory: () => void\n}\n\n/**\n * The bucket this badge should speak for, or null when it cannot speak for one.\n *\n * The service reports the same allowances under separate model groups, and a\n * bucket the service never measured must not be published as \"0% left\". So the\n * badge skips it and takes the next measured one in the group, and shows nothing\n * at all when the group has none. Falling back to another group's numbers would\n * label one allowance with another's reading.\n *\n * Exported for its own regression test; the badge is its only caller.\n */\nexport function selectQuotaBucketForModel(groups: AntigravityQuotaGroup[], modelId?: string) {\n if (!groups || groups.length === 0) return null\n const isClaudeOrGpt = modelId ? /claude|gpt/i.test(modelId) : false\n const targetGroup =\n groups.find((g) => {\n const match = /claude|gpt|3p/i.test(g.displayName)\n return isClaudeOrGpt ? match : !match\n }) || groups[0]\n\n if (!targetGroup || !targetGroup.buckets || targetGroup.buckets.length === 0) return null\n // A missing field and a null are the same statement (\"never measured\"), and a\n // non-finite number is no more publishable than either: all three are skipped\n // rather than multiplied into a \"0% left\" the service never said.\n const measured = (bucket: AntigravityModelBucket): boolean =>\n typeof bucket.remainingFraction === 'number' && Number.isFinite(bucket.remainingFraction)\n const shortBucket: AntigravityModelBucket | undefined =\n targetGroup.buckets.find((b: AntigravityModelBucket) => /5\\s*小时|hour|5h/i.test(b.displayName) && measured(b))\n ?? targetGroup.buckets.find(measured)\n if (shortBucket === undefined) return null\n const remaining = shortBucket.remainingFraction\n if (typeof remaining !== 'number' || !Number.isFinite(remaining)) return null\n\n return {\n groupName: targetGroup.displayName,\n bucketName: shortBucket.displayName,\n remainingPercent: Math.round(remaining * 100),\n resetTime: shortBucket.resetTime,\n }\n}\n\nfunction formatResetCountdown(resetTime?: string): string {\n if (!resetTime) return ''\n try {\n const diff = new Date(resetTime).getTime() - Date.now()\n if (diff <= 0) return '即将重置'\n const h = Math.floor(diff / 3600000)\n const m = Math.floor((diff % 3600000) / 60000)\n if (h > 0) return `${h}小时${m}分后重置`\n return `${m}分钟后重置`\n } catch {\n return ''\n }\n}\n\n/** The allowance the selected model actually draws on, as the badge's facts. */\nexport function selectBadgeFacts(status: AntigravityWebStatus | null, modelId?: string): ComposerQuotaFacts {\n const info = selectQuotaBucketForModel(status?.quota?.groups ?? [], modelId)\n if (info === null) return { text: '—', tooltip: '点击刷新 Antigravity 配额', level: 'normal' }\n const countdown = info.resetTime ? formatResetCountdown(info.resetTime) : ''\n return {\n text: `${info.remainingPercent}%`,\n tooltip: `[Antigravity] ${info.groupName} - ${info.bucketName}: 剩余 ${info.remainingPercent}%${countdown ? ` (${countdown})` : ''},点击刷新`,\n level: quotaLevel(info.remainingPercent),\n }\n}\n\nexport function AntigravityComposerQuota({ directory, loadModelDirectory, t }: Props): React.JSX.Element | null {\n return <ComposerQuotaBadge\n directory={directory}\n loadModelDirectory={loadModelDirectory}\n providerId=\"antigravity\"\n readStatus={(refresh) => (refresh\n ? api.post<AntigravityWebStatus>('/quota')\n : api.get<AntigravityWebStatus>('/status'))}\n selectFacts={selectBadgeFacts}\n label={t('composerLabel')}\n />\n}\n","import type { ModelDirectoryState } from '@deepseek-ai/dsh-client-ui-model-selection/client'\nimport type { PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\nimport type { ClaudeWebStatus } from '../../shared/claude-contracts.ts'\nimport { ComposerQuotaBadge, quotaLevel, type ComposerQuotaFacts } from '../common/ComposerQuotaBadge.tsx'\nimport { createLineApi } from '../common/line-api.ts'\nimport type { SnapshotStore } from '../store.ts'\nimport { NS_CLAUDE } from './locales.ts'\n\nconst api = createLineApi('/claude/api', 'Claude')\n\ntype Props = PropsRuntime<'conversation.input.right'> & PropsLocale<typeof NS_CLAUDE> & {\n directory: SnapshotStore<ModelDirectoryState>\n loadModelDirectory: () => void\n}\n\n/**\n * Pick the most meaningful number for the badge.\n *\n * A subscription is bounded by several windows at once — a 5-hour one and a\n * weekly one, and sometimes a per-model weekly one as well. They are not\n * interchangeable: the short window can be spent while the long one has room and\n * the reverse, so the TIGHTEST *remaining* percentage is what the badge shows\n * and its own label names the tooltip. Choosing \"the shortest window\" instead\n * would be a guess about which one runs out first, and the payload already\n * answers that.\n *\n * NOTE ON DIRECTION: the wire reports `usedPercent`, which is PERCENT USED, so\n * remaining is 100 - used. A window at 0% used is the normal empty state and\n * grades as 'normal', not as an error.\n */\nexport function selectBadgeFacts(status: ClaudeWebStatus | null): ComposerQuotaFacts | null {\n const quota = status?.quota\n if (quota === null || quota === undefined) {\n return { text: '—', tooltip: '[Claude] quota unavailable — click to refresh', level: 'normal' }\n }\n\n let tightest: { label: string; remaining: number } | null = null\n for (const window of quota.windows) {\n // A null is \"the source stated nothing\" — skipped rather than read as a\n // fully-spent window, which would be a fabricated alarm.\n const remaining = window.remainingPercent\n ?? (window.usedPercent === null ? null : 100 - window.usedPercent)\n if (remaining === null) continue\n if (tightest === null || remaining < tightest.remaining) {\n tightest = { label: window.label, remaining }\n }\n }\n if (tightest === null) {\n return { text: '—', tooltip: '[Claude] quota unavailable — click to refresh', level: 'normal' }\n }\n\n const remaining = Math.round(tightest.remaining)\n return {\n text: `${remaining}%`,\n tooltip: `[Claude] ${tightest.label}: ${remaining}% left`,\n level: quotaLevel(remaining),\n }\n}\n\nexport function ClaudeComposerQuota({ directory, loadModelDirectory, t }: Props): React.JSX.Element | null {\n return <ComposerQuotaBadge\n directory={directory}\n loadModelDirectory={loadModelDirectory}\n providerId=\"claude-subscription\"\n readStatus={(refresh) => (refresh\n ? api.post<ClaudeWebStatus>('/quota')\n : api.get<ClaudeWebStatus>('/status'))}\n selectFacts={selectBadgeFacts}\n label={t('composerLabel')}\n />\n}\n","import { installPluginStyle } from '../common/plugin-style.ts'\n\nexport const STYLE_ID = 'dsh-claude-settings-style'\n\n/**\n * Claude-only additions to the shared settings design system.\n *\n * The base control styles ('.dsha-page', '.dsha-group', '.dsha-models', the\n * account card, the meters, the composer badge, …) come from the stylesheet the\n * Kimi Code sibling installs, in the same order the client installs them, so\n * this file declares only what stays unique to this card — the same rule the\n * WorkBuddy and GLM cards follow.\n *\n * What stays unique here is the sign-in flow block and the borrowed-sign-in\n * markers, neither of which a sibling line renders.\n */\nexport function installClaudeStyles(): void {\n installPluginStyle('claude', `\n.dsha-badge.claude-adopted{background:color-mix(in srgb,var(--dsw-alias-button-info-fill,#397ee8) 16%,var(--dsw-alias-bg-layer-1));border-color:color-mix(in srgb,var(--dsw-alias-button-info-fill,#397ee8) 45%,var(--dsw-alias-border-l2));color:var(--dsw-alias-label-primary)}\n.dshcl-flow{border-bottom:0.5px solid var(--dsw-alias-border-l2);display:flex;flex-direction:column;gap:10px;padding:12px 0}\n.dshcl-flow-url{background:var(--dsw-alias-bg-layer-1,rgba(127,127,127,.14));border:0.5px solid var(--dsw-alias-border-l2);border-radius:7px;color:var(--dsw-alias-label-primary);font-family:ui-monospace,SFMono-Regular,Consolas,monospace;font-size:11px;overflow-wrap:anywhere;padding:8px 10px;user-select:all}\n.dshcl-paste{align-items:flex-start;display:flex;flex-direction:column;gap:8px}\n.dshcl-paste-row{align-items:center;display:flex;flex-wrap:wrap;gap:8px}\n.dshcl-paste-row input{flex:1 1 260px;min-width:200px}\n.dshcl-mono{font-family:ui-monospace,SFMono-Regular,Consolas,monospace;font-size:11px;overflow-wrap:anywhere}\n.dshcl-model-meta{color:var(--dsw-alias-label-tertiary);font-size:11px;margin-left:5px}\n.dshcl-empty-inline{color:var(--dsw-alias-label-tertiary);font-size:12px}\n`, STYLE_ID)\n}\n","import type { ModelDirectoryState } from '@deepseek-ai/dsh-client-ui-model-selection/client'\nimport type { PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\nimport type { CommandCodeWebStatus } from '../../shared/command-code-contracts.ts'\nimport { ComposerQuotaBadge, quotaLevel, type ComposerQuotaFacts } from '../common/ComposerQuotaBadge.tsx'\nimport { createLineApi } from '../common/line-api.ts'\nimport type { SnapshotStore } from '../store.ts'\nimport { NS_COMMAND_CODE } from './locales.ts'\n\nconst api = createLineApi('/command-code/api', 'Command Code')\n\ntype Props = PropsRuntime<'conversation.input.right'> & PropsLocale<typeof NS_COMMAND_CODE> & {\n directory: SnapshotStore<ModelDirectoryState>\n loadModelDirectory: () => void\n}\n\n/**\n * Pick the most meaningful number for the badge.\n *\n * A bounded usage window is the number a user actually spends down, so it wins\n * over a credit balance; the balance shows only when no window is reported.\n */\nexport function selectBadgeFacts(status: CommandCodeWebStatus | null): ComposerQuotaFacts | null {\n const quota = status?.quota\n if (quota === null || quota === undefined) {\n return { text: '—', tooltip: 'Command Code quota unavailable — click to refresh', level: 'normal' }\n }\n\n const window = [...(quota.windows ?? [])].sort((a, b) => (a.windowDurationMins ?? Infinity) - (b.windowDurationMins ?? Infinity))[0]\n if (window !== undefined) {\n const remaining = Math.max(0, 100 - window.usedPercent)\n return {\n text: `${remaining}%`,\n tooltip: `[Command Code] ${window.label}: ${remaining}% left`,\n level: quotaLevel(remaining),\n }\n }\n\n const meter = (quota.meters ?? []).find((candidate) => candidate.remainingFraction !== null)\n if (meter !== undefined && meter.remainingFraction !== null) {\n const remaining = Math.round(meter.remainingFraction * 100)\n return {\n text: `${remaining}%`,\n tooltip: `[Command Code] ${meter.label}: ${remaining}% left`,\n level: quotaLevel(remaining),\n }\n }\n\n if (quota.unlimited) {\n return { text: '∞', tooltip: '[Command Code] Unlimited plan allowance', level: 'normal' }\n }\n if (quota.creditBalance !== null) {\n return { text: quota.creditBalance, tooltip: `[Command Code] Remaining credits: ${quota.creditBalance}`, level: 'normal' }\n }\n return { text: '—', tooltip: 'Command Code quota unavailable — click to refresh', level: 'normal' }\n}\n\nexport function CommandCodeComposerQuota({ directory, loadModelDirectory, t }: Props): React.JSX.Element | null {\n return <ComposerQuotaBadge\n directory={directory}\n loadModelDirectory={loadModelDirectory}\n providerId=\"command-code\"\n readStatus={(refresh) => (refresh\n ? api.post<CommandCodeWebStatus>('/quota')\n : api.get<CommandCodeWebStatus>('/status'))}\n selectFacts={selectBadgeFacts}\n label={t('composerLabel')}\n />\n}\n","import type { ModelDirectoryState } from '@deepseek-ai/dsh-client-ui-model-selection/client'\nimport type { PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\nimport type { KimiCodeWebStatus } from '../../shared/kimi-code-contracts.ts'\nimport { ComposerQuotaBadge, quotaLevel, type ComposerQuotaFacts } from '../common/ComposerQuotaBadge.tsx'\nimport { createLineApi } from '../common/line-api.ts'\nimport type { SnapshotStore } from '../store.ts'\nimport { NS_KIMI_CODE } from './locales.ts'\n\nconst api = createLineApi('/kimi-code/api', 'Kimi Code')\n\ntype Props = PropsRuntime<'conversation.input.right'> & PropsLocale<typeof NS_KIMI_CODE> & {\n directory: SnapshotStore<ModelDirectoryState>\n loadModelDirectory: () => void\n}\n\n/**\n * Pick the most meaningful number for the badge.\n *\n * The shortest window is the one a user spends down first and the one that\n * blocks work soonest, so it wins over the longer pools; the 7-day allowance\n * shows only when no 5-hour window is reported.\n */\nexport function selectBadgeFacts(status: KimiCodeWebStatus | null): ComposerQuotaFacts | null {\n const quota = status?.quota\n if (quota === null || quota === undefined) {\n return { text: '—', tooltip: '[Kimi Code] quota unavailable — click to refresh', level: 'normal' }\n }\n\n const window = [...(quota.windows ?? [])]\n .filter((candidate) => candidate.windowDurationMins !== null)\n .sort((a, b) => (a.windowDurationMins ?? Infinity) - (b.windowDurationMins ?? Infinity))[0]\n ?? quota.windows[0]\n\n if (window !== undefined) {\n const remaining = Math.max(0, 100 - window.usedPercent)\n return {\n text: `${remaining}%`,\n tooltip: `[Kimi Code] ${window.label}: ${remaining}% left`,\n level: quotaLevel(remaining),\n }\n }\n\n const wallet = quota.extraUsage\n if (wallet !== null && wallet !== undefined && wallet.balanceCents !== null) {\n const amount = (wallet.balanceCents / 100).toFixed(2)\n return {\n text: amount,\n tooltip: `[Kimi Code] booster wallet: ${amount} ${wallet.currency ?? ''}`.trim(),\n level: 'normal',\n }\n }\n\n return { text: '—', tooltip: '[Kimi Code] quota unavailable — click to refresh', level: 'normal' }\n}\n\nexport function KimiCodeComposerQuota({ directory, loadModelDirectory, t }: Props): React.JSX.Element | null {\n return <ComposerQuotaBadge\n directory={directory}\n loadModelDirectory={loadModelDirectory}\n providerId=\"kimi-code\"\n readStatus={(refresh) => (refresh\n ? api.post<KimiCodeWebStatus>('/quota')\n : api.get<KimiCodeWebStatus>('/status'))}\n selectFacts={selectBadgeFacts}\n label={t('composerLabel')}\n />\n}\n","import { installPluginStyle } from '../common/plugin-style.ts'\n\nexport const STYLE_ID = 'dsh-kimi-code-settings-style'\n\n/**\n * Node the base control styles come from.\n *\n * The Kimi Code card renders the same controls as the sibling routes, so it\n * reuses one extracted stylesheet verbatim rather than re-declaring a parallel\n * design system that would drift from it.\n */\nconst BASE = `\n.dsha-page{box-sizing:border-box;color:var(--dsw-alias-label-primary);display:flex;flex-direction:column;gap:20px;max-width:780px;min-width:0;padding:2px 0 30px}\n.dsha-page *{box-sizing:border-box}\n.dsha-group{border-top:0.5px solid var(--dsw-alias-border-l2);min-width:0}\n.dsha-group:first-of-type{border-top:0}\n.dsha-grouphead{align-items:center;display:flex;gap:12px;justify-content:space-between;min-height:48px}\n.dsha-grouphead h3{font-size:14px;font-weight:650;margin:0;color:var(--dsw-alias-label-primary)}\n.dsha-row{align-items:center;border-bottom:0.5px solid var(--dsw-alias-border-l2);display:flex;gap:20px;justify-content:space-between;min-height:44px;padding:8px 0}\n.dsha-label{color:var(--dsw-alias-label-secondary);font-size:13px;flex:0 0 auto}\n.dsha-value{font-size:13px;min-width:0;overflow-wrap:anywhere;text-align:right;color:var(--dsw-alias-label-primary)}\n.dsha-actions{display:flex;flex-wrap:wrap;gap:8px;justify-content:flex-end;padding-top:12px}\n.dsha-btn{background:var(--dsw-alias-bg-layer-2);border:0.5px solid var(--dsw-alias-border-l2);border-radius:999px;corner-shape:round;color:var(--dsw-alias-label-primary);cursor:pointer;font:inherit;font-size:13px;line-height:1;padding:8px 13px;white-space:nowrap}\n.dsha-btn:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}\n.dsha-btn:disabled{cursor:default;opacity:.5}\n.dsha-btn-primary{background:var(--dsw-alias-button-info-fill,#397ee8);border-color:transparent;color:var(--dsw-alias-button-info-label,#fff)}\n.dsha-btn-primary:hover:not(:disabled){opacity:.9}\n.dsha-notice{background:var(--dsw-alias-bg-layer-2);border:0.5px solid var(--dsw-alias-border-l2);border-radius:7px;color:var(--dsw-alias-label-secondary);font-size:12px;line-height:1.55;margin:12px 0 0;padding:10px 12px}\n.dsha-muted{color:var(--dsw-alias-label-secondary);font-size:13px;line-height:1.55;margin:0}\n.dsha-models-hint{padding-top:10px}\n.dsha-pref-row{align-items:center;border-bottom:0.5px solid var(--dsw-alias-border-l2);display:flex;gap:16px;justify-content:space-between;min-height:58px;padding:10px 0}\n.dsha-pref-row strong{display:block;font-size:13px;font-weight:600;line-height:1.35;color:var(--dsw-alias-label-primary)}\n.dsha-select{background:var(--dsw-alias-bg-layer-2);border:0.5px solid var(--dsw-alias-border-l2);border-radius:7px;color:var(--dsw-alias-label-primary);font:inherit;font-size:12px;padding:7px 9px;max-width:220px;min-width:160px}\n.dsha-context-settings{border-bottom:0.5px solid var(--dsw-alias-border-l2);display:grid;gap:10px;padding:12px 0}\n.dsha-context-settings>div>strong{font-size:13px;font-weight:600;color:var(--dsw-alias-label-primary)}\n.dsha-context-row{align-items:center;display:flex;font-size:12px;gap:14px;justify-content:space-between}\n.dsha-capacity-control{align-items:center;display:flex;gap:7px}\n.dsha-capacity-control input{background:var(--dsw-alias-bg-layer-2);border:0.5px solid var(--dsw-alias-border-l2);border-radius:7px;color:var(--dsw-alias-label-primary);font:inherit;font-family:ui-monospace,SFMono-Regular,Consolas,monospace;font-size:12px;padding:7px 9px;text-align:right;width:90px}\n.dsha-capacity-control small{color:var(--dsw-alias-label-tertiary);font-size:11px;width:42px}\n.dsha-context-save{background:var(--dsw-alias-bg-layer-2);border:0.5px solid var(--dsw-alias-border-l2);border-radius:7px;color:var(--dsw-alias-label-primary);cursor:pointer;font:inherit;font-size:12px;line-height:1;padding:8px 10px;white-space:nowrap}\n.dsha-context-save:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}\n.dsha-context-save:disabled{cursor:default;opacity:.45}\n.dsha-context-reset{color:var(--dsw-alias-label-secondary)}\n.dsha-context-reset:hover:not(:disabled){color:var(--dsw-alias-label-primary)}\n.dsha-quota-card{background:var(--dsw-alias-bg-layer-2);border:0.5px solid var(--dsw-alias-border-l2);border-radius:8px;margin-top:12px;padding:12px}\n.dsha-quota-title{align-items:center;display:flex;font-size:13px;gap:8px;justify-content:space-between;color:var(--dsw-alias-label-primary);font-weight:650}\n.dsha-quota-title span{color:var(--dsw-alias-label-tertiary);font-size:11px;text-transform:uppercase}\n.dsha-meter-wrap{margin-top:13px}\n.dsha-meter-label,.dsha-meter-meta{display:flex;gap:10px;justify-content:space-between}\n.dsha-meter-label{font-size:12px;margin-bottom:6px;color:var(--dsw-alias-label-primary)}\n.dsha-meter-meta{color:var(--dsw-alias-label-tertiary);font-size:11px;line-height:1.45;margin-top:6px}\n.dsha-meter{background:var(--dsw-alias-bg-layer-1,rgba(127,127,127,.15));border-radius:999px;corner-shape:round;height:7px;overflow:hidden;width:100%}\n.dsha-meter>span{background:var(--dsw-alias-button-info-fill,#397ee8);border-radius:inherit;display:block;height:100%;max-width:100%;min-width:0;transition:width .25s ease}\n.dsha-meter-green>span{background:var(--dsw-alias-label-success,#10b981)}\n.dsha-meter-cyan>span{background:#06b6d4}\n.dsha-timestamp{color:var(--dsw-alias-label-tertiary);font-size:11px;margin:10px 0 0;text-align:right}\n.dsha-mini-btn{border:0;background:transparent;color:var(--dsw-alias-label-link,#397ee8);font-size:12px;line-height:18px;cursor:pointer;padding:0;margin-left:8px}\n.dsha-mini-btn:hover{text-decoration:underline}\n.dsha-empty{border:0.5px dashed var(--dsw-alias-border-l2);border-radius:7px;color:var(--dsw-alias-label-tertiary);font-size:12px;margin:12px 0 0;padding:16px;text-align:center}\n.dsha-error{color:var(--dsw-alias-label-danger,#d94b4b);font-size:12px;margin:8px 0 0}\n.dsha-composer-quota{align-items:center;background:var(--dsw-alias-bg-layer-2);border:0.5px solid var(--dsw-alias-border-l2);border-radius:999px;corner-shape:round;color:var(--dsw-alias-label-secondary);cursor:pointer;display:inline-flex;font-size:11px;gap:6px;height:28px;line-height:1;max-width:160px;padding:0 9px;white-space:nowrap;user-select:none;transition:all .15s ease}\n.dsha-composer-quota:hover{background:var(--dsw-alias-interactive-bg-hover);border-color:var(--dsw-alias-border-l1,var(--dsw-alias-border-l2))}\n.dsha-composer-quota strong{color:var(--dsw-alias-label-primary);font-size:11px;font-weight:650}\n.dsha-composer-quota[data-level=warning] strong{color:var(--dsw-alias-label-warning,#d58a24)}\n.dsha-composer-quota[data-level=danger] strong{color:var(--dsw-alias-label-danger,#d94b4b)}\n\n.dsha-device-box{background:var(--dsw-alias-bg-layer-2);border:0.5px solid var(--dsw-alias-border-l2);border-radius:8px;display:flex;flex-direction:column;gap:10px;margin-top:12px;padding:12px}\n.dsha-code-row{align-items:center;display:flex;flex-wrap:wrap;gap:10px;justify-content:space-between}\n.dsha-code{background:var(--dsw-alias-bg-layer-1,rgba(127,127,127,.14));border:0.5px solid var(--dsw-alias-border-l2);border-radius:7px;color:var(--dsw-alias-label-primary);font-family:ui-monospace,SFMono-Regular,Consolas,monospace;font-size:16px;font-weight:650;letter-spacing:.14em;padding:8px 12px}\n.dsha-link{color:var(--dsw-alias-label-link,#397ee8);font-size:12px;overflow-wrap:anywhere;text-decoration:none}\n.dsha-link:hover{text-decoration:underline}\n.dsha-model-meta{color:var(--dsw-alias-label-tertiary);font-size:11px;margin-left:5px}\n.dsha-badge{background:var(--dsw-alias-bg-layer-1,rgba(127,127,127,.14));border:0.5px solid var(--dsw-alias-border-l2);border-radius:999px;color:var(--dsw-alias-label-tertiary);font-size:10px;padding:2px 6px}\n.dsha-cap-table{border-bottom:0.5px solid var(--dsw-alias-border-l2);padding:12px 0}\n.dsha-cap-table table{border-collapse:collapse;font-size:11px;width:100%}\n.dsha-cap-table th{color:var(--dsw-alias-label-tertiary);font-size:11px;font-weight:500;padding:0 10px 6px 0;text-align:left;white-space:nowrap}\n.dsha-cap-table th:last-child,.dsha-cap-table td:last-child{padding-right:0}\n.dsha-cap-table td{border-top:0.5px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-label-secondary);padding:8px 10px 8px 0;vertical-align:top}\n.dsha-cap-table td:first-child{color:var(--dsw-alias-label-primary);font-family:ui-monospace,SFMono-Regular,Consolas,monospace;white-space:nowrap}\n.dsha-cap-table td:nth-child(2),.dsha-cap-table td:nth-child(3){white-space:nowrap}\n.dsha-cap-on{color:var(--dsw-alias-label-primary);font-weight:500}\n.dsha-cap-off{color:var(--dsw-alias-label-tertiary)}\n.dsha-cap-notes{line-height:1.5;min-width:200px}\n.dsha-cap-footnote{font-size:11px;line-height:1.55;margin:8px 0 0}\n.dsha-warn{border:0.5px solid var(--dsw-alias-border-l2);border-radius:6px;line-height:1.55;margin:0 0 10px;padding:8px 10px}\n`\n\n/** Kimi-specific rules layered on top of the shared control styles. */\nexport function installKimiCodeStyles(): void {\n installPluginStyle('kimi-code', BASE, STYLE_ID)\n}\n","import type { ModelDirectoryState } from '@deepseek-ai/dsh-client-ui-model-selection/client'\nimport type { PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\nimport type { MinimaxCodeWebStatus } from '../../shared/minimax-code-contracts.ts'\nimport { ComposerQuotaBadge, quotaLevel, type ComposerQuotaFacts } from '../common/ComposerQuotaBadge.tsx'\nimport { createLineApi } from '../common/line-api.ts'\nimport type { SnapshotStore } from '../store.ts'\nimport { NS_MINIMAX_CODE } from './locales.ts'\n\nconst api = createLineApi('/minimax-code/api', 'MiniMax Code')\n\ntype Props = PropsRuntime<'conversation.input.right'> & PropsLocale<typeof NS_MINIMAX_CODE> & {\n directory: SnapshotStore<ModelDirectoryState>\n loadModelDirectory: () => void\n}\n\n/**\n * Pick the badge facts for one status answer, or nothing at all.\n *\n * Quota is optional in the contract, and the usage read is allowed to fail (the\n * endpoint is undocumented and which host serves this subscription is\n * unmeasured), so a status without quota means the badge has nothing to say: it\n * is not rendered, rather than showing a placeholder that would read as a broken\n * meter. Callers must treat null as \"hide the badge\".\n */\nexport function selectBadgeFacts(status: MinimaxCodeWebStatus | null): ComposerQuotaFacts | null {\n const quota = status?.quota\n if (quota === undefined) return null\n\n if (quota.usedPercent !== undefined && Number.isFinite(quota.usedPercent)) {\n const remaining = Math.max(0, Math.round(100 - quota.usedPercent))\n return {\n text: `${remaining}%`,\n tooltip: `[MiniMax Code] ${quota.label}: ${remaining}% left`,\n level: quotaLevel(remaining),\n }\n }\n\n // A quota without a percentage still names something (a plan, a window), so\n // it is shown as text instead of a number.\n return { text: quota.label, tooltip: `[MiniMax Code] ${quota.label}`, level: 'normal' }\n}\n\nexport function MinimaxCodeComposerQuota({ directory, loadModelDirectory, t }: Props): React.JSX.Element | null {\n return <ComposerQuotaBadge\n directory={directory}\n loadModelDirectory={loadModelDirectory}\n providerId=\"minimax-code\"\n // `/quota` rather than `/status`: it answers with the same payload, but it\n // also refreshes the snapshot (subject to the host-side TTL), whereas\n // `/status` only ever reports the cached one. The badge is the one place a\n // stale number is visible at a glance, so it asks for the fresher read —\n // which is also why a click asks for nothing more than a re-read.\n readStatus={() => api.get<MinimaxCodeWebStatus>('/quota')}\n selectFacts={selectBadgeFacts}\n label={t('composerLabel')}\n />\n}\n","import { installPluginStyle } from '../common/plugin-style.ts'\n\nexport const STYLE_ID = 'dsh-minimax-code-settings-style'\n\n/**\n * MiniMax Code-only additions to the shared settings design system.\n *\n * The base control styles (.dsha-page, .dsha-group, .dsha-row, .dsha-models,\n * the device-code box, the meter, the composer badge, ...) come from the\n * stylesheet the sibling routes install, in the same order the client installs\n * them, so this file declares only what stays unique to this card: the mono\n * credential path and the model-name list.\n */\nexport function installMinimaxCodeStyles(): void {\n installPluginStyle('minimax-code', `\n.dshm-mono{font-family:ui-monospace,SFMono-Regular,Consolas,monospace;font-size:11px}\n.dshm-model-list{display:flex;flex-wrap:wrap;gap:7px;padding-top:8px}\n.dshm-model-list code{background:var(--dsw-alias-bg-layer-2);border:0.5px solid var(--dsw-alias-border-l2);border-radius:6px;color:var(--dsw-alias-label-secondary);font-family:ui-monospace,SFMono-Regular,Consolas,monospace;font-size:11px;padding:5px 8px;white-space:nowrap}\n.dshm-quota-note{margin-top:12px}\n`, STYLE_ID)\n}\n","import type { ModelDirectoryState } from '@deepseek-ai/dsh-client-ui-model-selection/client'\nimport type { PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\nimport type { WorkBuddyWebStatus } from '../../shared/workbuddy-contracts.ts'\nimport { ComposerQuotaBadge, quotaLevel, type ComposerQuotaFacts } from '../common/ComposerQuotaBadge.tsx'\nimport { createLineApi } from '../common/line-api.ts'\nimport type { SnapshotStore } from '../store.ts'\nimport { NS_WORKBUDDY } from './locales.ts'\n\nconst api = createLineApi('/workbuddy/api', 'WorkBuddy')\n\ntype Props = PropsRuntime<'conversation.input.right'> & PropsLocale<typeof NS_WORKBUDDY> & {\n directory: SnapshotStore<ModelDirectoryState>\n loadModelDirectory: () => void\n}\n\n/**\n * Pick the most meaningful number for the badge.\n *\n * A bounded allowance is what a user spends down, so it wins over a bare credit\n * balance; the balance shows only when no percentage is reported. The billing\n * payload reports both a cycle meter and a package meter, and the cycle meter\n * is the one that actually resets, so it is preferred when both exist.\n */\nexport function selectBadgeFacts(status: WorkBuddyWebStatus | null): ComposerQuotaFacts | null {\n const quota = status?.quota\n if (quota === null || quota === undefined) {\n return { text: '—', tooltip: 'WorkBuddy quota unavailable — click to refresh', level: 'normal' }\n }\n\n const meter = (quota.meters ?? []).find((candidate) => candidate.id === 'cycle' && candidate.remainingFraction !== null)\n ?? (quota.meters ?? []).find((candidate) => candidate.remainingFraction !== null)\n if (meter !== undefined && meter.remainingFraction !== null) {\n const remaining = Math.round(meter.remainingFraction * 100)\n return {\n text: `${remaining}%`,\n tooltip: `[WorkBuddy] ${meter.label}: ${remaining}% left`,\n level: quotaLevel(remaining),\n }\n }\n\n if (quota.remainingCredits !== null) {\n return {\n text: String(quota.remainingCredits),\n tooltip: `[WorkBuddy] Remaining credits: ${quota.remainingCredits}`,\n level: 'normal',\n }\n }\n return { text: '—', tooltip: 'WorkBuddy quota unavailable — click to refresh', level: 'normal' }\n}\n\nexport function WorkBuddyComposerQuota({ directory, loadModelDirectory, t }: Props): React.JSX.Element | null {\n return <ComposerQuotaBadge\n directory={directory}\n loadModelDirectory={loadModelDirectory}\n providerId=\"workbuddy-subscription\"\n readStatus={(refresh) => (refresh\n ? api.post<WorkBuddyWebStatus>('/quota')\n : api.get<WorkBuddyWebStatus>('/status'))}\n selectFacts={selectBadgeFacts}\n label={t('composerLabel')}\n />\n}\n","import { installPluginStyle } from '../common/plugin-style.ts'\n\nexport const STYLE_ID = 'dsh-workbuddy-settings-style'\n\n/**\n * WorkBuddy-only additions to the shared settings design system.\n *\n * The base control styles (`.dsha-page`, `.dsha-group`, `.dsha-models`, the\n * account card, …) come from the stylesheet the sibling routes install, in the\n * same order the client installs them, so this file declares only what stays\n * unique to this card: the mono credential paths and the login-progress line.\n *\n * Everything this tab used to declare locally — the per-model capability line\n * and the account-region headings — is gone: the model pill is name-only like\n * every sibling tab, and the account card is the shared one.\n */\nexport function installWorkBuddyStyles(): void {\n installPluginStyle('workbuddy', `\n.dshwb-mono{font-family:ui-monospace,SFMono-Regular,Consolas,monospace;font-size:11px}\n.dsha-account-add-actions{display:flex;flex-wrap:wrap;gap:8px}\n.dsha-account-add-actions .dsha-btn{background:var(--dsw-alias-button-info-fill,#397ee8);border-color:transparent;color:var(--dsw-alias-button-info-label,#fff)}\n.dsha-account-add-actions .dsha-btn:hover:not(:disabled){opacity:.9;background:var(--dsw-alias-button-info-fill,#397ee8)}\n`, STYLE_ID)\n}\n","const STRIP_ELEMENTS = new Set([\n 'foreignobject',\n 'script',\n 'img',\n 'iframe',\n 'object',\n 'embed',\n 'video',\n 'audio',\n 'input',\n 'button',\n 'form',\n 'link',\n 'meta',\n 'base',\n])\n\nexport function sanitizeSvg(svg: string): string {\n if (typeof DOMParser === 'undefined' || typeof XMLSerializer === 'undefined') return ''\n let doc: Document\n try {\n doc = new DOMParser().parseFromString(svg, 'image/svg+xml')\n } catch {\n return ''\n }\n if (doc.querySelector('parsererror') !== null) return ''\n if (doc.documentElement === null || doc.documentElement.localName !== 'svg') return ''\n doc.querySelectorAll('*').forEach((node) => {\n if (STRIP_ELEMENTS.has(node.localName.toLowerCase())) {\n node.remove()\n return\n }\n for (const attribute of [...node.attributes]) {\n const name = attribute.name\n const normalized = name.toLowerCase()\n if (normalized.startsWith('@') || normalized.startsWith('on')) {\n node.removeAttribute(name)\n continue\n }\n if (normalized === 'href' || normalized === 'xlink:href') {\n node.removeAttribute(name)\n }\n }\n })\n return new XMLSerializer().serializeToString(doc.documentElement)\n}","import { installPluginStyle } from '../common/plugin-style.ts'\n\nexport const MERMAID_STYLE_ID = 'dsh-mermaid-renderer-style'\n\nexport function installMermaidStyles(): void {\n installPluginStyle('mermaid', `\n.dsh-mermaid-wrapper{margin:12px 0;border:1px solid var(--dsw-alias-border-l2,rgba(255,255,255,0.12));border-radius:8px;overflow:hidden;background:var(--dsw-alias-bg-layer-2,#1a1a1a);box-shadow:0 2px 8px rgba(0,0,0,0.15)}\n.dsh-mermaid-header{display:flex;align-items:center;justify-content:space-between;padding:6px 12px;background:var(--dsw-alias-bg-layer-1,rgba(0,0,0,0.25));border-bottom:1px solid var(--dsw-alias-border-l2,rgba(255,255,255,0.08));font-size:12px;color:var(--dsw-alias-label-secondary,#888)}\n.dsh-mermaid-title{font-family:ui-monospace,SFMono-Regular,Consolas,monospace;font-size:11px;text-transform:uppercase;letter-spacing:0.5px;color:var(--dsw-alias-label-tertiary,#aaa);font-weight:600}\n.dsh-mermaid-controls{display:flex;gap:8px;align-items:center}\n.dsh-mermaid-btn{background:transparent;border:1px solid var(--dsw-alias-border-l2,rgba(255,255,255,0.15));border-radius:4px;color:var(--dsw-alias-label-secondary,#ccc);padding:2px 8px;font-size:11px;cursor:pointer;line-height:18px;transition:all .15s}\n.dsh-mermaid-btn:hover{background:var(--dsw-alias-interactive-bg-hover,rgba(255,255,255,0.08));color:var(--dsw-alias-label-primary,#fff);border-color:var(--dsw-alias-border-l1,rgba(255,255,255,0.3))}\n.dsh-mermaid-chart{padding:18px;overflow-x:auto;display:flex;justify-content:center;align-items:center;min-height:100px;background:var(--dsw-alias-bg-layer-2,#181818);cursor:zoom-in}\n.dsh-mermaid-chart svg{max-width:100%;height:auto;display:block;margin:0 auto}\n.dsh-mermaid-source{display:none;margin:0;padding:12px;background:var(--dsw-alias-bg-layer-1,#121212);border-top:1px solid var(--dsw-alias-border-l2,rgba(255,255,255,0.08));font-family:ui-monospace,SFMono-Regular,Consolas,monospace;font-size:12px;line-height:1.5;overflow-x:auto;white-space:pre-wrap;word-break:break-all}\n.dsh-mermaid-source.is-visible{display:block}\n\n/* 全屏缩放预览模态框 */\n.dsh-mermaid-modal-overlay{position:fixed;inset:0;background:rgba(0,0,0,0.8);backdrop-filter:blur(4px);z-index:99999;display:flex;flex-direction:column;justify-content:center;align-items:center}\n.dsh-mermaid-modal-toolbar{position:absolute;top:20px;right:24px;display:flex;gap:8px;background:rgba(20,20,20,0.85);border:1px solid rgba(255,255,255,0.15);border-radius:6px;padding:4px;box-shadow:0 8px 24px rgba(0,0,0,0.5)}\n.dsh-mermaid-modal-btn{background:transparent;border:0;color:#fff;font-size:14px;padding:6px 12px;cursor:pointer;border-radius:4px}\n.dsh-mermaid-modal-btn:hover{background:rgba(255,255,255,0.15)}\n.dsh-mermaid-modal-stage{flex:1;width:100%;height:100%;overflow:auto;display:flex;justify-content:center;align-items:center;padding:40px}\n.dsh-mermaid-modal-stage svg{max-width:90vw;max-height:85vh;height:auto}\n`, MERMAID_STYLE_ID)\n}","import { sanitizeSvg } from './sanitize.ts'\nimport { installMermaidStyles } from './styles.ts'\n\ninterface MermaidAPI {\n initialize: (config: Record<string, unknown>) => void\n render: (id: string, text: string) => Promise<{ svg: string }>\n}\n\nlet mermaidSeq = 0\nlet mermaidPromise: Promise<MermaidAPI | null> | null = null\nconst processedHosts = new WeakSet<HTMLElement>()\n\nfunction loadMermaid(): Promise<MermaidAPI | null> {\n if (typeof window === 'undefined') return Promise.resolve(null)\n const existing = (window as unknown as { mermaid?: MermaidAPI }).mermaid\n if (existing) return Promise.resolve(existing)\n if (mermaidPromise) return mermaidPromise\n\n mermaidPromise = new Promise((resolve) => {\n const current = (window as unknown as { mermaid?: MermaidAPI }).mermaid\n if (current) {\n resolve(current)\n return\n }\n\n const script = document.createElement('script')\n script.src = '/api/dsh-chatgpt-subscription/mermaid.min.js'\n script.async = true\n script.onload = () => {\n resolve((window as unknown as { mermaid?: MermaidAPI }).mermaid || null)\n }\n script.onerror = () => {\n const cdn = document.createElement('script')\n cdn.src = 'https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.min.js'\n cdn.async = true\n cdn.onload = () => resolve((window as unknown as { mermaid?: MermaidAPI }).mermaid || null)\n cdn.onerror = () => resolve(null)\n document.head.appendChild(cdn)\n }\n document.head.appendChild(script)\n })\n\n return mermaidPromise\n}\n\nfunction isDarkTheme(): boolean {\n if (typeof document === 'undefined') return false\n const root = document.documentElement\n return (\n root.classList.contains('dark') ||\n root.getAttribute('data-theme') === 'dark' ||\n root.getAttribute('data-color-mode') === 'dark' ||\n window.matchMedia('(prefers-color-scheme: dark)').matches\n )\n}\n\nasync function initMermaidConfig(): Promise<MermaidAPI | null> {\n const m = await loadMermaid()\n if (!m) return null\n try {\n m.initialize({\n startOnLoad: false,\n securityLevel: 'strict',\n htmlLabels: false,\n theme: isDarkTheme() ? 'dark' : 'default',\n fontFamily: 'ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica, Arial, sans-serif',\n })\n } catch {\n // best-effort\n }\n return m\n}\n\nfunction openZoomModal(svgHtml: string): void {\n const overlay = document.createElement('div')\n overlay.className = 'dsh-mermaid-modal-overlay'\n\n let scale = 1\n\n overlay.innerHTML = `\n <div class=\"dsh-mermaid-modal-toolbar\">\n <button type=\"button\" class=\"dsh-mermaid-modal-btn\" data-action=\"zoom-out\" title=\"缩小\">− 缩小</button>\n <button type=\"button\" class=\"dsh-mermaid-modal-btn\" data-action=\"zoom-in\" title=\"放大\">+ 放大</button>\n <button type=\"button\" class=\"dsh-mermaid-modal-btn\" data-action=\"reset\" title=\"重置\">⟳ 重置</button>\n <button type=\"button\" class=\"dsh-mermaid-modal-btn\" data-action=\"close\" title=\"关闭\">关闭</button>\n </div>\n <div class=\"dsh-mermaid-modal-stage\">\n <div class=\"dsh-mermaid-zoom-container\">${svgHtml}</div>\n </div>\n `\n\n const stage = overlay.querySelector('.dsh-mermaid-zoom-container') as HTMLElement\n const updateTransform = () => {\n if (stage) stage.style.transform = `scale(${scale})`\n }\n\n overlay.addEventListener('click', (e) => {\n const target = e.target as HTMLElement\n const action = target?.getAttribute('data-action')\n if (action === 'close' || target === overlay) {\n overlay.remove()\n document.removeEventListener('keydown', onKeyDown)\n } else if (action === 'zoom-in') {\n scale = Math.min(5, scale * 1.25)\n updateTransform()\n } else if (action === 'zoom-out') {\n scale = Math.max(0.2, scale / 1.25)\n updateTransform()\n } else if (action === 'reset') {\n scale = 1\n updateTransform()\n }\n })\n\n const onKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'Escape') {\n overlay.remove()\n document.removeEventListener('keydown', onKeyDown)\n }\n }\n document.addEventListener('keydown', onKeyDown)\n\n document.body.appendChild(overlay)\n}\n\nfunction findMermaidCandidate(codeEl: HTMLElement): { host: HTMLElement; code: string } | null {\n // 1. 绝对忽略我们自己渲染容器内的任何子元素\n if (codeEl.closest('.dsh-mermaid-wrapper')) return null\n\n // 2. 找到唯一的代码块宿主容器(优先 .md-code-block,其次 pre,最后自身)\n const host = (codeEl.closest('.md-code-block') as HTMLElement) || codeEl.closest('pre') || codeEl\n if (processedHosts.has(host) || host.getAttribute('data-dsh-mermaid-status')) return null\n if (host.previousElementSibling?.classList.contains('dsh-mermaid-wrapper')) return null\n\n const codeText = (codeEl.textContent || '').trim()\n if (!codeText || codeText.length < 5) return null\n\n // 3. 判断是否为 mermaid 语法或标记\n const hasMermaidClass = [...codeEl.classList].some((c) => c.toLowerCase().includes('mermaid'))\n const topText = host.firstElementChild?.textContent?.trim().toLowerCase()\n const isHeaderMermaid = topText === 'mermaid' || topText?.startsWith('mermaid ')\n\n const isGrammarStart = /^(flowchart|graph|sequenceDiagram|classDiagram|stateDiagram|erDiagram|gantt|pie|gitGraph|mindmap|timeline)\\b/i.test(codeText)\n\n if (hasMermaidClass || isHeaderMermaid || isGrammarStart) {\n return { host, code: codeText }\n }\n\n return null\n}\n\nasync function renderMermaidHost(host: HTMLElement, code: string): Promise<void> {\n // 同步立即锁死该宿主,杜绝并发与重入\n processedHosts.add(host)\n host.setAttribute('data-dsh-mermaid-status', 'processing')\n\n const m = await initMermaidConfig()\n if (!m) {\n processedHosts.delete(host)\n host.removeAttribute('data-dsh-mermaid-status')\n return\n }\n\n const renderId = `dsh-mermaid-${++mermaidSeq}`\n\n try {\n const { svg } = await m.render(renderId, code)\n const cleanSvg = sanitizeSvg(svg)\n if (!cleanSvg) {\n processedHosts.delete(host)\n host.removeAttribute('data-dsh-mermaid-status')\n return\n }\n\n // 再次双重检查:防止在异步等待期间被其他流程插入\n if (host.previousElementSibling?.classList.contains('dsh-mermaid-wrapper')) {\n host.setAttribute('data-dsh-mermaid-status', 'done')\n host.style.display = 'none'\n return\n }\n\n const wrapper = document.createElement('div')\n wrapper.className = 'dsh-mermaid-wrapper'\n\n let showSource = false\n\n wrapper.innerHTML = `\n <div class=\"dsh-mermaid-header\">\n <span class=\"dsh-mermaid-title\">Mermaid 图表</span>\n <div class=\"dsh-mermaid-controls\">\n <button type=\"button\" class=\"dsh-mermaid-btn\" data-btn=\"toggle-source\">源码</button>\n <button type=\"button\" class=\"dsh-mermaid-btn\" data-btn=\"copy\">复制</button>\n <button type=\"button\" class=\"dsh-mermaid-btn\" data-btn=\"zoom\" title=\"放大查看\">放大 ↗</button>\n </div>\n </div>\n <div class=\"dsh-mermaid-chart\" title=\"点击放大\">${cleanSvg}</div>\n <div class=\"dsh-mermaid-source\"><code>${code.replace(/</g, '&lt;').replace(/>/g, '&gt;')}</code></div>\n `\n\n const sourceEl = wrapper.querySelector('.dsh-mermaid-source') as HTMLElement\n const toggleBtn = wrapper.querySelector('[data-btn=\"toggle-source\"]') as HTMLButtonElement\n const copyBtn = wrapper.querySelector('[data-btn=\"copy\"]') as HTMLButtonElement\n const chartEl = wrapper.querySelector('.dsh-mermaid-chart') as HTMLElement\n\n toggleBtn?.addEventListener('click', (e) => {\n e.stopPropagation()\n showSource = !showSource\n if (showSource) {\n sourceEl.classList.add('is-visible')\n toggleBtn.textContent = '图表'\n } else {\n sourceEl.classList.remove('is-visible')\n toggleBtn.textContent = '源码'\n }\n })\n\n copyBtn?.addEventListener('click', async (e) => {\n e.stopPropagation()\n try {\n await navigator.clipboard.writeText(code)\n copyBtn.textContent = '已复制'\n setTimeout(() => {\n copyBtn.textContent = '复制'\n }, 1500)\n } catch {\n // fallback\n }\n })\n\n const handleZoom = (e: Event) => {\n e.stopPropagation()\n openZoomModal(cleanSvg)\n }\n\n wrapper.querySelector('[data-btn=\"zoom\"]')?.addEventListener('click', handleZoom)\n chartEl?.addEventListener('click', handleZoom)\n\n // 隐藏宿主并插入图表\n host.style.display = 'none'\n host.parentNode?.insertBefore(wrapper, host)\n host.setAttribute('data-dsh-mermaid-status', 'done')\n } catch {\n // 语法错误或流式未完成时释放锁,允许后续更新后重试\n processedHosts.delete(host)\n host.removeAttribute('data-dsh-mermaid-status')\n const errContainer = document.getElementById(renderId)\n if (errContainer) errContainer.remove()\n }\n}\n\nexport function scanAndRenderMermaid(): void {\n if (typeof document === 'undefined') return\n\n // 只以 code 标签为唯一的判定入口,彻底避免 querySelector 多级命中同一代码块\n const codeElements = document.querySelectorAll<HTMLElement>('pre code, .md-code-block code')\n\n for (const codeEl of codeElements) {\n const candidate = findMermaidCandidate(codeEl)\n if (candidate) {\n void renderMermaidHost(candidate.host, candidate.code)\n }\n }\n}\n\nexport function setupMermaidObserver(): () => void {\n if (typeof document === 'undefined') return () => {}\n\n installMermaidStyles()\n\n let timer: number | undefined\n const debouncedScan = () => {\n window.clearTimeout(timer)\n timer = window.setTimeout(() => {\n scanAndRenderMermaid()\n }, 250)\n }\n\n debouncedScan()\n\n const observer = new MutationObserver((mutations) => {\n let shouldScan = false\n for (const m of mutations) {\n // 只要 mutation 是我们自己的 wrapper 产生的变动,直接忽略\n for (const node of m.addedNodes) {\n if (node.nodeType === 1) {\n const el = node as HTMLElement\n if (el.classList?.contains('dsh-mermaid-wrapper') || el.closest?.('.dsh-mermaid-wrapper')) {\n continue\n }\n shouldScan = true\n break\n }\n }\n if (shouldScan) break\n }\n if (shouldScan) debouncedScan()\n })\n\n observer.observe(document.body, {\n childList: true,\n subtree: true,\n })\n\n const themeObserver = new MutationObserver(() => {\n void initMermaidConfig()\n for (const el of document.querySelectorAll<HTMLElement>('[data-dsh-mermaid-status=\"done\"]')) {\n processedHosts.delete(el)\n el.removeAttribute('data-dsh-mermaid-status')\n const prevWrapper = el.previousElementSibling\n if (prevWrapper && prevWrapper.classList.contains('dsh-mermaid-wrapper')) {\n prevWrapper.remove()\n }\n el.style.display = ''\n }\n debouncedScan()\n })\n\n themeObserver.observe(document.documentElement, {\n attributes: true,\n attributeFilter: ['class', 'data-theme', 'data-color-mode'],\n })\n\n return () => {\n observer.disconnect()\n themeObserver.disconnect()\n window.clearTimeout(timer)\n }\n}","import type { Context as ClientContext } from '@deepseek-ai/cordis'\nimport type { ImageAttachmentRef } from '@deepseek-ai/dsh-attachment'\nimport type { SessionId } from '@deepseek-ai/dsh-client-connection/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-settings/client'\nimport type {} from '@deepseek-ai/dsh-client-locale/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-slots'\nimport type {} from '@deepseek-ai/dsh-client-ui-model-selection/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-conversation/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-renderer/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-tool/client'\nimport { CODEX_IMAGE_TOOL_NAME } from '../compat.ts'\nimport { CodexComposerQuota } from './CodexComposerQuota.tsx'\nimport { CodexImageToolView, type ImageLoader } from './CodexImageToolView.tsx'\nimport { ProviderHubSection } from './ProviderHubSection.tsx'\nimport { SubscriptionApi } from './api.ts'\nimport { dictionaries, NS, type LocaleKey } from './locales.ts'\nimport { installStyles } from './styles.ts'\nimport { installHubStyles } from './hub/hub-styles.ts'\nimport { installModelChecklistStyles } from './common/model-checklist-styles.ts'\nimport { installAntigravityStyles } from './antigravity/styles.ts'\nimport { installPoolStyles } from './common/styles.ts'\nimport { dictionaries as antigravityDicts, NS_ANTIGRAVITY, type AntigravityLocaleKey } from './antigravity/locales.ts'\nimport { AntigravityComposerQuota } from './antigravity/AntigravityComposerQuota.tsx'\nimport { ClaudeComposerQuota } from './claude/ClaudeComposerQuota.tsx'\nimport { dictionaries as claudeDicts, NS_CLAUDE, type ClaudeLocaleKey } from './claude/locales.ts'\nimport { installClaudeStyles } from './claude/styles.ts'\nimport { CommandCodeComposerQuota } from './command-code/CommandCodeComposerQuota.tsx'\nimport { dictionaries as commandCodeDicts, NS_COMMAND_CODE, type CommandCodeLocaleKey } from './command-code/locales.ts'\nimport { KimiCodeComposerQuota } from './kimi-code/KimiCodeComposerQuota.tsx'\nimport { dictionaries as kimiCodeDicts, NS_KIMI_CODE, type KimiCodeLocaleKey } from './kimi-code/locales.ts'\nimport { installKimiCodeStyles } from './kimi-code/styles.ts'\nimport { MinimaxCodeComposerQuota } from './minimax-code/MinimaxCodeComposerQuota.tsx'\nimport { dictionaries as minimaxCodeDicts, NS_MINIMAX_CODE, type MinimaxCodeLocaleKey } from './minimax-code/locales.ts'\nimport { installMinimaxCodeStyles } from './minimax-code/styles.ts'\nimport { WorkBuddyComposerQuota } from './workbuddy/WorkBuddyComposerQuota.tsx'\nimport { dictionaries as workBuddyDicts, NS_WORKBUDDY, type WorkBuddyLocaleKey } from './workbuddy/locales.ts'\nimport { installWorkBuddyStyles } from './workbuddy/styles.ts'\nimport { dictionaries as ollamaDicts, NS_OLLAMA, type OllamaLocaleKey } from './ollama/locales.ts'\nimport { setupMermaidObserver } from './mermaid/renderer.ts'\n\ndeclare module '@deepseek-ai/dsh-client-ui-slots' {\n /**\n * Every namespace this plugin registers, typed by that line's own dictionary.\n *\n * These were `any`, which made a renamed or misspelled key invisible to the\n * compiler: the card rendered the key name itself and only a human noticed.\n * Each line exports its key union beside its dictionaries, so this map is now\n * the compile-time half of the locale contract.\n */\n interface LocaleNamespaceMap {\n 'dsh-chatgpt-subscription': LocaleKey\n 'dsh-antigravity': AntigravityLocaleKey\n 'dsh-claude': ClaudeLocaleKey\n 'dsh-command-code': CommandCodeLocaleKey\n 'dsh-kimi-code': KimiCodeLocaleKey\n 'dsh-minimax-code': MinimaxCodeLocaleKey\n 'dsh-workbuddy': WorkBuddyLocaleKey\n 'dsh-ollama': OllamaLocaleKey\n }\n}\n\nexport const inject = [\n 'slots',\n 'locale',\n 'modelDirectories',\n 'conversation',\n 'sessions',\n 'remote',\n 'remote.session',\n]\n\nexport function apply(ctx: ClientContext): void {\n ctx.effect(() => ctx.locale.register(NS, dictionaries), 'dsh-chatgpt-subscription: dictionaries')\n ctx.effect(() => installStyles(), 'dsh-chatgpt-subscription: styles')\n ctx.effect(() => {\n installHubStyles()\n installModelChecklistStyles()\n return () => {}\n }, 'dsh-chatgpt-subscription: hub styles')\n ctx.effect(() => ctx.locale.register(NS_ANTIGRAVITY, antigravityDicts), 'dsh-antigravity: dictionaries')\n ctx.effect(() => {\n installAntigravityStyles()\n return () => {}\n }, 'dsh-antigravity: styles')\n ctx.effect(() => ctx.locale.register(NS_CLAUDE, claudeDicts), 'dsh-claude: dictionaries')\n ctx.effect(() => {\n installClaudeStyles()\n return () => {}\n }, 'dsh-claude: styles')\n ctx.effect(() => ctx.locale.register(NS_COMMAND_CODE, commandCodeDicts), 'dsh-command-code: dictionaries')\n ctx.effect(() => ctx.locale.register(NS_KIMI_CODE, kimiCodeDicts), 'dsh-kimi-code: dictionaries')\n ctx.effect(() => {\n installKimiCodeStyles()\n return () => {}\n }, 'dsh-kimi-code: styles')\n ctx.effect(() => ctx.locale.register(NS_MINIMAX_CODE, minimaxCodeDicts), 'dsh-minimax-code: dictionaries')\n ctx.effect(() => {\n installMinimaxCodeStyles()\n return () => {}\n }, 'dsh-minimax-code: styles')\n ctx.effect(() => ctx.locale.register(NS_WORKBUDDY, workBuddyDicts), 'dsh-workbuddy: dictionaries')\n ctx.effect(() => ctx.locale.register(NS_OLLAMA, ollamaDicts), 'dsh-ollama: dictionaries')\n ctx.effect(() => {\n installWorkBuddyStyles()\n return () => {}\n }, 'dsh-workbuddy: styles')\n // Badge variants the shared account-pool card adds on top of each provider's\n // own stylesheet; additive, so it never restyles an existing tab.\n ctx.effect(() => {\n installPoolStyles()\n return () => {}\n }, 'dsh-chatgpt-subscription: pool styles')\n ctx.effect(() => setupMermaidObserver(), 'dsh-mermaid: observer')\n\n const t = ctx.locale.bind(NS)\n\n const handleModelDirectoryReload = () => {\n try {\n const conv = ctx.conversation as unknown as { activeSessionId?: string; currentSessionId?: string; activeId?: string }\n const activeSessionId = conv?.activeSessionId || conv?.currentSessionId || conv?.activeId\n if (activeSessionId && ctx.modelDirectories) {\n const dir = ctx.modelDirectories.directoryFor(activeSessionId as any)\n void dir?.load?.().catch?.(() => undefined)\n }\n } catch {\n // best-effort\n }\n }\n\n // One sidebar entry hosts every subscription provider behind tabs instead\n // of registering a separate settings page per provider.\n const ProviderHubSectionWrapper: React.FC<React.ComponentProps<typeof ProviderHubSection>> = (props) => {\n // The hub reuses the refresh callback contract so a model toggle in any\n // provider tab repaints the conversation model picker.\n return <ProviderHubSection {...props} onModelChange={handleModelDirectoryReload} />\n }\n\n ctx.slots.inject('settings.section', () => ctx.slots.register({\n name: 'settings.section',\n id: 'subscription-hub',\n order: 45,\n label: () => t('hubTitle'),\n locale: NS,\n }, ProviderHubSectionWrapper))\n\n ctx.slots.inject('conversation.input.right', () => ctx.slots.register({\n name: 'conversation.input.right', id: 'codex-subscription-quota', order: 35, locale: NS,\n inject: (sessionId) => composerBadgeInject(ctx, sessionId, { withApi: true }),\n }, CodexComposerQuota))\n ctx.slots.inject('conversation.input.right', () => ctx.slots.register({\n name: 'conversation.input.right', id: 'antigravity-quota', order: 36, locale: NS_ANTIGRAVITY,\n inject: (sessionId) => composerBadgeInject(ctx, sessionId),\n }, AntigravityComposerQuota))\n ctx.slots.inject('conversation.input.right', () => ctx.slots.register({\n name: 'conversation.input.right', id: 'command-code-quota', order: 37, locale: NS_COMMAND_CODE,\n inject: (sessionId) => composerBadgeInject(ctx, sessionId),\n }, CommandCodeComposerQuota))\n ctx.slots.inject('conversation.input.right', () => ctx.slots.register({\n name: 'conversation.input.right', id: 'kimi-code-quota', order: 38, locale: NS_KIMI_CODE,\n inject: (sessionId) => composerBadgeInject(ctx, sessionId),\n }, KimiCodeComposerQuota))\n ctx.slots.inject('conversation.input.right', () => ctx.slots.register({\n name: 'conversation.input.right', id: 'workbuddy-quota', order: 39, locale: NS_WORKBUDDY,\n inject: (sessionId) => composerBadgeInject(ctx, sessionId),\n }, WorkBuddyComposerQuota))\n ctx.slots.inject('conversation.input.right', () => ctx.slots.register({\n name: 'conversation.input.right', id: 'minimax-code-quota', order: 40, locale: NS_MINIMAX_CODE,\n inject: (sessionId) => composerBadgeInject(ctx, sessionId),\n }, MinimaxCodeComposerQuota))\n ctx.slots.inject('conversation.input.right', () => ctx.slots.register({\n name: 'conversation.input.right', id: 'claude-quota', order: 41, locale: NS_CLAUDE,\n inject: (sessionId) => composerBadgeInject(ctx, sessionId),\n }, ClaudeComposerQuota))\n ctx.slots.inject('tool.call.toolview', () => ctx.slots.register({\n name: 'tool.call.toolview',\n key: CODEX_IMAGE_TOOL_NAME,\n locale: NS,\n inject: (sessionId) => ({\n loadImage: imageLoader(ctx, sessionId),\n }),\n }, CodexImageToolView))\n}\n\ntype ImageUrlResolver = (sessionId: string, attachment: ImageAttachmentRef) => Promise<string>\n\n/**\n * The seats every composer badge is handed.\n *\n * Seven registrations each repeated this eight-line factory verbatim, and the\n * only difference between them was whether ChatGPT's own badge also reads the\n * subscription API directly. It lives here so a badge added later cannot forget\n * the directory seat (the badge resolves the session's model list through it) or\n * the reload callback that keeps that list fresh.\n *\n * The session id arrives as a plain string while the directory service takes the\n * branded one, so the cast lives here rather than at seven call sites.\n */\nfunction composerBadgeInject(ctx: ClientContext, sessionId: string, options: { withApi?: boolean } = {}) {\n const directory = ctx.modelDirectories.directoryFor(sessionId as SessionId)\n return {\n ...(options.withApi === true ? { api: new SubscriptionApi() } : {}),\n directory: directory.store,\n loadModelDirectory: () => {\n void directory.load().catch(() => undefined)\n },\n }\n}\n\n/**\n * Why the seven registrations below are spelled out rather than driven from a\n * table.\n *\n * `ctx.slots.register` is generic over the slot key *and* the locale namespace,\n * and it is overloaded; the component's props are composed from both. A table\n * would have to hold components of different namespaces, so the correlation\n * between a row's `locale` and its `component` would be erased — and a helper\n * that keeps the correlation generically fails overload resolution inside its\n * own body, because the namespace parameter is still unresolved there. Both\n * roads end in a cast against the harness's composed-props internals, which is a\n * version-sensitive seam this plugin does not add. What each row repeats is only\n * the registration object; the eight-line seat factory is\n * {@link composerBadgeInject}.\n */\n\n/**\n * Resolve one session-authorized image URL.\n *\n * Harness 0.1.2 moved this from `resolveImage` on `conversation` to `imageUrl`\n * on `uiConversation`, so both shapes stay supported.\n */\nfunction imageLoader(ctx: ClientContext, sessionId: string): ImageLoader {\n const current = ctx.get('uiConversation') as unknown as { imageUrl?: ImageUrlResolver } | undefined\n const currentResolve = current?.imageUrl?.bind(current)\n if (currentResolve !== undefined) return (attachment) => currentResolve(sessionId, attachment)\n const legacy = ctx.get('conversation') as unknown as { resolveImage?: ImageUrlResolver } | undefined\n const legacyResolve = legacy?.resolveImage?.bind(legacy)\n if (legacyResolve !== undefined) return (attachment) => legacyResolve(sessionId, attachment)\n return () => Promise.reject(new Error('no client service resolves an image URL'))\n}\n"],"mappings":"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"}